我目前正在开展一个项目,我需要能够非常可靠地将球的位置放在台球桌上.
我正在使用桌面上方的Kinect v2作为源.
初始image看起来像这样(通过丢弃不在表级别之前的像素将其从16位转换为8位):
然后,我从当前图像中用空表减去参考图像.
在阈值处理和均衡之后,它看起来像这样:image
在单个图像上检测单个球相当容易,问题是我必须以30fps不断地进行检测.
难点:
>低分辨率图像(512 * 424),球的直径约为4-5像素
> Kinect深度图像从这个距离(2米)有很多噪音
>球在深度图像上看起来不同,例如黑球与其他球相比有点倒置
>如果它们彼此接触,那么它们可以成为图像上的一个斑点,如果我尝试用深度阈值分离它们(仅使用球的顶部),那么一些球可以从图像中消失
>除了球以外的任何东西都不应该被检测到非常重要,例如:球杆,手等……
我的过程哪种工作但不够可靠:
通过阈值处理> 16位到8位
>用空表减去样本图像
>裁剪
>阈值
>均衡
>腐蚀
> Dilating
>二进制阈值
>轮廓查找器
>输出坐标上的一些其他算法
问题是可以将球杆或手可以被检测为球,并且如果两个球接触则可以引起问题.也尝试过hough圈,但成功率更低. (如果Kinect更接近但是它无法覆盖整个表格,那么效果很好)
任何线索将非常感激.
最佳答案 扩展以上评论:
我建议尽可能地改进IRL设置.
大多数情况下,确保可靠的设置比在尝试检测/跟踪任何内容之前尝试“修复”用户计算机视觉更容易.
我的建议是:
>将相机移近桌子. (你张贴的图像可以大117%,仍然覆盖口袋)
>将摄像机对准与桌子完全垂直(并确保传感器支架坚固且固定良好):处理完美的俯视视图比略微倾斜的视图(深度渐变显示)更容易. (确保数据可以旋转,但为什么在简单地保持传感器平直时浪费CPU周期)
通过更可靠的设置,您应该能够根据深度进行阈值处理.
你可以对球的中心设置阈值,因为无论如何信息都会被遮挡.球不会变形,因此球半径可能很快降低,球可能会放入口袋中.
如果你有一个清晰的阈值图像,你可以找到Contours()和minEnclosingCircle().另外你应该根据最小和最大半径值来反对结果,以避免视图中的其他对象(手,池提示等).另请查看moments()并确保阅读Adrian’s excellent Ball Tracking with OpenCV article
它使用的是Python,但您应该能够找到与您使用的语言相同的OpenCV调用.
在跟踪方面
如果您使用OpenCV 2.4,您应该查看OpenCV 2.4’s tracking algorithms(例如Lucas-Kanade).
如果您已经使用OpenCV 3.0,那么它拥有自己的list of contributed tracking algorithms(例如TLD).
我建议首先从Moments开始:最初使用最简单且计算量最小的设置,并在进入更复杂的算法之前看看结果是如何得到的(这将需要理解并获得正确的参数以获得预期结果)