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;
colorConvertedFrame = cv::imread(IMAGE_PATH);
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());
}