我想检测图像中的椭圆。由于当时正在学习Mathematica,所以问了一个问题here并从下面的答案中得到了满意的结果,该答案使用RANSAC算法检测椭圆。
但是,最近我需要将其移植到OpenCV,但是有一些功能只存在于Mathematica中。关键函数之一是“GradientOrientationFilter”函数。
由于一般椭圆有五个参数,因此我需要采样五个点才能确定一个。然而,采样点越多,猜测正确的机会越小,从而导致椭圆检测的成功率较低。因此,Mathematica的答案又增加了一个条件,即图像的梯度必须与椭圆方程的梯度平行。无论如何,我们只需要三个点就可以使用 Mathematica 方法中的最小二乘法确定一个椭圆。结果还是不错的。
但是,当我尝试在 OpenCV 中使用 Sobel 或 Scharr 算子求图像梯度时,它不够好,这总是导致不好的结果。
如何准确计算图像的梯度或正切?谢谢!
带梯度的结果,三点
无梯度结果,五分
----------已更新----------
我事先做了一些边缘检测和中值模糊,并将结果绘制在边缘图像上。我的原始测试图像是这样的:
总的来说,我的最终目标是检测场景中或物体上的椭圆。像这样的事情:
这就是为什么我选择使用 RANSAC 从边缘点拟合椭圆。
最佳答案
至于你的最终目标,你可以尝试一下
<强> findContours 和 [fitEllipse] 在 OpenCV
伪代码为
1)一些图像处理
2)找到所有轮廓
3)通过fitEllipse拟合每个轮廓
这是我之前使用的部分代码
[... image process ....you get a bwimage ]
vector<vector<Point> > contours;
findContours(bwimage, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
for(size_t i = 0; i < contours.size(); i++)
{
size_t count = contours[i].size();
Mat pointsf;
Mat(contours[i]).convertTo(pointsf, CV_32F);
RotatedRect box = fitEllipse(pointsf);
/* You can put some limitation about size and aspect ratio here */
if( box.size.width > 20 &&
box.size.height > 20 &&
box.size.width < 80 &&
box.size.height < 80 )
{
if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 )
continue;
//drawContours(SrcImage, contours, (int)i, Scalar::all(255), 1, 8);
ellipse(SrcImage, box, Scalar(0,0,255), 1, CV_AA);
ellipse(SrcImage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(200,255,255), 1, CV_AA);
}
}
imshow("result", SrcImage);
关于c++ - 如何使用 OpenCV 检测图像梯度或法线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22804875/