Вы должны сначала сегментировать цвет, а затем найдите контуры сегментированного изображения.
СЕГМЕНТ ЦВЕТ
Работа в HSV в целом является хорошей идеей для цветов сегмента. Когда у вас есть правильная нижняя и верхняя граница, вы можете легко сегментировать цвет. Простым подходом является использование inRange. Вы можете найти, как его использовать here например.
НАЙТИ ГРАНИЦЫ
После того как вы двоичная маска (полученную через сегментацию), вы можете найти ее границы с помощью findContours. Вы можете обратиться к this или this, чтобы узнать, как использовать findContours
, чтобы обнаружить границу, и drawContours
, чтобы нарисовать его.
UPDATE
Вот рабочий пример о том, как нарисовать контур на сегментированных объектов. Я использовал морфологию для очистки маски и изменил ее на синий цвет, но вы можете поместить свой любимый цвет.
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
VideoCapture cap(0);
while (true)
{
Mat img;
cap.read(img);
Mat dst;
Mat imghsv;
cvtColor(img, imghsv, COLOR_BGR2HSV);
inRange(imghsv, Scalar(110, 100, 100), Scalar(130, 255, 255), dst); // Detect blue objects
// Remove some noise using morphological operators
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7,7));
morphologyEx(dst, dst, MORPH_OPEN, kernel);
// Find contours
vector<vector<Point>> contours;
findContours(dst.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
// Draw all contours (green)
// This
drawContours(img, contours, -1, Scalar(0,255,0));
// If you want to draw a contour for a particular one, say the biggest...
// Find the biggest object
if (!contours.empty())
{
int idx_biggest = 0;
int val_biggest = contours[0].size();
for (int i = 0; i < contours.size(); ++i)
{
if (val_biggest < contours[i].size())
{
val_biggest = contours[i].size();
idx_biggest = i;
}
}
// Draw a single contour (blue)
drawContours(img, contours, idx_biggest, Scalar(255,0,0));
// You want also the rotated rectangle (blue) ?
RotatedRect r = minAreaRect(contours[idx_biggest]);
Point2f pts[4];
r.points(pts);
for (int j = 0; j < 4; ++j)
{
line(img, pts[j], pts[(j + 1) % 4], Scalar(0, 0, 255), 2);
}
}
imshow("name", dst);
imshow("image", img);
if (waitKey(30) == 27) //wait for 'esc' key press for 30ms
{
cout << "esc key is pressed by user" << endl;
break;
}
}
}
вы должны размещать больше информации: эталонное изображение, язык программирования, ваши HSV ограничивающей – Miki
т.е. [mcve] (http://stackoverflow.com/help/mcve) – kkuilla
Поскольку вы обновили свой вопрос с некоторыми код, я также обновил свой ответ с помощью некоторого кода! Проверьте это и посмотрите, соответствует ли он вашим потребностям. (В следующий раз, пожалуйста, сообщите людям, что вы обновили вопрос с комментариями к их ответам) – Miki