Reputation: 65
I'm reading an jp2 file using openCV's imread()
.
The image loads, but it's always grayscale.
I saw in the documentation that some IMREAD_FLAGS could cause this and I also know that cv2 may change the channel order to BGR.
However, I believe none of these reasons are the issue here. I imported the image with different IMREAD_FLAGS and saved copies like this:
image = cv2.imread("mypath.jp2", cv2.IMREAD_UNCHANGED) # change flag here
cv2.imwrite("IMREAD_UNCHANGED.png", image) # change file name accordingly
I also converted the image to RGB using cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
. The resulting image sizes are different, but the result are always a grayscale image:
Also, I'm certain these images have color, because when opening it with Pillow it looks like this:
Can someone tell me what I'm doing wrong here? Thanks in advance !
Upvotes: 3
Views: 1828
Reputation: 1
Docs say there are some modification flags for the cv2 imread function:
cv2.IMREAD_COLOR – It specifies to load a color image. Any transparency of image will be neglected. It is the default flag. Alternatively, we can pass integer value 1 for this flag.
cv2.IMREAD_GRAYSCALE – It specifies to load an image in grayscale mode. Alternatively, we can pass integer value 0 for this flag.
cv2.IMREAD_UNCHANGED – It specifies to load an image as such including alpha channel. Alternatively, we can pass integer value -1 for this flag.
See the docs for full enum list.
So, if you face a problem with reading an image in the format you expect, you could try:
cv2.imread(img_path, -1)
cv2.imread(img_path, 0)
or, in my case, I've solved this issue with
cv2.imread(img_path, 3)
[UPD] As Mark Setchell rightly corrected me, it is better to use constant names. So I've updated my answer with a neater and more readable way to do the trick:
cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
# and
cv2.imread(img_path, cv2.IMREAD_ANYCOLOR)
Upvotes: -1
Reputation: 15518
When I use cv.imread(path)
(OpenCV 4.7.0 on Windows), it gives me three channels, not grayscale. I didn't look to check if OpenCV removed any color information.
It does complain if I ask for IMREAD_UNCHANGED
:
[ERROR:[email protected]] global grfmt_jpeg2000_openjpeg.cpp:410 cv::`anonymous-namespace'::decodeGrayscaleData OpenJPEG2000: unsupported conversion from 4 components to 4 for Grayscale image decoding
The same error happens for cv.imreadmulti(path, flags=cv.IMREAD_UNCHANGED)
which is usually the right choice for multi-plane image formats (TIFF can be like that). Without the flag, it just returns one layer of 3-channel data.
So there's potential for a bug report. If you want to file it, do it on OpenCV's github.
PIL reads it as "RGBA". There is no transparency there, it's just a 4th channel.
The file name contains "rgbi", which makes me suspect it's a multi-layer file, or at least the fourth channel contains another color layer, not "transparency".
If you convert from PIL Image to numpy array, at least you can get all the channels and their data.
import numpy as np
from PIL import Image
im = Image.open(path)
im = np.asarray(im)
You could also use imageio
. It warns about the image being huge, but it does load the whole thing. It's a complex library, so check the docs for recommended ways to read such files.
import imageio
im = imageio.read(path)
im.get_data(0) # (10000, 10000, 4)
Upvotes: 3