0

假设我们在图像中有一个连接组件,如下图所示:图像 http://dl.dropbox.com/u/92688392/ellipse.jpg

我的问题是如何计算连接组件的边界椭圆(图像中的红色椭圆)。我检查了 MATLAB 函数regionprops,并了解 MATLAB 如何做到这一点。我还注意到 Opencv 具有类似的功能来执行CBlob::GetEllipse()。但是,虽然我了解他们是如何通过阅读代码获得结果的,但其背后的基本理论对我来说仍然不清楚。因此,我想知道是否有一些标准算法可以完成这项工作。谢谢!

编辑:

根据评论,我重新组织了我的问题:在图像时刻维基百科中,最长轴角的计算公式是

公式

但是,在 MATLAB 函数regionprops中,代码如下:

    % Calculate orientation.
    if (uyy > uxx)
        num = uyy - uxx + sqrt((uyy - uxx)^2 + 4*uxy^2);
        den = 2*uxy;
    else
        num = 2*uxy;
        den = uxx - uyy + sqrt((uxx - uyy)^2 + 4*uxy^2);
    end

此实现与维基百科中的公式不一致。我想知道哪个是正确的。

4

3 回答 3

2

如果您正在寻找 OpenCV 实现,我可以给您。算法如下:

  1. 将图像转换为 1 位(黑白)
  2. 查找所有轮廓
  3. 创建包含已建立轮廓的所有点的轮廓
  4. 计算这个轮廓的凸包
  5. 找到包含在上一步轮廓中计算的最小正方形的旋转椭圆(矩形)

这是代码:

Mat src = imread("ellipse.jpg"), tmp;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
vector<Point> bigContour, hull;
RotatedRect ell;

//step 1
cvtColor(src, tmp, CV_BGR2GRAY);
threshold(tmp, tmp, 100, 255, THRESH_BINARY);

//step 2
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

//step 3
for (size_t i=0; i<contours.size(); i++)
{
    for (size_t j=0; j<contours[i].size(); j++)
    {
        bigContour.push_back(contours[i][j]);
    }
}

//step 4
convexHull(bigContour, hull);

//step 5
ell = fitEllipse(hull);

//drawing result
ellipse(src, ell, Scalar(0,0,255), 2);

imshow("result", src);
waitKey();

这是输入:

输入

结果如下:

结果图片

于 2012-08-01T17:17:20.620 回答
1

我试图找出它背后的算法是什么,以便我可以编写自己的实现。我在mathworks 的博客文章中找到了它。在其中一条评论中,作者说:

regionprops 计算所讨论对象的二阶矩,然后返回具有相同二阶矩的椭圆的测量值。

后来:

使用的方程式来自 Haralick 和 Shapiro,Computer and Robot Vision vol。1,附录 A,Addison-Wesley 1992。我通过构建一个包含长轴长度 = 100 和短轴长度 = 50 的椭圆的图像进行了完整性检查,并且 regionprops 返回了正确的测量值。

我没有那本书,但似乎我需要得到一本。

于 2012-09-17T23:43:24.253 回答
0

我不确定 matlab 或 opencv 如何计算椭球。但是如果你对它背后的数学感兴趣,有一种非常好的优化方法,叫做Löwner-John ellipsoid您可以在斯坦福凸优化课程中找到有关此方法的更多信息。我希望它有帮助...

于 2012-08-01T11:22:26.040 回答