# How to set inRange() bounds properly when converting color with CV_BGR2HLS ?

Good evening,

I'm trying to use inRange() function, in line with cvtColor() but I'm a little bit confused as to the type of inRange() bounds.

I am converting an image from BGR to HLS (which, I don't know why, isn't HSL...), that is :

cv::cvtColor(original, converted, CV_BGR2HLS)


I would like to extract the white/beige pixels from the converted image. My questions are the following:

• Why it is BGR2HLS and not BGR2HSL, which would be more obvious ?
• What values should I put into my cv::Scalar bounds to get these white/beige pixels ? (in which order more precisely : Hue, Saturation and Lightness or Hue, Lightness and Saturation ?)

I am confused about the second question, because when I adjust the trackbars' values this way :

cv::Scalar(0, 115, 0) // lower bound
cv::Scalar(180, 255, 255) // upper bound


I can get white and beige pixels, but these values ​​do not seem to match the HSL range at all.

Thank you for your time !

EDIT: I changed the wording of the question and added some code. The code below is a little helper for me, to adjust HSL bounds.

EDIT2: I am an oyster, I forgot to change the title.

/*                  Taken from stackoverflow */
std::string         typeToString(int type) {
std::string     ret;
uchar           depth = type & CV_MAT_DEPTH_MASK;
uchar           chans = 1 + (type >> CV_CN_SHIFT);

ret = "CV_";
switch (depth) {
case CV_8U:  ret += "8U"; break;
case CV_8S:  ret += "8S"; break;
case CV_16U: ret += "16U"; break;
case CV_16S: ret += "16S"; break;
case CV_32S: ret += "32S"; break;
case CV_32F: ret += "32F"; break;
case CV_64F: ret += "64F"; break;
default:     ret += "User"; break;
}
ret += "C";
ret += (chans + '0');
return (ret);
}

int                 launchHelper() {
cv::Mat         colorConvertedFrame, firstFilterFrame;
int             minH = 0, minS = 0, minL = 0;
int             maxH = 180, maxS = 255, maxL = 255;
cv::Scalar      minBound, maxBound;

if (colorConvertedFrame.empty()) {
std::cerr << "Frame is empty." << std::endl;
return (-1);
}
std::cout << "Your image has type " << typeToString(colorConvertedFrame.type()) << " !" << std::endl;
std::cout << "Your image has " << colorConvertedFrame.channels() << " channel(s) !" << std::endl;
cv::namedWindow("Frame with converted color");
cv::namedWindow("First filter");
cv::namedWindow("Color panel");
cv::createTrackbar("Min H", "Color panel", &minH, 180);
cv::createTrackbar("Max H", "Color panel", &maxH, 180);
cv::createTrackbar("Min S", "Color panel", &minS, 255);
cv::createTrackbar("Max S", "Color panel", &maxS, 255);
cv::createTrackbar("Min L", "Color panel", &minL, 255);
cv::createTrackbar("Max L", "Color panel", &maxL, 255);
while (cv::waitKey(1) != 27) {
minBound = cv::Scalar(minH, minS, minL);
maxBound = cv::Scalar(maxH, maxS, maxL);
cv::inRange(colorConvertedFrame, minBound, maxBound, firstFilterFrame);
cv::imshow("Frame with converted color", colorConvertedFrame);
cv::imshow("First filter", firstFilterFrame);
}
return (0);
}

int                 main(int ac, char **av) {
return (launchHelper());
}

edit retag close merge delete

Sort by » oldest newest most voted

Well, I'm so dumb.

Converting a frame from one palette to another one and using cv::inRange are two things completely different. I thought there was a link between the method used to convert the frame and the bounds of inRange() function, but there are absolutely not.

I hope that my answer will help some people that are confused using those functions together.

Converting a frame from one palette to another one is a thing. Whether you use a particular method, the result is the same : the pixels will be color-converted and the colors will be situated in RGB palette (BGR on OpenCV). Whether you use BGR2HSV or BGR2HLS, pixels will be color-converted to another color.

Using cv::inRange to thresh your frame is another thing. I had originally thought that depending on the method used to color-convert pixels, the bounds of the inRange() function would be different: absolutely not. Since the results of the color-conversion remain in the RGB palette, the bounds must be defined in RGB too (BGR on OpenCV).

cv::Scalar(minimum_blue, minimum_green, minimum_red)
cv::Scalar(maximum_blue, maximum_green, maximum_red)


So, for example, if you only want to retrieve some purple, this would be :

cv::Scalar(135, 0, 65)
cv::Scalar(200, 70, 130)


(NB: this is an example. These bounds are correctly set for purple but they're not an absolute reference for the purple you would consider to retrieve by yourself)

more

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2016-04-23 18:27:41 -0500

Seen: 1,958 times

Last updated: Apr 26 '16