我过去几年中最有趣的项目之一是关于图像处理的项目。目的是开发一个能够识别可口可乐“罐头” 的系统 (请注意,我强调的是 “罐头” 一词,稍后您会看到原因)。您可以在下面看到一个示例,该示例在带有刻度和旋转的绿色矩形中可以识别。
对项目的一些限制:
因此,您可能会遇到诸如此类的棘手事情(在这种情况下,我的算法完全失败了):
我前一段时间做了这个项目,并且做得很有趣,并且实现得很好。以下是有关我的实现的一些详细信息:
语言 :使用OpenCV库在 C ++ 中完成。
预处理 :对于图像预处理,即将图像转换为更原始的形式以提供给算法,我使用了 2 种方法:
算法 :我为此任务选择的算法本身取自于这本很棒的书中有关特征提取的书,并称为通用霍夫变换 (与常规霍夫变换完全不同)。它基本上说了几件事:
最后,您将获得投票的热图,例如,此处罐轮廓的所有像素都将为其重力中心投票,因此在与像素相对应的同一像素中将有很多投票居中,并会在热图中看到一个峰值,如下所示:
有了这些功能后,您就可以使用简单的基于阈值的启发式方法来确定中心像素的位置,从中可以得出比例尺和旋转角度,然后在其周围绘制一个小矩形(最终比例尺和旋转系数显然相对于您的原始模板)。理论上至少...
结果 :现在,尽管此方法在基本情况下可行,但在某些领域却严重缺乏:
您能否使用专有的 OpenCV功能帮助我改善特定算法,以解决上述四个特定问题?
我希望有些人也能从中学到一些东西,毕竟我认为不仅提出问题的人也应该学习。 :)
为了加快处理速度,我会利用这样一个事实,即不要求您查找任意图像 / 对象,而是要查找带有可口可乐徽标的对象。这很重要,因为该徽标非常有特色,并且在频域中,尤其是在 RGB 的红色通道中,应具有特征性的,比例不变的签名。也就是说,水平扫描线(在水平对齐的徽标上训练)遇到的红色到白色到红色的交替图案在穿过徽标的中心轴时将具有独特的 “节奏”。该节奏将以不同的比例和方向 “加速” 或 “减速”,但将保持成比例的相等。您可以通过星标模式在徽标的水平和垂直方向以及对角线中识别或定义数十条这样的扫描线。称这些为 “签名扫描线”。
在目标图像中搜索此签名很简单,只需扫描水平条中的图像即可。在红色通道中寻找一个高频(指示从红色区域移到白色区域),一旦找到,请查看其是否跟随训练中确定的频率节律之一。一旦找到匹配项,您将立即知道扫描线在徽标中的方向和位置(如果您在训练期间跟踪这些内容),因此从那里识别徽标的边界很简单。
如果这不是线性高效算法,或者几乎不是线性高效算法,我会感到惊讶。它显然不能解决您的水壶歧视问题,但至少您会拥有徽标。
(更新:对瓶承认我会找焦(棕色液体)相邻的标志 - 那就是, 瓶内或者说,在一个空瓶子的情况下,我会找一个上限 ,这将始终有基本形状,大小和与徽标的距离相同,通常为白色或红色。搜索相对于徽标应有帽子的纯色椭圆形。当然,这并非万无一失,但您的目标是快速找到简单的对象。)
(距离我的图像处理工作已经过去了几年,所以我将建议从总体上讲是概念性的。我认为这可能与人眼的操作方式略有相似,或者至少是我的大脑的操作方式!)
有趣的问题:当我瞥了一眼您的酒瓶图像时,我认为它也是一个罐头。但是,作为一个人类,我所做的与众不同之处在于我后来发现它也是一个瓶子……
因此,要区分罐头和瓶子,首先简单地扫描瓶子怎么样?如果找到一个,在寻找罐子之前先将标签遮盖。
如果您已经在做罐头,则实施起来并不难。真正的缺点是它将处理时间加倍。 (但是考虑到现实世界的应用程序,您最终还是想做瓶子;-)
即使人类在第二个图像中区分瓶子和罐头也不难(前提是瓶子的透明区域被隐藏了)?
除了很小的区域外,它们几乎是相同的(也就是说,罐头顶部的宽度略小,而瓶子的包装纸的宽度在整个宽度上都是相同的,但是有小的变化吗?)
我想到的第一件事是检查瓶子的红顶。但是,如果瓶子没有顶部,或者部分隐藏(如上所述),仍然是一个问题。
我想到的第二件事是关于瓶子的透明度。 OpenCV 在查找图像中的透明对象方面有一些工作。检查以下链接。
特别要看一下,以了解他们检测玻璃的准确性:
查看其执行结果:
他们说这是K. McHenry 和 J. Ponce 在 CVPR 2006 上发表的“用于寻找玻璃的测地线主动轮廓框架”的实现。
这可能对您的情况有所帮助, 但是如果装满瓶子 , 问题就会再次出现。
因此,我认为在这里,您可以先搜索瓶子的透明主体,或者搜索横向连接到两个透明对象(显然是瓶子)的红色区域。 (理想工作时,图像如下)。
现在,您可以删除黄色区域,也就是瓶子的标签,然后运行算法以查找罐头。
无论如何,该解决方案也有其他解决方案中存在的其他问题。
但是无论如何,如果图片中没有上述问题,那似乎是更好的方法。
我真的很喜欢Darren Cook和堆垛机对这个问题的回答 。我当时正对这些想法发表评论,但我相信我的方法太过具有答案性,无法离开这里。
简而言之,您已经确定了一种算法,该算法可确定在空间的特定位置是否存在可口可乐徽标。您现在正在尝试针对任意方向和任意缩放比例确定一种启发式方法,以区分可口可乐罐与其他对象,包括:与该标志性徽标相关联的瓶子 , 广告牌 , 广告和可口可乐用具 。您没有在问题陈述中提到很多其他情况,但我认为它们对于算法的成功至关重要。
这里的秘诀之一就是确定视觉特征一罐含有,或者通过负空间,特点是本作中不存在对罐外焦产品是什么。为此, 当前的最高答案勾勒出了一种基本方法,即当且仅当通过瓶盖,液体或其他类似的视觉启发法未识别出 “瓶” 时,才选择 “罐”。
问题是这崩溃了。例如,瓶子可能是空的,并且没有瓶盖,导致误报。或者,它可能是带有其他特征的不完整瓶子 ,从而再次导致错误检测。不用说,这不是很优雅,也不符合我们的目的。
为此,罐的最正确选择标准如下:
然后,您的分类可能如下所示:
这在视觉上向用户突出显示了检测到的内容,强调了可以正确检测为扭曲罐的弱阳性。
对每个属性的检测具有非常不同的时间和空间复杂度,对于每种方法,快速通过http://dsp.stackexchange.com来确定最正确,最有效的算法是合理的。我的意图是纯粹地和简单地强调, 通过使候选检测空间的一小部分无效来检测某物是否是罐子,并不是解决此问题的最有效或最有效的解决方案,理想情况下,您应该采取适当的措施相应地。
嘿,恭喜《黑客新闻》发布!总体而言,这是一个非常棒的问题,值得其宣传。 :)
看形状
在罐子 / 瓶子红色部分的形状上 a 一口。请注意,在瓶子标签是笔直的情况下,罐子如何在顶部稍微变细。您可以通过比较红色部分的宽度和长度来区分这两个部分。
看重点
区分瓶子和罐头的一种方法是材料。瓶子是用塑料制成的,而罐子是用铝金属制成的。在光线充足的情况下,查看镜面反射性将是从罐头标签分辨瓶子标签的一种方法。
据我所知,这就是人类如何分辨两种标签之间的区别。如果照明条件较差,则无论如何将两者区分开肯定会有一些不确定性。在这种情况下,您将必须能够检测到透明 / 半透明瓶本身的存在。
请查看 Zdenek Kalal 的 “ 捕食者” 追踪器 。它需要一些培训,但是它可以主动学习被跟踪对象如何看待不同方向和比例并实时进行操作!
源代码可在他的网站上找到。它在MATLAB 中 ,但是社区成员可能已经完成了 Java 实现。我已经成功地在 C#中重新实现了 TLD 的跟踪器部分。如果我没记错的话,TLD 正在使用蕨类作为关键点检测器。我使用 SURF 或 SIFT 代替(@stacker 已经建议)以重新获取对象,如果该对象被跟踪器丢失了。跟踪器的反馈使您可以轻松地随时间构建动态的筛选 / 冲浪模板列表,这些列表可以随着时间的流逝以很高的精度重新捕获对象。
如果您对我的 C#跟踪器实现感兴趣,请随时提出。
如果您不仅仅局限于一个不受限制的相机,也许您可以转向使用 Xbox Kinect 之类的距离传感器。使用此功能,您可以对图像进行基于深度和颜色的匹配分割。这样可以更快地分离图像中的对象。然后,您可以使用 ICP 匹配或类似的技术来匹配罐的形状,而不是仅匹配罐的轮廓或颜色,并且鉴于罐是圆柱形的,如果您以前对目标进行了 3D 扫描,那么这对于任何方向都是有效的选择。这些技术通常很快,特别是在用于解决速度问题的特定目的时。
我也可以建议,不一定出于准确性或速度的考虑,而是为了娱乐,您可以在色相分割的图像上使用经过训练的神经网络来识别罐子的形状。这些速度非常快,通常可以达到 80/90%的准确度。培训将是一个漫长的过程,尽管您必须手动识别每个图像中的罐头。
我会检测到红色矩形:RGB-> HSV,过滤红色 -> 二进制图像, 关闭 (先膨胀然后腐蚀,在 matlab 中称为imclose
)
然后从最大到最小浏览矩形。可以删除在已知位置 / 比例下具有较小矩形的矩形(假定瓶比例是恒定的,较小的矩形将是瓶盖)。
这会使您留下红色矩形,然后您需要以某种方式检测徽标以判断它们是红色矩形还是可乐罐。类似于 OCR,但带有已知徽标?
这可能是一个非常幼稚的想法(或可能根本不起作用),但是所有可乐罐的尺寸都是固定的。因此,如果同一张图片中同时包含一个罐头和一个瓶子,那么您可以通过尺寸方面的区分来区分它们(瓶子会更大)。现在,由于缺少深度(即 3D 映射到 2D 映射),瓶子可能会缩水并且大小没有差异。您可以使用立体成像恢复一些深度信息,然后恢复原始大小。