Build H-value histogram of HSV image: wrong parameters?

asked 2019-12-16 10:49:40 -0600

michlvl gravatar image

updated 2019-12-16 12:21:55 -0600

Hi,

I want to build histogram of Hue value of HSV image.

My initial image:

image description

This is what Photoshop gives for it (just to have some reference, I suppose its not real HSV):

image description

Histogram that I've got:

image description

As soon as there are majority of green color and also some Red and Blue spots present, I suppose "colored" version should looks something like that:

colored_histo

Few peaks of red, blue and high peak of green.

1) Am I correct in this assumption?

Now I want to check this with simple HSV selection. And I've got ranges:

160...200 for red strip RED

110..170 for blue strip image description

Blue strip range is kind of expected result, but red confused me.

After I checked color in picture editor, I've got this. (in this software H channel is in range 0 ... 360)

Red: image description

Blue: image description

2) "Red" ranges should be 0...10 % of scale (or at 90...100 %), why on color selection its ~70...80% ?

As far as I know OpenCV v2.x.x used 0...127 for H channel, but later it was updated. Some sources says its 180, some its 255.

3) Does range 0...255 is correct for H-channel in OpenCV 4.1.2?

I cant figure out this... My HSV selection and histogram building based in assumption that range is 0...255

Are there any glance errors in my code?

HSV selector:

Mat HSVSelection(Mat& img_input, const char* window_name){
  Mat camera_HSV;
  Mat camera_HSV_th;

  static int iLowH = 0;
  static int iHighH = 255;

  static int iLowS = 0;
  static int iHighS = 255;

  static int iLowV = 0;
  static int iHighV = 255;

  //create a window
  namedWindow(window_name, CV_WINDOW_AUTOSIZE); 

  //Create trackbars in window
  cvCreateTrackbar("Low_H", window_name, &iLowH, 255); //Hue (0 - 255)
  cvCreateTrackbar("High_H", window_name, &iHighH, 255);

  cvCreateTrackbar("Low_S", window_name, &iLowS, 255); //Saturation (0 - 255)
  cvCreateTrackbar("High_S", window_name, &iHighS, 255);

  cvCreateTrackbar("Low_V", window_name, &iLowV, 255); //Value (0 - 255)
  cvCreateTrackbar("High_V", window_name, &iHighV, 255);

   //Convert the captured frame from BGR to HSV
  cvtColor(img_input, camera_HSV, COLOR_BGR2HSV); 

  //Threshold the image
  inRange(camera_HSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), camera_HSV_th); 

  return camera_HSV_th;
}

Histogram:

int bins = 255;

void buildHistogram(Mat& camera_input)
{
  Mat hue;
  Mat hist;

  hue.create(camera_input.size(), camera_input.depth());
  int ch[] = { 0, 0 };
  mixChannels(&camera_input, 1, &hue, 1, ch, 1);

  int histSize = MAX(bins, 2); 
  float hue_range[] = { 0, 255 }; // CORRECT RANGE?
  const float* ranges = { hue_range };

  calcHist(&hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
  normalize(hist, hist, 0, histSize, NORM_MINMAX, -1, Mat()); // can be always normalizeto to [0 , 255]?

  int w = 400, h = 400;
  int bin_w = cvRound((double)w / histSize);

  Mat histImg = Mat::zeros(h, w, CV_8UC3);

  for (int i = 0; i < bins; i++)
  {
      int px_qty = cvRound(hist.at<float>(i)*h / 255.0);

      rectangle(histImg, Point(i*bin_w, h), Point((i + 1)*bin_w, h - px_qty),
        COLOR_WHITE,
        FILLED);
  }

  imshow("HISTOGRAM", histImg);
}
edit retag flag offensive close merge delete

Comments

hue is in [0..180] (it has to fit into a byte) in opencv

berak gravatar imageberak ( 2019-12-17 01:02:01 -0600 )edit