# Grayscale with weighted colors

I'm trying to reproduce the results of Photoshop's "Black and White" color adjustments (Image -> Adjustments -> Black and White) in OpenCV, however I was not able to figure out how they calculate the resulting intensity image. What confuses me is that they use percentages in the HSV color space, and I'm not sure to what the percentage relates to, the "value" channel? Also the percentages range from -200% to +300%....

I created some samples using a color wheel, maybe somebody could give me a hint about how to calculate the intensity?

Thanks a lot in advance :)

edit retag close merge delete

"I'm trying to reproduce the results of Photoshop's .... " this is NOT photoshop.

have a look here for actual conversions used.

( 2017-05-17 16:44:50 -0500 )edit

@berak: I'm well aware that OpenCV is not Photoshop, however Photoshop is a handy tool to pre-process images quickly for testing. I found a good set of parameters to separate the foreground from background for object detection in my case. Usually the greyscale conversion is just a weighted sum of the color channels like described in your link Y←0.299⋅R+0.587⋅G+0.114⋅B. Photoshop does the same here, but the weighting is different and I think it is using the hue value (secondary colors). I just couldn't figure out how the percent values map to the actual intensity in the greyscale image yet.... My goal is to implement a function in C++ which takes the same percentage values and applies the greyscale conversion in the same way as Photoshop in this case.

( 2017-05-17 17:45:24 -0500 )edit

still, opencv is not an appropriate tool to simulate photoshop problems, and photoshop is the wrong tool to solve opencv problems.

( 2017-05-18 04:51:18 -0500 )edit

Sort by » oldest newest most voted

you do not have to "implement" anything on your own, just use cvtColor like:

Mat src = ...
Mat dst;
cvtColor(src, dst, COLOR_BGR2GRAY);


please also note, that it's BGR order in opencv, not RGB, like in photoshop.

again, you won't be able to get a 1 to 1 mapping to photoshop, there's a lot of small differences, like byte order, hue range in [0..180], no support for alpha, etc.

maybe you started your question at the wrong end ? if you wanted to do something like segmentation based on color, you'd roughly do it like this (let's say, looking for cyan):

Mat hsv;
cvtColor(src, hsv, COLOR_BGR2HSV);

Mat binary;
Scalar lo(90-10, 90, 90); // again, H is in [0..180] !
Scalar hi(90+10, 150, 150);
inRange(hsv, lo, hi, binary);
// now use binary e.g. for findContours()

more

Official site

GitHub

Wiki

Documentation