这是我的源图像(忽略点,稍后手动添加):
我的目标是获得两只手的粗略多边形近似值。像这样:
我对如何做到这一点有一个大概的了解;我想使用cvCanny
查找边,cvFindContours
查找轮廓,然后cvApproxPoly
。
我面临的问题是我不知道如何正确使用cvCanny
,尤其是我应该对最后3个参数(threshold1& 2,apertureSize)使用什么?我试过了:
cvCanny(source, cannyProcessedImage, 20, 40, 3);
但结果并不理想。左手看起来相对较好,但右手检测得很少:
总的来说,它并不像我想的那么可靠。有没有办法猜测Canny的“最佳”参数,或者至少是一个详细的解释(初学者可以理解)他们做了什么,所以我可以做出有根据的猜测?或者也许还有一种更好的方法可以完成这项工作?
答案 0 :(得分:6)
似乎你必须降低你的门槛。
Canny算法适用于滞后阈值:如果至少一个像素与最大阈值一样明亮,则选择一个轮廓,如果它们高于下限阈值,则选择所有连接的轮廓像素。
论文建议采用2:1 oe 3:1(例如10和30,或20和60等)的两个阈值。对于某些应用程序,手动和硬编码确定的阈值就足够了。也可能是你的情况。我怀疑如果你降低你的门槛,你会得到很好的结果,因为图像并不复杂。
已经提出了许多自动确定最佳精确阈值的方法。他们中的大多数依靠梯度幅度来估计最佳阈值。
<强>步骤:强>
注意:在Matlab中实现了一个优秀的阈值检测算法。它基于上面的想法,但有点复杂。
注意2 :如果图像区域之间的轮廓和照明变化不大,此方法将起作用。如果轮廓在图像的一部分上更清晰,那么您需要局部自适应阈值,这是另一个故事。但是看着你的照片,情况应该不是这样。
答案 1 :(得分:4)
也许最简单的解决方案之一就是在灰度图像上进行Otsu阈值处理,在二值图像上找到轮廓,然后近似它们。这是代码:
Mat img = imread("test.png"), gray;
vector<Vec4i> hierarchy;
vector<vector<Point2i> > contours;
cvtColor(img, gray, CV_BGR2GRAY);
threshold(gray, gray, 0, 255, THRESH_OTSU);
findContours(gray, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
for(size_t i=0; i<contours.size(); i++)
{
approxPolyDP(contours[i], contours[i], 5, false);
drawContours(img, contours, i, Scalar(0,0,255));
}
imshow("result", img);
waitKey();
这就是结果: