Easy color detection

  • Tutorial
Good day.
In this short post I wanted to show an easy way to search for objects by color with OpenCV .

For experiments I used the Logitech WebCam C270 camera.


So let's start.

Connect everything you need.
#include 
#include 
#include  // Для функции exit()
using namespace cv;
using std::cout;
using std::endl;


Declare Variables
char mainWindow[] = "Main";
	char trackbarWindow[] = "Trackbar";
	char thresholdWindow[] = "Threshold";
	int min = 0, max = 1000;
	int hmin = 0, smin = 0, vmin = 0,
		hmax = 255, smax = 255, vmax = 255;
	Mat frame, HSV, threshold, blurred;
	VideoCapture capture;


Create a colorbar trackbar
createTrackbar("H min:", trackbarWindow, &hmin, hmax);
createTrackbar("H max:", trackbarWindow, &hmax, hmax);
createTrackbar("S min:", trackbarWindow, &smin, smax);
createTrackbar("S max:", trackbarWindow, &smax, smax);
createTrackbar("V min:", trackbarWindow, &vmin, vmax);
createTrackbar("V max:", trackbarWindow, &vmax, vmax);
createTrackbar("Size min:", trackbarWindow, &min, max);
createTrackbar("Size max:", trackbarWindow, &max, max);


Open the camera
capture.open(1);
if(!capture.isOpened()){
	cout << "Камера не может быть открыта." << endl;
	exit(1);
}


We start the camera processing cycle
for(;;){
	capture >> frame;
	cvtColor(frame, HSV, COLOR_BGR2HSV);
	medianBlur(HSV, blurred, 21);
	inRange(blurred, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), threshold);
	for(int y = 0; y < threshold.rows; y++){
		for(int x = 0; x < threshold.cols; x++){
			int value = threshold.at(y, x);
			if(value == 255){
				Rect rect;
				int count = floodFill(threshold, Point(x, y), Scalar(200), &rect);
				if(rect.width >= min && rect.width <= max
					&& rect.height >= min && rect.height <= max){
					rectangle(frame, rect, Scalar(255, 0, 255, 4));
				}
			}
		}
	}
		imshow(mainWindow, frame);
		imshow(thresholdWindow, threshold);
		if(waitKey(33) == 27) break;
}


In this loop, we first convert the frame from RGB to HSV. Then we do the blur and call the color search function. The inRange () function does a search based on the “from and to” principle, i.e. from what color to which pixels to select. Then I process each pixel of the frame, if the pixel is white, fill it with gray. Well, with the rectangle () function, select the object by simply drawing a rectangle around the selected area.

Here is an example of a lemon search:


Full source code
#include 
#include 
#include 
using namespace cv;
using std::cout;
using std::endl;
int main(int argc, char **argv){
	char mainWindow[] = "Main";
	char trackbarWindow[] = "Trackbar";
	char thresholdWindow[] = "Threshold";
	int min = 0, max = 1000;
	int hmin = 0, smin = 0, vmin = 0,
		hmax = 255, smax = 255, vmax = 255;
	Mat frame, HSV, threshold, blurred;
	VideoCapture capture;
	//Создаем окна
	namedWindow(mainWindow, 0);
	namedWindow(trackbarWindow, 0);
	namedWindow(thresholdWindow, 0);
	//Создаем трэкбар
	createTrackbar("H min:", trackbarWindow, &hmin, hmax);
	createTrackbar("H max:", trackbarWindow, &hmax, hmax);
	createTrackbar("S min:", trackbarWindow, &smin, smax);
	createTrackbar("S max:", trackbarWindow, &smax, smax);
	createTrackbar("V min:", trackbarWindow, &vmin, vmax);
	createTrackbar("V max:", trackbarWindow, &vmax, vmax);
	createTrackbar("Size min:", trackbarWindow, &min, max);
	createTrackbar("Size max:", trackbarWindow, &max, max);
	//Открываем камеру
	capture.open(1);
	if(!capture.isOpened()){
		cout << "Камера не может быть открыта." << endl;
		exit(1);
	}
	//Запускаем цикл чтения с камеры
	for(;;){
		capture >> frame;
		cvtColor(frame, HSV, COLOR_BGR2HSV);
		medianBlur(HSV, blurred, 21);
		inRange(blurred, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), threshold);
		for(int y = 0; y < threshold.rows; y++){
			for(int x = 0; x < threshold.cols; x++){
				int value = threshold.at(y, x);
				if(value == 255){
					Rect rect;
					int count = floodFill(threshold, Point(x, y), Scalar(200), &rect);
					if(rect.width >= min && rect.width <= max
						&& rect.height >= min && rect.height <= max){
						rectangle(frame, rect, Scalar(255, 0, 255, 4));
					}
				}
			}
		}
		imshow(mainWindow, frame);
		imshow(thresholdWindow, threshold);
		if(waitKey(33) == 27) break;
	}
	return 0;
}


Also popular now: