我的目标是识别图像中存在的所有形状。这个想法是:
- 提取轮廓
- 用不同的形状拟合每个轮廓
- 正确的形状应该是最接近轮廓区域的形状。
示例图片:
我用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;
}