Ask Your Question

# threshold yuv image

Hi! I want to create a binary image from a yuv image. Before I do this with rgb image with this code:

IplImage imgThreshold = cvCreateImage(cvGetSize(img), 8, 1);
cvInRangeS(img, rgba_min, rgba_max, imgThreshold);
cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 15);


How can i create theshold image from yuv image?

Thank you!

edit retag close merge delete

## 1 answer

Sort by » oldest newest most voted

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) + (0.504 x channels) + (0.098 x channels) + 16;
Mat U = -(0.148 x channels) - (0.291 x channels) + (0.439 x channels) + 128;
Mat V = (0.439 x channels) - (0.368 x channels) - (0.071 x  channels) + 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 );

more

## Comments

Thank you for your answer. Now I want to extract a color object from the yuv image (threshold/binary image). So in binary image I want my color object in white and all the other in black. I don't understand how can I do this!

google opencv + object detection. I will not solve the project for you ;)

I keep reading that OpenCV uses the BGR channels instead of RGB. However, I get a more stable result (e.g. color detection) on my Android Nexus S device when I use COLOR_RGB2HSV instead of COLOR_BGR2HSV. So, is this a myth then?

Imgproc.cvtColor(rgbaImage, mHsvMat, Imgproc.COLOR_RGB2HSV);

Core.inRange(mHsvMat, new Scalar(60, 100, 30), new Scalar(130, 255, 255), mProcessedMat); // green color

Actually you are mixing two things up. The C++ interface uses BGR images, which means you need to use the BGR2HSV function after an imread to get the correct values. HOWEVER, the android API captures images in the RGBA format, so if you want to transform those, you will need the RGB2HSV function, whch will simply ignore the alpha channel.

1

Hum! That makes more sense now. Thanks for the clarification Steven.

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2013-08-27 07:21:44 -0500

Seen: 3,466 times

Last updated: Aug 27 '13