Grayscale conversion algorithm of OpenCV's imread() - opencv

What grayscale conversion algorithm does OpenCV's
cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
use?

In OpenCV 3.0:
cv::IMREAD_COLOR: the image is decompressed by cv::JpegDecoder as JCS_RGB (three channel image) and then the icvCvt_RGB2BGR_8u_C3R() function will swap the red and blue channels in order to get BGR format.
cv::IMREAD_GRAYSCALE: the image is decompressed by cv::JpegDecoder as JCS_GRAYSCALE (one channel image), all details of color conversion and other preprocessing/postprocessing is handled by the libjpeg. Finally, the decompressed data are copied into the internal buffer of the given cv::Mat.
Ergo no cv::cvtColor() is called after reading the image as cv::IMREAD_GRAYSCALE.

Related

Converting Grayscale Images to Colormap in Swift/iOS?

I have a 512x512 grayscale image (or MultiArray) which is the output of a CoreML depth estimation model.
In Python, one can use Matplotlib or other packages to visualise grayscale images in different colormaps, like so:
Grayscale
Magma
[Images from https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html]
I was wondering if there was any way to take said output and present it as a cmap in Swift/iOS?
If you make the model output an image, you get a CVPixelBuffer object. This is easy enough to draw on the screen by converting it to a CIImage and then a CGImage.
If you want to draw it with a colormap, you'll have to replace each of the grayscale values with a color manually. One way to do this is to output an MLMultiArray and loop through each of the output values, and use a lookup table for the colors. A quicker way is to do this in a Metal compute shader.

how to check whether image is YUV or RGB format

I have downloaded a program, in which there are multiple classes. In that one of the function receives an image as parameter. How can I check the Image received by that function in is in YUV format or RGB format using opencv ??
You can't. Mat does not have such information. All you can get is depth and number of channels.

SURF and OpenSURF to color image

I am using SURF features in OpenCV where the input images are converted to GRAY image.
cvtColor(object, object, CV_RGB2GRAY);
When I went through the documentation of OpenSURF I realised that its not in grayscale.
My confusion is that can we apply SURF to any image formats (YUV, HSV, RGB) or we have to change and modify the program to achieve that?
Most feature detectors work on greyscale because they analyse the patterns of edges in the image patch. You can run SURF on any single colour channel from the colour formats you mention i.e. You can run it on Y, U or V from YUV images, or on H, S or V from HSV images. Not sure how OpenSURF treats this, but they must be using the greyscale image internally.
Like OpenCV if you given an image to OpenSURF that is not single channel, it calls cvtColor(src, dst, CV_BGR2GRAY). If you pass either a 3 channel image in a YUV, HSV, Lab etc, things will go horribly wrong because the image will have an inappropriate color conversion applied..

Convert 8 depth single channel (YUV) image to 24 depth RGB(3 Channels) image

How convert one channel YUV image (first channel - Y are used) to 24 depth RGB image? I asks, because i must display it using gtk+ interface and gtk supports only 24 depth RGB image.
I'm not sure what you are actually starting from, a single-channel grayvalue image or a three-channel YUV image of which the second and third channel are full of zeros. If you have a single-channel 8-bit image to start with, you can use cvtColor(source_mat,destination_mat,CV_GRAY2RGB) to convert to 24-bit RGB. If you are starting from a 3-channel 24-bit YUV image with two channels full of zeros, you can use the split() function to get the Y channel out of it, then convert that as described above.

OpenCV image conversion from RGB to Grayscale using imread giving poor results

I'm loading a 24 Bit RGB image from a PNG file into my OpenCV application.
However loading the image as grayscale directly using imread gives a very poor result.
Mat src1 = imread(inputImageFilename1.c_str(), 0);
Loading the RGB image as RGB and converting it to Grayscale gives a much better looking result.
Mat src1 = imread(inputImageFilename1.c_str(), 1);
cvtColor(src1, src1Gray, CV_RGB2GRAY);
I'm wondering if I'm using imread for my image type correctly. Has anyone experienced similar behavior?
The image converted to grayscale using imread is shown here:
The image converted to grayscale using cvtColor is shown here:
I was having the same issue today. Ultimately, I compared three methods:
//method 1
cv::Mat gs = cv::imread(filename, CV_LOAD_IMAGE_GRAYSCALE);
//method 2
cv::Mat color = cv::imread(filename, 1); //loads color if it is available
cv::Mat gs_rgb(color.size(), CV_8UC1);
cv::cvtColor(color, gs_rgb, CV_RGB2GRAY);
//method 3
cv::Mat gs_bgr(color.size(), CV_8UC1);
cv::cvtColor(color, gs_bgr, CV_BGR2GRAY);
Methods 1 (loading grayscale) and 3 (CV_BGR2GRAY) produce identical results, while method 2 produces a different result. For my own ends, I've started using CV_BGR2GRAY.
My input files are jpgs, so there might be issues related to your particular image format.
The simple answer is, that openCV functions uses the BGR format. If you read in a image with imread or VideoCapture, it'll be always BGR. If you use RGB2GRAY, you interchange the blue channel with the green. The formula to get the brightness is
y = 0.587*green + 0.299*red + 0.114*blue
so if you change green and blue, this will cause an huge calculation error.
Greets
I have had a similar problem once, working with OpenGL shaders. It seems that the first container that OpenCV reads your image with does not support all the ranges of color and hence you see that the image is a poor grayscale transformation. However once you convert the original image into grayscale using cvtColor the container is different from the first one and supports all ranges. In my opinion the first one uses less than 8 bits for grayscale or changing to the grayscale uses a bad method. But the second one gives smooth image because of more bits in gray channel.

Resources