假设我们在图像中有一个连接的组件,如下图所示:image http://dl.dropbox.com/u/92688392/ellipse.jpg。
我的问题是如何计算连通分量的边界椭圆(图像中的红色椭圆)。我检查了MATLAB函数regionprops,并了解MATLAB如何做到这一点。我还注意到Opencv具有与CBlob::GetEllipse()类似的功能。然而,虽然我理解他们如何通过阅读代码获得结果,但其背后的基本理论仍然不清楚。因此,我想知道是否有一些标准算法来完成这项工作。谢谢!
修改
根据评论,我重新组织了我的问题:在image moment Wikipedia中,最长轴角的计算公式是
但是,在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
此实现与Wikipedia中的公式不一致。我想知道哪一个是正确的。
答案 0 :(得分:2)
如果您正在寻找OpenCV实施,那么我可以将其提供给您。算法如下:
这是代码:
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();
这是输入:
这是一个结果:
答案 1 :(得分:1)
我试图找出它背后的算法是什么,所以我可以编写自己的实现。我在blog post of mathworks找到了它。在其中一条评论中,作者说:
regionprops计算相关物体的二阶矩,然后返回具有相同二阶矩的椭圆的测量结果。
以及稍后:
使用的等式来自Haralick和Shapiro,计算机和机器人视觉卷。 1,附录A,Addison-Wesley 1992.我通过构建包含长轴长度= 100且短轴长度= 50的椭圆的图像进行了健全性检查,并且regionprops返回了正确的测量结果。
我没有那本书,但似乎我需要得到它的副本。
答案 2 :(得分:0)
我不确定matlab或opencv如何计算椭圆体。但是如果你对它背后的数学感兴趣,那么有一种非常好的优化方法叫做Löwner-John ellipsoid。您可以在斯坦福Convex Optimization课程中找到有关此方法的更多信息。我希望它有所帮助...