can anybody explain the mathematical background and function for conversion of BGR2GRAY?
Under https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html I found the following for RGB to Gray:
RGB[A] to Gray:Y←0.299⋅R+0.587⋅G+0.114⋅B
Is it the same reversed for BGR? Is it really that simple or is there a more complex method behind:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
Since the human vision does not receipt all colors equally, the contributions of the primary colors vary. This depends on the wavelengths of the colors. In the following document on page 7 you can find the formula and also some more explanations: http://poynton.ca/PDFs/ColorFAQ.pdf
BGR has been used for OpenCV since back then when it was established a couple companies used BGR instead of RGB. The standard is nowadays RGB. Nontheless, the formula for the transformation is equivalent to Y=0.299*R + 0.587*G + 0.114*B
Related
I have to detect leukocytes cells in an image that contains another blood cells, but the differences can be distinguished through the color of cells, leukocytes have more dense purple color, can be seen in the image below.
What color methode I've to use RGB/HSV ? and why ?!
sample image:
Usually when making decisions like this I just quickly plot the different channels and color spaces and see what I find. It is always better to start with a high quality image than to start with a low one and try to fix it with lots of processing
In this specific case I would use HSV. But unlike most color segmentation I would actually use the Saturation Channel to segment the images. The cells are nearly the same Hue so using the hue channel would be very difficult.
hue, (at full saturation and full brightness) very hard to differentiate cells
saturation huge contrast
Green channel, actually shows a lot of contrast as well (it surprised me)
the red and blue channels are hard to actually distinguish the cells.
Now that we have two candidate representations the saturation or the Green channel, we ask which is easier to work with? Since any HSV work involves us converting the RGB image, we can dismiss it, so the clear choice is to simply use the green channel of the RGB image for segmentation.
edit
since you didn't include a language tag I would like to attach some Matlab code I just wrote. It displays an image in all 4 color spaces so you can quickly make an informed decision on which to use. It mimics matlabs Color Thresholder colorspace selection window
function ViewColorSpaces(rgb_image)
% ViewColorSpaces(rgb_image)
% displays an RGB image in 4 different color spaces. RGB, HSV, YCbCr,CIELab
% each of the 3 channels are shown for each colorspace
% the display mimcs the New matlab color thresholder window
% http://www.mathworks.com/help/images/image-segmentation-using-the-color-thesholder-app.html
hsvim = rgb2hsv(rgb_image);
yuvim = rgb2ycbcr(rgb_image);
%cielab colorspace
cform = makecform('srgb2lab');
cieim = applycform(rgb_image,cform);
figure();
%rgb
subplot(3,4,1);imshow(rgb_image(:,:,1));title(sprintf('RGB Space\n\nred'))
subplot(3,4,5);imshow(rgb_image(:,:,2));title('green')
subplot(3,4,9);imshow(rgb_image(:,:,3));title('blue')
%hsv
subplot(3,4,2);imshow(hsvim(:,:,1));title(sprintf('HSV Space\n\nhue'))
subplot(3,4,6);imshow(hsvim(:,:,2));title('saturation')
subplot(3,4,10);imshow(hsvim(:,:,3));title('brightness')
%ycbcr / yuv
subplot(3,4,3);imshow(yuvim(:,:,1));title(sprintf('YCbCr Space\n\nLuminance'))
subplot(3,4,7);imshow(yuvim(:,:,2));title('blue difference')
subplot(3,4,11);imshow(yuvim(:,:,3));title('red difference')
%CIElab
subplot(3,4,4);imshow(cieim(:,:,1));title(sprintf('CIELab Space\n\nLightness'))
subplot(3,4,8);imshow(cieim(:,:,2));title('green red')
subplot(3,4,12);imshow(cieim(:,:,3));title('yellow blue')
end
you could call it like this
rgbim = imread('http://i.stack.imgur.com/gd62B.jpg');
ViewColorSpaces(rgbim)
and the display is this
in DIP and CV is this always a valid question
But it has no universal answer because each task is unique so use what is better suited for it. To choose correctly you need to know the pros/cons of each so here is some summary:
RGB
this is easy to handle and you can easyly access r,g,b bands. For many cases is better to check just single band instead of whole color or mix the colors to emphasize wanted feature or even dampening unwanted one. It is hard to compare colors in RGB due to intensity encoded into bands directly. To remedy that you can use normalization but that is slow (need per pixel sqrt). You can do arithmetics on RGB colors directly.
Example of task better suited for RGB:
finding horizont in high altitude photo
HSV
is better suited for color recognition because CV algorithms using HSV has very similar visual perception to human perception so if you want to recognize areas of distinct colors HSV is better. The conversion between RGB/HSV takes a bit of time which can be for big resolutions or hi fps apps a problem. For standard DIP/CV tasks is this usually not the case.
Example of task better suited for HSV:
Compare RGB colors
Take a look at:
HSV histogram
to see the distinct color separation in HSV. The segmentation of image based on color is easy on HSV. You can not do arithmetics on HSV colors directly instead need to convert to RGB and back
I need to quantize the RGB values to 29 uniform color dictionary. I used rgb2ind(image,29) in Matlab.
So, is there any function or efficient way to quantize the image color in OpenCV?
(I need to quantize the image color because i want to get a 29-sized histogram of color)
You will have to make your own. I can reccomend using HSV instead of RGB (you can convert RGB to HSV with opencv). Once the image is converted, you can then simply use 29 ranges for the H value.
EDIT: I saw this answer might be a bit vague for those who have little experience in computer vision. This question gives a lot more information about the difference between HSV and RGB and why this is usefull.
I am reading a book for image processing algorithms and for the contrast
algorithm it says that I can either go RGB->HSL or RGB->HSI first and
than apply a contrast technique for grayscale images, on the lightness component.
Then it gives this formula only, not other formulas for color conversion:
L(x,y) = 0.299*R(x,y) + 0.587*G(x,y) + 0.114*B(x,y)
This formula is neither for the L in HSL, neither for the I in HSI and that is
what confuses me.
Thanks
It's the luma value mentioned in the fourth bullet here: http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
I have a greyscale image which was created from a RGB image using farmula:
0.3 * c.r + 0.59 * c.g + 0.11 * c.b
Now, I want to convert the greyscale image back to the RGB color image close to original as far as possible.
I tried o look for it on the internet, but could not find how to do it. Wikipedia suggests that it is possible but does not explain how.
Could someone please suggest how can I do it.
Thanks in advance.
That is not possible. You've taken 3D information, and thrown away 2 of the dimensions. You can't get them back.
You cannot get true color values.
Think of it like this:
you have three unknowns and only one equation.
there are infinite solutions that form a two dimensional plane. You can get a poor representation of the image. Just choose two of the values randomly and calculate thethird one. Hope for the best.
you can generate an RGB value from yoru grayscale if you set R=G=B=Grayscale value
yes you cant, there was some method to make greyscale to RGB, in this method its include RGB image as baseimage. i write code about this before but i completely forgot the method name.
try RGB, alpha beta gamma, some kind like color conversion.
I need a robust motion detection and tracking in web cam's video frames. The background is always the same. The aim is to identify the position of the object, if possible without the shadows, but not so urgent to remove shadows. I've tried the opencv algorithm for background subtraction and thresholding, but this depends on only one image as a background, what if the background changes a little bit in brightness (or camera auto-focus), I need the algorithm to be strong for little changes as brightness or some shadows.
Robust method for tracking are part of broad research interests that are being developed all around the world...
Here are maybe keys to solve your problem that is very interesting but wide and open.
First a lot of them assumes brightness constancy (therefore what you ask is difficult to achieve). For instance:
Lucas-Kanade
Horn-Schunk
Block-matching
is widely used for tracking but assumes brightness constancy.
Then other interesting ones could be meanshift or camshift tracking, but you need a projection to follow... However you can use a back-projection computed accordingly to certain threshold to fit your needs for robustness...
I'll post later about that,
Julien,
When you try the thresholding in OpenCV are you doing this with RGB (red,green,blue) or HSV (hue,saturation,value) colour formats? From personal experience, I find the HSV encoding to be far superior for tracking coloured objects in video footage when used in conjunction with OpenCV for thresholding and cvBlobsLib for identifying the blob location.
HSV is easier since HSV has the advantage of only having to use a single number to detect the colour (“hue”), in spite of the very real probability of there being several shades of that colour, ranging from light to darker shades. (The amount of colour and the brightness of the colour are handled by the “saturation” and “value” parameters respectively).
I threshold the HSV reference image ('imgHSV') to obtain a binary (black and white) image using a call to the cvInRange() OpenCV API:
cvInRangeS( imgHSV,
cvScalar( 104, 178, 70 ),
cvScalar( 130, 240, 124 ),
imgThresh );
In the above example, the two cvScalar parameters are lower and upper bounds of HSV values that represents hues that are blueish in colour. In my own experiments I was able to obtain some suitable max/min values by grabbing screenshots of the object(s) I was interested in tracking and observing the kinds of hue/saturation/lum values that occur.
More detailed descriptions with a code sample can be found on this blog posting.
Andrian has a cool tutorial http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/
I followed and have an good experiment test
https://youtu.be/HJBOOZVefXA
I use static image as well
frameDelta = cv2.absdiff(firstFrame, gray)
thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
(cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
4 lines code find motion well
good luck