5

After reading these tutorials (this & this), I can figure out how to extract any color range including Red, Green, Blue and Yellow, using the Hue value of an HSV image or OpenCV Mat. However this value doesn't have the ability to describe the Gray color that I need to select. So is there any way to extract the Gray pixels of an image using OpenCV?

HansHirse
  • 18,010
  • 10
  • 38
  • 67
peter bence
  • 782
  • 3
  • 14
  • 34

2 Answers2

3

In HSV/HSL colourspace, the grey pixels are characterised by having Saturation of zero or very close to zero, so that test will discriminate black through grey to white pixels. Then the Value/Lightness will tell you how far along the scale from black to white they actually are, low Lightness/Value is dark grey whereas high Lightness/Value means light grey.

In RGB colourspace, grey pixels are characterised by having all three colour components equal, i.e. R=G=B.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • thanks for your valuable information. I really know all of that but still not solving the issue. I'm asking how to implement gray selection using OPENCV!! – peter bence Jun 12 '19 at 22:36
1

After several notes, and knowing that:

  • To get have a white-to-dark-gray color out of an HSV image channels you should have the following values together Hue 0 to 360, Sat 0 to 10 & Val 50 to 100 (Check this page to test your own color range).

  • The OpenCV inRange function doesn't support handling HSV color combinations like this.

I decided to apply the range on each channel alone then getting the intersection of the 3 masks into a final mask that will represent my target white-to-dark-gray color.

Note that in OpenCV H has values from 0 to 180, S and V from 0 to 255. so you need to map your ranges into these limits.

Here is my code:

Mat hueMask1 = new Mat();
Mat satMask2 = new Mat();
Mat valMask3 = new Mat();
Mat white2GrayMask = new Mat();

Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2HSV);
List<Mat> channels_HSV = new ArrayList<>();
Core.split(image,channels_HSV);

Core.inRange(channels_HSV.get(0),new Scalar(0),new Scalar(180),hueMask1);
Core.inRange(channels_HSV.get(1),new Scalar(0),new Scalar(20),satMask2);
Core.inRange(channels_HSV.get(2),new Scalar(70),new Scalar(255),valMask3);

Core.bitwise_and(hueMask1,satMask2,white2GrayMask);
Core.bitwise_and(white2GrayMask,valMask3,white2GrayMask);
peter bence
  • 782
  • 3
  • 14
  • 34