我目前正在开展一个项目,我需要能够非常可靠地确定球在台球 table 上的位置。
我在 table 上方使用 Kinect v2 作为源。
初始image看起来像这样(在通过丢弃不在表级别附近的像素将其从 16 位转换为 8 位之后):
然后我从当前图像中减去带有空表的引用图像。
经过阈值化和均衡后,它看起来像这样:image
在单个图像上检测单个球相当容易,问题是我必须以 30fps 不断地检测。
难点:
- 低分辨率图片 (512*424),球的直径约为 4-5 像素
- Kinect 深度图像在这个距离(2 米)处有很多噪声
- 球在深度图像上看起来不同,例如黑球与其他球相比有点倒置
- 如果它们相互接触,那么它们可能会变成图像上的一个 Blob ,如果我尝试使用深度阈值将它们分开(仅使用球的顶部),那么一些球可能会从图像中消失
- 除了球以外的任何东西都不应该被检测到,这一点非常重要,例如:球杆、手等...
我的过程哪种有效但不够可靠:
- 通过阈值从 16 位到 8 位
- 用空表减去示例图像
- 裁剪
- 阈值
- 均衡
- 侵 eclipse
- 膨胀
- 二进制阈值
- 轮廓查找器
- 一些关于输出坐标的进一步算法
问题是台球杆或手可以被检测为球,而且如果两个球接触则可能会导致问题。还尝试使用 hough 圆,但收效甚微。 (如果 Kinect 更近,效果很好,但它不能覆盖整个 table )
任何线索将不胜感激。
最佳答案
扩展上面的注释:
我建议尽可能改进 IRL 设置。 大多数情况下,确保可靠的设置比在开始检测/跟踪任何东西之前尝试“修复”用户计算机视觉更容易。
我的建议是:
- 将相机移近 table 。 (您发布的图片可以大 117%,但仍能盖住口袋)
- 将相机与 table 完全垂直(并确保传感器支架坚固且固定良好):处理完美的自上而下的 View 比稍微倾斜的 View (这是深度梯度显示的)更容易). (确保数据可以旋转,但是当您可以简单地保持传感器笔直时,为什么要浪费 CPU 周期)
通过更可靠的设置,您应该能够根据深度设置阈值。 你可能会到达球的中心,因为下面的信息无论如何都被遮挡了。球不会变形,所以如果半径减小得很快,球可能会进入口袋。
如果您有清晰的阈值图像,您可以findContours()
和minEnclosingCircle() .此外,您应该根据最小和最大半径值来限制结果,以避免可能出现在 View 中的其他对象(手、台球杆等)。也看看 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 开始:最初使用最简单且计算成本最低的设置,然后在进入更复杂的算法之前先看看结果有多稳健(这将需要理解并获得正确的参数以获得预期结果)
关于opencv - 检测台球 table 上的球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40717587/