HSV v RGB with inRange

asked Aug 14 '19

I used a colour picker and worked out equivalent range values in HSV and RGB for my special yellow.

Scalar yellowHsvMin = new Scalar(50, 35, 40);
Scalar yellowHsvMax = new Scalar(55, 91, 71);

Scalar yellowRgbMin = new Scalar(139, 127, 66);
Scalar yellowRgbMax = new Scalar(249, 238, 114);

But when I apply a filter using the HSV values:

Mat raw = Imgcodecs.imread("file.jpg");
Matt colours = new Matt(raw.size(), raw.type());
Matt yel = new Matt(raw.size(), raw.type());
Imgproc.cvtColor(raw, colours, Imgproc.COLOR_BGR2HSV);
Core.inRange(colours, yellowHsvMin, yellowHsvMax, yel);

I get a hugely different answer to using RGB values:

Mat raw = Imgcodecs.imread("file.jpg");
Matt colours = new Matt(raw.size(), raw.type());
Matt yel = new Matt(raw.size(), raw.type());
Imgproc.cvtColor(raw, colours, Imgproc.COLOR_BGR2RGB);
Core.inRange(colours, yellowRgbMin, yellowRgbMax, yel);

I would expect it to be slightly different from rounding errors etc but it's completely different. Can anyone help me understand what I'm doing wrong?

Preview: (hide)

Comments

1

see Color conversions RGB ↔ HSV and notice

8-bit images: V←255V,S←255S,H←H/2(to fit to 0 to 255)

sturkmen gravatar imagesturkmen (Aug 15 '19)edit

the upper limit of H would be 179 but your H in yellowRgbMax is 249, which may make more colors(especially red) show in your image.

gino0717 gravatar imagegino0717 (Aug 15 '19)edit

@gino0717 The "H" in yellow-->Rgb<--Max is 249 because it's only used in the RGB channels. yellow-->Hsv<--Max is 55 (below 179) and is used with the COLOR_BGR2HSV channels.

davidnewcomb gravatar imagedavidnewcomb (Aug 16 '19)edit

try swap your channel 0 and channel 2 like:

Scalar yellowRgbMin = new Scalar(66, 127, 139);
Scalar yellowRgbMax = new Scalar(114, 238, 249);

since the color in opencv channel is ( blue , green , red ) instead of ( red , green , blue )

gino0717 gravatar imagegino0717 (Aug 16 '19)edit

There is no need to swap the channels in the scalar because the colour conversion (COLOR_BGR2--->RGB<---) has already converted it to RGB. In fact the RGB code (above) is pretty good. I don't understand why when I pick 2 shades of yellow (min/max) the RGB/BGR works fine but the HSV is useless. Even if I do min(45, 100, 100) and max(66, 255, 255) with BGR2HSV I expect to get everything that is yellowy but I get nearly all black. I am clearly not understanding something about HSV colour filtering but I don't know what it is.

davidnewcomb gravatar imagedavidnewcomb (Aug 16 '19)edit

@sturkman not sure why you posted the link? Looks like you are just saying v,s [0,255] and h [0,179] which isn't relevant either because none of my hsv values are outside that range.

davidnewcomb gravatar imagedavidnewcomb (Aug 16 '19)edit
1

i mean you need to half of H values

Scalar yellowHsvMin = new Scalar(25, 35, 40);
Scalar yellowHsvMax = new Scalar(28, 91, 71);
sturkmen gravatar imagesturkmen (Aug 17 '19)edit