Моя цель - распознать все фигуры, присутствующие в изображении. Идея такова:
- Контуры извлечения
- Установите каждый контур с различными формами
- Правильная форма должна быть той, у которой есть область, наиболее близкая к область контура.
Пример изображения:
Я использую fitEllipse()
, чтобы найти наилучший подходящий эллипс для контуров, но результат немного грязный:
Вероятно правильные эллипсы заполняются синим, а ограничивающие эллипсы - желтыми. Вероятно-неправильные контуры заполняются зеленым цветом, а (неправильные) ограничивающие эллипсы являются голубыми.
Как вы можете видеть, эллипс, ограничивающий треугольник в первом ряду, выглядит очень хорошо для наилучшего соответствия. Ограничивающий эллипс треугольника в третьей строке, по-видимому, не лучший, но приемлемый в качестве критерия для отклонения неправильного эллипса.
Но я не могу понять, почему остальные треугольники имеют ограничивающий эллипс полностью вне их контура. И наихудший случай - третий треугольник в последней строке: эллипс совершенно не прав, но он имеет область, близкую к области контура, поэтому треугольник ошибочно распознается как эллипс.
Пропустить что-нибудь? Мой код:
#include <iostream>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace std;
using namespace cv;
void getEllipses(vector<vector<Point> >& contours, vector<RotatedRect>& ellipses) {
ellipses.clear();
Mat img(Size(800,500), CV_8UC3);
for (unsigned i = 0; i<contours.size(); i++) {
if (contours[i].size() >= 5) {
RotatedRect temp = fitEllipse(Mat(contours[i]));
if (area(temp) <= 1.1 * contourArea(contours[i])) {
//cout << area(temp) << " < 1.1* " << contourArea(contours[i]) << endl;
ellipses.push_back(temp);
drawContours(img, contours, i, Scalar(255,0,0), -1, 8);
ellipse(img, temp, Scalar(0,255,255), 2, 8);
imshow("Ellipses", img);
waitKey();
} else {
//cout << "Reject ellipse " << i << endl;
drawContours(img, contours, i, Scalar(0,255,0), -1, 8);
ellipse(img, temp, Scalar(255,255,0), 2, 8);
imshow("Ellipses", img);
waitKey();
}
}
}
}
int main() {
Mat img = imread("image.png", CV_8UC1);
threshold(img, img, 127,255,CV_THRESH_BINARY);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(img, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
vector<RotatedRect> ellipses;
getEllipses(contours, ellipses);
return 0;
}