Ask Your Question

Revision history [back]

First of all, you are using a very complex way of thresholding a RGB image. I suggest using the C++ - API and use its advantages. Also take a look at the threshold and cvtColor functionality.

Also, OpenCV uses the BGR channels in stead of RGB, so be aware of that order change!

Basically what you would do is something like this, if you can use another colormapping:

// Read in original BGR image
Mat image_input = imread("location.jpeg");
// Convert to HSV
Mat image_HSV;
CvtColor(image_input, image_HSV, CV_BGR2HSV);
// Threshold this image
Mat image_threshold;
int threshold = 120;
Threshold(image_HSV, image_threshold, threshold, THRESH_BINARY);

EDIT: it seems that YUV is actually equal to YCrCb, as mentioned here. For actual YUV formatting you should use applies to the following rules.

Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

Which results in the following code:

// Read in original BGR image
Mat image_input = imread("location.jpeg");
// Convert to YUV
Mat image_YUV;
CvtColor(image_input, image_YUV, CV_BGR2YCrCb);
// Threshold this image
Mat image_threshold;
int threshold = 120;
Threshold(image_YUV, image_threshold, threshold, THRESH_BINARY);

First of all, you are using a very complex way of thresholding a RGB image. I suggest using the C++ - API and use its advantages. Also take a look at the threshold and cvtColor functionality.

Also, OpenCV uses the BGR channels in stead of RGB, so be aware of that order change!

Basically what you would do is something like this, if you can use another colormapping:

// Read in original BGR image
Mat image_input = imread("location.jpeg");
// Convert to HSV
Mat image_HSV;
CvtColor(image_input, image_HSV, CV_BGR2HSV);
// Threshold this image
Mat image_threshold;
int threshold = 120;
Threshold(image_HSV, image_threshold, threshold, THRESH_BINARY);

EDIT: it seems that YUV is actually equal to YCrCb, as mentioned here. For actual YUV formatting you should use applies to the following rules.

Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

Which results in the following code:

// Read in original BGR image
Mat image_input = imread("location.jpeg");
// Convert to YUV
Mat image_YUV;
CvtColor(image_input, image_YUV, CV_BGR2YCrCb);
// Threshold this image
Mat image_threshold;
int threshold = 120;
Threshold(image_YUV, image_threshold, threshold, THRESH_BINARY);

Or if you ever encounter a format where you can find transformation parameters for, then you can apply the formulas yourself, just split the channels.

//Read in an image in BGR
Mat image_input = imread("location.jpeg");
//Split into channels
vector<Mat> channels;
split(image_input, channels);
//Apply transformations
//Replace the x by asterixes, but the forum doesn't allow me to use them...
Mat Y = (0.257 x channels[2]) + (0.504 x channels[1]) + (0.098 x channels[0]) + 16;
Mat U = -(0.148 x channels[2]) - (0.291 x channels[1]) + (0.439 x channels[0]) + 128;
Mat V = (0.439 x channels[2]) - (0.368 x channels[1]) - (0.071 x  channels[0]) + 128;
//mix channels back together
Mat result_HSV(image_input.rows, image_input.cols, CV_8UC3);
Mat in[] = { Y, U, V };
int from_to[] = { 0,0, 1,1, 2,2 };
mixChannels( in, 3, &result_HSV, 1, from_to, 3 );