【问题标题】:Detecting balls on a pool table (stripes and solids)检测台球桌上的球(条纹和固体)
【发布时间】:2018-08-10 19:23:58
【问题描述】:

我找不到关于该主题的任何令人满意的答案。我想制作一个程序,从台球桌上方的相机获取快照并检测球。我正在使用 OpenCV 和 Java。我现在的算法基本上是:

模糊图像 -> 将 RGB 转换为 HSV -> 分成 3 个平面 -> 在 H 平面上使用 Canny() -> 使用 HoughCircles() 方法检测球

这个算法很好地检测球,它只对两个球有问题(绿色和蓝色,因为桌子的背景是绿色的)。但我想更进一步:

  • 检测球是属于条纹还是固体
  • 为每个球设置一个 ID,例如条纹为 1-7,实心为 8-14,每个球都有唯一的 ID,在比赛期间不会更改

您知道如何实施任务 #1 吗?我的想法是使用 inRange() 函数,但是我必须为每个球准备一个掩码,以检测指定颜色范围内的一个球,并对每个球进行此检测,对吗?感谢您分享您的意见。

@Edit:这里我给你一些我的算法如何工作的示例。我更改了一些参数,因为我想检测所有内容,现在效果更差了,但它仍然可以非常准确地工作。我会给你三个来自相机的原始图像样本,我检测到球的图像(未失真,带有一些过滤器)和检测到球的图像。

【问题讨论】:

  • 尝试发布示例图片供用户测试他们的假设。即使是绿色的球也与绿色的桌子背景颜色不同。
  • 我可以看到检测固体,但条纹会很困难。我认为最好的办法是让另一台相机参与进来并开始进行比较和交叉检查。

标签: java opencv


【解决方案1】:

推荐:

如果您可以屏蔽与球对应的像素,则以下方法应该可以根据相关像素区分条纹/实心球:

  1. 去饱和球像素并在一定亮度p阈值
  2. 统计球区内的白色像素数和总像素数。
  3. 计数阈值:如果白色像素的比例大于某个阈值q,则将其归类为条纹球。否则,它就是一个实心球。

(这个想法是条纹是白色的,并且总是至少部分可见,因此条纹球将具有更高比例的白色像素)。


样本测试:

这是一个示例(手动,使用p = 0.7)应用于unrectified 图像中的一些球,右侧有最后的 % 白色像素。

看起来q = 0.1 的分类阈值(至少 10% 的白色像素是条纹球)可以区分这两组,尽管根据更多数据调整阈值是理想的。

如果您在使用此方法时遇到了阴影球的问题,您还可以尝试在阈值化之前重新调整每个球的亮度(使亮度跨越 0、1 的整个范围),这样可以减少该方法对绝对亮度的依赖.

【讨论】:

  • 我将在下周尝试这个并对该主题进行一些更新。如果其他人对设置球 ID 或某事有一些想法,请随时分享。
  • 对于球 ID,您可能只需找到每个球像素的主要色调(转换为 HSV,取色调值的饱和加权平均值),然后按色调值对球进行排序获得规范的顺序(因为无论照明如何,相对色调都应该是相同的顺序)。不过,您需要白色/黑色球的特殊情况。更强大的选择是使用直方图交集 (mpatacchiola.github.io/blog/2016/11/12/…),或者只计算直方图特征向量并训练 SVM。
  • 哦!我的意思是使用threshold (docs.opencv.org/3.4/javadoc/org/opencv/imgproc/…) 和p 作为阈值。我认为您可以使用直方图 (opencv-java-tutorials.readthedocs.io/en/latest/…) 将掩码参数设置为圆的像素,然后使用顶部 bin 作为白色像素的数量,底部 bin 作为黑色像素。
  • 我发布的图片使用了 Lightness(与您的评论相同)。对于黄色/紫色球,您可以尝试在阈值化之前重新缩放/标准化亮度,或者(等效地,我认为?)使阈值自适应(即 threshold = k + (1-k) * (average lightness of ball) 用于 [0,1] 中的某些 k)。在最坏的情况下,您可以首先进行主色调计算,然后制作一个查找表来映射色调范围 -> 阈值(因此,黄色阈值较高,紫色阈值较低)。
  • 我的意思是我想使用白色像素的数量来区分白球和黑球。我认为白球的白色像素最多,黑球最少。没有更多的问题,我会用你提到的方法来处理它。谢谢你的帮助,干杯!
猜你喜欢
  • 2017-04-04
  • 1970-01-01
  • 2013-10-21
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多