我正在使用基于this example的代码,并想知道是否有任何方法可以找出“好”的方法。椭圆拟合是。我有一些椭圆,只是非常适合我的数据,我想摆脱它们,而一些椭圆几乎是完美的。
我希望保持良好的适应性并摆脱糟糕的情况。我怎样才能在opencv
?
答案 0 :(得分:4)
您可以在文献中找到几种方法,例如:
检查 Dilip K. Prasad,Maylor K.H. Leung和Siu-Yeung Cho,“基于边缘曲率和凸性的椭圆检测方法”,模式识别,2012。,Section 4.2
检查 Fornaciari,Michele,Andrea Prati和Rita Cucchiara。 “用于嵌入式视觉应用的快速有效的椭圆探测器。”模式识别47.11(2014):3693-3708。 Section 3.3.1
然而,一种非常简单的方法可以是属于轮廓和椭圆的像素数。您可以计算它,例如,在两个单独的黑色初始化图像上绘制轮廓和椭圆,并计算交叉点的数量,即两个图像的逻辑AND的白色像素的数量。
为了更加健壮,您可以使用线宽2绘制轮廓和椭圆。这将导致略微错位的估计,但仍然在感知上正确。
例如,给定此输入图像:
你可以看到好的椭圆朝向绿色,而糟糕的结果是朝向红色:
代码:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
// Load image
Mat3b img = imread("path_to_image");
// Convert to grayscale. Binarize if needed
Mat1b bin;
cvtColor(img, bin, COLOR_BGR2GRAY);
// Find contours
vector<vector<Point>> contours;
findContours(bin.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// For each contour
for (int i = 0; i < contours.size(); ++i)
{
// Find ellipse
RotatedRect ell = fitEllipse(contours[i]);
// Draw contour
Mat1b maskContour(img.rows, img.cols, uchar(0));
drawContours(maskContour, contours, i, Scalar(255), 2);
// Draw ellips
Mat1b maskEllipse(img.rows, img.cols, uchar(0));
ellipse(maskEllipse, ell, Scalar(255), 2);
// Intersect
Mat1b intersection = maskContour & maskEllipse;
// Count amount of intersection
float cnz = countNonZero(intersection);
// Count number of pixels in the drawn contour
float n = countNonZero(maskContour);
// Compute your measure
float measure = cnz / n;
// Draw, color coded: good -> gree, bad -> red
ellipse(img, ell, Scalar(0, measure*255, 255 - measure*255), 3);
}
imshow("Result", img);
waitKey();
return 0;
}