Ask Your Question

Grayscale with weighted colors

asked 2017-05-17 13:56:59 -0500

simons gravatar image

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 :)

Link to full image

image description

edit retag flag offensive 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.

berak gravatar imageberak ( 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.

simons gravatar imagesimons ( 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.

berak gravatar imageberak ( 2017-05-18 04:51:18 -0500 )edit

1 answer

Sort by » oldest newest most voted

answered 2017-05-17 23:34:51 -0500

berak gravatar image

updated 2017-05-17 23:58:05 -0500

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()
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2017-05-17 13:56:59 -0500

Seen: 537 times

Last updated: May 17 '17