Convert from Vec3b to Mat3b - opencv

I am using BGR to HSV conversion of image using OpenCV. Since I am new to this field and software, I may sound incorrect so please let me know if I am wrong.
Now, in my school project i want to work with HSV image, which is easily converted using
cvtColor(src, dst, CV_BGR2HSV);
I suppose, that imread() function reads image in a uchar format which is 8bit unsigned image (i suppose). In that case imshow() is also uchar.
But to work with HSV image, I am not sure but I feel i need to convert use Mat3b perhaps for the distinctive H, S and V channels of the image.
Incase if I am wrong, that I want to work with H channel of the HSV image only so how can i print, or modify this channel information.
Many thanks

Perhaps you can use cv::split to devide the HSV to 3 one-channel Mat. I think this topic OpenCV:split HSV image and scan through H channel may solve your problem.

Related

Color descriptor OpenCV

I am using openCV to extract color information for each pixel in an image. I have found openCV has provided that through "OpponentColorDescriptorExtractor", but I have no idea how to use it. Can some one please provide me demo code that extracts color information pixel by pixel in an image? Thank you.
to access a pixel, use:
uchar v = img.at<uchar>(row,col); // grayscale, 1chan, 8bit
Vec3b v = img.at<Vec3b>(row,col); // rgb, 3chan, 3*8bit
// v[0]==b; v[1]==g; v[00]==r;

OpenCV default storage format

What is the default (Pixel) storage format used by OpenCV ?
I know it is BGR but is it BGR32 ? BGR16 ?
Is it Packed or Planar ?
Can you suggest me a way to find it out?
Thank you for your help.
[EDIT] Context : Actually I am trying to use OpenCV with another library called MIL (Matrox Imaging Library). I need to grab an Image with MIL and then convert it to an OpenCV Image. That is why I need to know the default pixel format, to configure MIL.
The image format is set by the flag when you create the image eg CV_8UC3 means 8bit pixels, unsigned, 3colour channels. In a colour image the pixel order is BGR, data is stored in row order.
The data isn't packed at the pixel level - it's 3bytes/pixel (BGRA is an option on some of the GPU calls).
Data may be packed at the line level, if the number of pixels in a row * the number of bytes/pixel isn't a multiple of 4 then the data is padded with zero to the next 32bit boundary. The call mat.ptr(n) returns a pointer to the start of the 'n' th row
Note that you can share memory with another comaptible image format by passing the data pointer from the MIL image to the ctor of the cv::Mat
It depends on the way you are managing the image: have you loaded it from a file with imread for example?
Have a look at imread here, with a colour jpeg for example you'll have a 3 channel format, 24 bits overall. Can you be more specific?
I do not know if it's useful, but I had a similar issue when converting an image from Android Bitmap (passed to OpenCV as a byte array RGBA8888) to OpenCV image (BGR888).
Here is how I've solved it.
cv::Mat orig_image1(orig_height, orig_width, CV_8UC4, image_data);
int from_to[] = { 0, 2, 1, 1, 2, 0};
cv::Mat image(orig_height, orig_width, CV_8UC3);
cv::mixChannels(&orig_image1, 1, &image, 1, from_to, 3);
orig_image1.release();

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..

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.

OpenCV - How does it handle color profiles?

I have a jpeg. Its color profile is sRGB, of course. I load it into "image" and call
cvCvtColor(image, gray, CV_BGR2GRAY);
to convert it to grayscale. When I step into that routine in the debugger, I find it multiplying pixels by these values:
#define cscGr_32f 0.299f
#define cscGg_32f 0.587f
#define cscGb_32f 0.114f
Waaaait a minute. Those are the luminance values for NTSC RGB, not sRGB. Furthermore, I cannot see that it's doing anything about gamma correction. I am confused. When OpenCV decodes the image, does it remove gamma correction and convert to NTSC RGB?
Bonus question: Is there an OpenCV forum where the gurus hang? I've googled in vain.
It ignores. OpenCV usually does not perform gamma correction. Well, it does, only when cvtColoring RGB-to-L*a*b*/L*u*v* (But, how? Does OpenCV assume the gamma of the input image?).

Resources