gpt4 book ai didi

c++ - OpenCV 的 fitEllipse() 有时会返回完全错误的椭圆

转载 作者:IT老高 更新时间:2023-10-28 22:25:38 26 4
gpt4 key购买 nike

我的目标是识别图像中存在的所有形状。这个想法是:

  1. 提取轮廓
  2. 用不同的形状拟合每个轮廓
  3. 正确的形状应该是面积最接近等高线的面积。

示例图片: enter image description here

我使用 fitEllipse() 来找到最适合轮廓的椭圆,但结果有点困惑: enter image description here

可能正确的椭圆用蓝色填充,边界椭圆用黄色填充。可能不正确的轮廓用绿色填充,(错误的)边界椭圆用青色填充。

如您所见,第一行中三角形边界的椭圆看起来非常适合最佳拟合。第三行中三角形的边界椭圆似乎不是最合适的,但仍然可以作为拒绝错误椭圆的标准。

但我不明白为什么剩下的三角形的边界椭圆完全在它们的轮廓之外。而最坏的情况是最后一行的第三个三角形:椭圆是完全错误的,但它的面积恰好接近轮廓的面积,所以三角形被错误地识别为椭圆。

我错过了什么吗?我的代码:

#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;
}

最佳答案

请记住,fitEllipse 不是 boundingEllipse 的计算,而是假设点位于椭圆上的最小二乘优化。

我无法告诉你为什么它在最后一行的 3 个三角形上失败得如此糟糕,但在上面一行的三角形上“有效”,但我看到的一件事是,最后一行中的所有 3 个三角形被安装到 angle 0 的旋转矩形上。可能最小二乘拟合在那里失败了。

但我不知道 openCV 实现中是否存在错误,或者算法是否无法处理这些情况。使用此算法:http://www.bmva.org/bmvc/1995/bmvc-95-050.pdf

我的建议是,仅在您非常确定这些点确实属于椭圆时才使用 fitEllipse。如果您有随机数据点,您也不会假设从 fitLine 获得合理的结果。您可能想要查看的其他函数是:minAreaRectminEnclosureCircle

如果你使用 RotatedRect temp = minAreaRect(Mat(contours[i])); 而不是 fitEllipse 你会得到这样的图像:

enter image description here

也许您甚至可以同时使用这两种方法并拒绝在两个版本中都失败的所有省略号,并接受两个版本中都接受的所有省略号,但在不同的地方进一步调查?!?

关于c++ - OpenCV 的 fitEllipse() 有时会返回完全错误的椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17159964/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com