c - 如何确定用于多边形近似的 cvCanny 的最佳参数

标签 c opencv computer-vision feature-detection edge-detection

这是我的源图(忽略点,它们是后来手动添加的):

enter image description here

我的目标是获得两只手的粗略多边形近似值。像这样:

enter image description here

我对如何做到这一点有一个大概的想法;我想用 cvCanny寻找边缘,cvFindContours找到轮廓,然后 cvApproxPoly .

我面临的问题是我不知道如何正确使用 cvCanny,特别是我应该为最后 3 个参数(阈值 1 和 2、光圈大小)使用什么?我尝试这样做:

cvCanny(source, cannyProcessedImage, 20, 40, 3);

但结果并不理想。左手看起来还不错,但右手检测的很少:

enter image description here

总的来说,它并不像我希望的那样可靠。有没有办法猜测 Canny 的“最佳”参数,或者至少有详细的解释(初学者可以理解)他们所做的,以便我可以做出有根据的猜测?或者也许有更好的方法来完全做到这一点?

最佳答案

看来你必须降低阈值。

Canny 算法在滞后阈值上工作:如果至少有一个像素与最大阈值一样亮,它会选择一个轮廓,如果它们高于下阈值,则采用所有连接的轮廓像素。

论文建议采用 2:1 或 3:1 比例的两个阈值(例如 10 和 30,或 20 和 60 等)。对于某些应用程序,手动确定并硬编码的阈值就足够了。这也可能是你的情况。我怀疑如果你降低阈值,你会得到好的结果,因为图像并没有那么复杂。

已经提出了许多自动确定最佳精明阈值的方法。他们中的大多数依靠梯度大小来估计最佳阈值。

步骤:

  • 提取梯度(Sobel 是一个不错的选择)
  • 您可以将其转换为 uchar。梯度理论上可以具有比 255 更大的数值,但这没关系。 opencv 的 sobel 返回 uchars。
  • 制作结果图像的直方图。
  • 在直方图的第 95 个百分位处取最大阈值,较低的阈值为 high/3。
  • 您可能应该根据您的应用调整百分位数值,但结果会比硬编码的高值和低值更稳健

注意:在Matlab中实现了一个优秀的阈值检测算法。它基于上述想法,但更复杂一些。

注意 2:如果图像区域之间的轮廓和光照变化不大,则此方法会起作用。如果图像的某个部分的轮廓更清晰,那么您需要局部自适应阈值,那就是另一回事了。但是看你的照片,应该不是这样的。

关于c - 如何确定用于多边形近似的 cvCanny 的最佳参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11515072/

相关文章:

c - 如何使用自定义端口(非默认)仅使用 telnet 或 FTP 连接服务器和客户端(在 C 语言的套接字编程中)?

有向图的 C 输入

c++ - 如何将 STX/ETX(C0 控制代码)写入 BSTR 缓冲区 IXMLDOMElement*

c++ - 使用 OpenCV 将帧转换为就像从上方获取的一样

c++ - 精细控制GCC的输出

python - 通过分析 skype 屏幕截图找出谁开始了对话 - python

c++ - OpenCV findContours 点 vector

opencv - 与 OpenCV 3.0 链接时出现“未解析的外部符号”错误

compiler-errors - 空未声明的标识符错误

video - 在编码视频时强制 GStreamer 管道实时运行