Доброго времени суток.
В этом коротком посте хотел показать простой способ поиска объектов по цвету с OpenCV.
Для экспериментов использовал камеру Logitech WebCam C270
Итак начнем
Подключаем всё нужное
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cstdlib> // Для функции exit()
using namespace cv;
using std::cout;
using std::endl;
Объявляем переменные
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;
Создаем трэкбар для регулирования цвета
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<uchar>(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;
}
В этом цикле сначала преобразуем кадр из RGB в HSV. После чего делаем размытие и вызываем функцию поиска цвета. Функция inRange() делает поиск по принципу «от и до», т.е. от какого до какого цвета ей выделять пиксели. Дальше обрабатываю каждый пиксель кадра, если пиксель белого цвета, заливаем его серым. Ну и функцией rectangle() выделяем объект, просто рисуя прямоугольник вокруг выделенной области.
Вот пример поиска лимона:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cstdlib>
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<uchar>(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;
}
Автор: web_loki