Skip to content

Instantly share code, notes, and snippets.

@heisters
Last active October 9, 2015 19:17
Show Gist options
  • Save heisters/3562715 to your computer and use it in GitHub Desktop.
Save heisters/3562715 to your computer and use it in GitHub Desktop.
Function for elegantly performing range thresholding with arbitrary colors and ranges with OpenCV
// This code is modified from the working version to remove coupling with the original
// application, and hasn't been tested in its new form. So, it's enough to give you
// the basic idea, but may not entirely work ;)
//
// It assumes the src image is in HSV and the dst image is grayscale.
//
// CvScalar red = cvScalar(179, 255, 255);
// CvScalar lowOffset = cvScalar(-20, -150, -150); // find colors down to h = 159, s = 105, v = 105
// CvScalar highOffset = cvScalar(20, 0, 0); // find colors up to h = 19, s = 255, v = 255 (h wraps/is mod 179)
// colorThreshold(img, thresholded, red, lowOffset, highOffset);
void function colorThreshold
(IplImage & src, IplImage & dst, CvScalar & color, CvScalar & low, CvScalar & high)
{
cv::Mat m_src = src;
cv::Mat m_dst = dst;
int hMidPoint = 89;
// you may want to change these or pass them in to threshold saturation or value
int sMidPoint = 125;
int vMidPoint = 125;
int rotation = hMidPoint - color.val[0];
for(int row = 0; row < m_src.rows; ++row) {
uchar * p_src = m_src.ptr<uchar>(row);
uchar * p_dst = m_dst.ptr<uchar>(row);
for (int col = 0; col < m_src.cols; ++col) {
int srcH = *p_src++;
int srcS = *p_src++;
int srcV = *p_src++;
int dst = 0;
int rotated = (srcH + rotation) % 179;
if(rotated >= hMidPoint + low.val[0] && rotated <= hMidPoint + high.val[0] &&
srcS >= sMidPoint + low.val[1] && srcS <= sMidPoint + high.val[1] &&
srcV >= vMidPoint + low.val[2] && srcV <= vMidPoint + high.val[2]) {
dst = 255;
}
*p_dst++ = dst;
}
}
}
@anthonykeane
Copy link

Good contributor thanks,
For others can you init s an v

@EdgeCaseBerg
Copy link

What should s and v be initialized to? And what do they represent? some type of saturation offset?

@heisters
Copy link
Author

heisters commented Aug 7, 2014

yes, if you were performing a saturation/value thresholding, they would be the midpoints of your range. I'll update the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment