Параметры для Canny и ApproPolyDP при обнаружении полигонов

Я новичок в OpenCV. Я знаю, что существует много способов обнаружения контуров многоугольников. Но существует ли способ, который дает мне решение, когда я пытаюсь обнаружить контуры многоугольника, которые я нарисовал?

П. С. Извините за мой английский …

Мой код:

Mat src = imread("C:/Users/Nickolay/Desktop/1.jpg");
resize(src, src, Size(400, 400), 0, 0, INTER_CUBIC);
if (src.empty())
{
cout << "Cannot load image!" << endl;
return -1;
}

//================================

Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat bw;
Canny(gray, bw, 800, 850, 5, true);
imshow("canny", bw);
vector<vector<Point>> countours;
findContours(bw.clone(), countours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

vector<Point> approx;
Mat dst = src.clone();

for(int i = 0; i < countours.size(); i++)
{
approxPolyDP(Mat(countours[i]), approx, arcLength(Mat(countours[i]), true) * 0.01, true);

if (approx.size() >= 4 && (approx.size() <= 6))
{
int vtc = approx.size();
vector<double> cos;
for(int j = 2; j < vtc + 1; j++)
cos.push_back(Angle(approx[j%vtc], approx[j-2], approx[j-1]));

sort(cos.begin(), cos.end());

double mincos = cos.front();
double maxcos = cos.back();

if (vtc == 4)// && mincos >= -0.5 && maxcos <= 0.5)
{
Rect r = boundingRect(countours[i]);
double ratio = abs(1 - (double)r.width / r.height);

line(dst, approx.at(0), approx.at(1), cvScalar(0,0,255),4);
line(dst, approx.at(1), approx.at(2), cvScalar(0,0,255),4);
line(dst, approx.at(2), approx.at(3), cvScalar(0,0,255),4);
line(dst, approx.at(3), approx.at(0), cvScalar(0,0,255),4);
SetLabel(dst, "RECT", countours[i]);
}
}
}

//================================

imshow("source", src);
imshow("detected lines", dst);

waitKey(0);

return 0;`

пример

Мой вопрос заключается в том, как определить контуры многоугольника, которые я нарисовал с помощью opencv? В прикрепленных изображениях я использовал функции из opencv, но вместо 5 ожидаемых прямоугольников я получил только 3.

5

Решение

Проблема может заключаться в том, что вы непосредственно передаете изображение края для поиска контура, который может содержать множество не связанных краев.

Так что прежде чем найти контур примените Морфология Преобразования.

лайк,

   Size kernalSize (5,5);
Mat element = getStructuringElement (MORPH_RECT, kernalSize, Point(1,1)  );
morphologyEx( bw, bw, MORPH_CLOSE, element );

Смотрите результат.

Ограничительный прямоугольник для контуров

ограничивающий прямоугольник для контуров

приблизительноPolyDP для контуров

приблизительноPolyDP для контуров

7

Другие решения

Вы также можете попробовать порог, чтобы найти края, а не Canny.

threshold (gray, bw, 0, 255, THRESH_BINARY|THRESH_OTSU);
1