Доброго времени суток.
В этом коротком посте хотел показать простой способ поиска объектов по цвету с OpenCV.
Для экспериментов использовал камеру Logitech WebCam C270
Итак начнем
Подключаем всё нужное
Объявляем переменные
Создаем трэкбар для регулирования цвета
Открываем камеру
Запускаем цикл обработки камеры
В этом цикле сначала преобразуем кадр из RGB в HSV. После чего делаем размытие и вызываем функцию поиска цвета. Функция inRange() делает поиск по принципу «от и до», т.е. от какого до какого цвета ей выделять пиксели. Дальше обрабатываю каждый пиксель кадра, если пиксель белого цвета, заливаем его серым. Ну и функцией rectangle() выделяем объект, просто рисуя прямоугольник вокруг выделенной области.
Вот пример поиска лимона:
В этом коротком посте хотел показать простой способ поиска объектов по цвету с 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; }
