我刚刚开始使用 OpenCV 来检测图像中的特定曲线。首先,我想验证是否有曲线,然后,我想根据垂直或水平凸或凹曲线来识别曲线的类型。OpenCV中有可用的功能吗?如果没有,你能给我一些关于如何编写这样一个函数的想法吗?谢谢!顺便说一句,我正在使用 C++。
1 回答
模板匹配不是解决这个问题的可靠方法(它就像从一个小针孔里看一个物体),并且边缘检测器不一定会返回图像中的真实边缘;也会返回诸如由于阴影引起的错误边缘。此外,您还必须处理边缘不完整的问题以及随着图像中场景复杂性的增加而增加的其他问题。
一般来说,您提出的问题是一个非常具有挑战性的问题,除了玩具示例外,没有好的解决方案。
粗略的尝试可能是首先尝试使用边缘检测器(例如建议的 canny 边缘检测器)检测似是而非的边缘。接下来,使用 RANSAC 尝试将检测到的边缘中的点的子集拟合到曲线模型。
例如,假设您正在尝试检测以下形式的曲线 f(x) = ax^2 + bx + c。RANSAC 基本上会尝试从检测到的边缘中的点中找到最适合该曲线模型的子集。要检测不同的曲线,请相应地更改 f(x) 并为每个曲线运行 RANSAC。然后,您可以尝试确定由 f(x) 表示的曲线是否真的存在于您的图像中,使用一些启发式方法应用于 RANSAC 分配给它的点(例如,如果模型拟合的点太少,很可能曲线不存在。但是如何确定点数的良好阈值?)。当您必须考虑允许的转换(例如旋转等)时,您的模型将变得更加复杂。
这种方法的问题在于,您基本上是在尝试将您认为应该在图像中的点与点相匹配,有时,即使您正在寻找的东西不存在,它也会为您返回“最佳”拟合。例如,您从同心圆中检测到一大堆点。如果您尝试从这些点检测直线,RANSAC 将返回最佳拟合线!事实上,根据它在随机初始化阶段选择的点,它可以从不同的运行中为您提供许多不同的行。
有关如何在此类问题上使用 RANSAC 的更多详细信息,请查看Marco Zuliani的RANSAC for Dummies。他还有一个很好的MATLAB 工具箱来配合这份技术报告,您可以将其移植到您选择的语言。
除非你知道你的背景是什么样的,或者如果你可以控制它,例如强制一个干净的背景,这是一个很难解决的问题。