图像处理:“可口可乐”识别的算法改进
c++
image-processing
opencv
5
0

我过去几年中最有趣的项目之一是关于图像处理的项目。目的是开发一个能够识别可口可乐“罐头”的系统 (请注意,我在强调“罐头”一词,您将在稍后看到原因)。您可以在下面看到一个示例,该示例在带有刻度和旋转的绿色矩形中可以识别。

模板匹配

对项目的一些限制:

  • 背景可能非常嘈杂。
  • 可以有任何比例旋转或什至取向(在合理范围内)。
  • 图像可能有一定程度的模糊性(轮廓可能不完全笔直)。
  • 图像中可能有可口可乐瓶,该算法只能检测到罐头
  • 图像的亮度可能相差很大(因此您不能过多地依赖颜色检测)。
  • 可以部分地隐藏在两侧或中间,可能部分地隐藏了一瓶后面。
  • 有可能是在所有的图像中没有就可以了 ,在这种情况下,你必须找到什么,写一条消息这样说。

因此,您可能会遇到诸如此类的棘手事情(在这种情况下,我的算法完全失败了):

总失败

我前一段时间做了这个项目,并且做得很有趣,并且实现得很好。以下是有关我的实现的一些详细信息:

语言 :使用OpenCV库在C ++中完成。

预处理 :对于图像预处理,即将图像转换为更原始的形式以提供给算法,我使用了2种方法:

  1. 将颜色域从RGB更改为HSV,并基于“红色”色调进行过滤,饱和度高于特定阈值以避免产生类似橙色的颜色,而对低值进行过滤以避免产生深色。最终结果是一个二进制的黑白图像,其中所有白色像素将代表与该阈值匹配的像素。显然,图像中仍然有很多废话,但这减少了必须处理的尺寸数。 二值化图像
  2. 使用中值滤波进行噪声滤波(获取所有邻居的中值像素值,然后用该值替换像素)以减少噪声。
  3. 经过2个先验步骤后,使用Canny Edge Detection滤镜获取所有项目的轮廓。 轮廓检测

算法 :我为此任务选择的算法本身取自于这本很棒的书中有关特征提取的书,并称为通用霍夫变换 (与常规霍夫变换完全不同)。它基本上说了几件事:

  • 您可以在不知道其解析方程的情况下描述空间物体(此处就是这种情况)。
  • 它可以抵抗诸如缩放和旋转之类的图像变形,因为它将基本上测试图像的缩放因子和旋转因子的每种组合。
  • 它使用算法将“学习”的基本模型(模板)。
  • 轮廓图像中剩余的每个像素将投票给另一个像素,该像素根据其从模型中学到的内容,应该是对象的中心(就重力而言)。

最后,您将获得投票的热图,例如,此处罐头轮廓的所有像素都将为其重力中心投票,因此在与像素相对应的同一像素中将有很多投票居中,并会在热图中看到一个峰值,如下所示:

GHT

有了这些功能后,您就可以使用简单的基于阈值的启发式方法来确定中心像素的位置,从中可以得出比例尺和旋转角度,然后在其周围绘制一个小矩形(最终比例尺和旋转系数显然相对于您的原始模板)。理论上至少...

结果 :现在,尽管此方法在基本情况下可行,但在某些领域却严重缺乏:

  • 太慢了 !我的压力还不够。处理这30张测试图像几乎需要整整一天的时间,这显然是因为我对旋转和平移具有非常高的缩放系数,因为某些罐非常小。
  • 当瓶子出现在图像中时,它完全丢失了,并且出于某种原因几乎总是找到瓶子而不是罐子(也许是因为瓶子更大,所以像素更多,因此票数更多)
  • 模糊图像也不是很好,因为投票最终以像素为中心围绕中心的随机位置,从而以非常嘈杂的热图结束。
  • 实现了平移和旋转的不变性,但没有实现定向,这意味着未识别未直接面对相机物镜的罐子。

您能否使用专有的OpenCV功能帮助我改善特定算法,以解决上述四个特定问题?

我希望有些人也能从中学到一些东西,毕竟我认为不仅提出问题的人也应该学习。 :)

参考资料:
Stack Overflow
收藏
评论
共 10 个回答
高赞 时间 活跃

为了加快处理速度,我会利用这样一个事实,即不要求您查找任意图像/对象,而是要查找带有可口可乐徽标的对象。这很重要,因为该徽标非常有特色,并且在频域中,尤其是在RGB的红色通道中,应具有特征性的,比例不变的签名。也就是说,水平扫描线(在水平对齐的徽标上训练)遇到的红色到白色到红色的交替图案在穿过徽标的中心轴时将具有独特的“节奏”。该节奏将以不同的比例和方向“加速”或“减速”,但将保持成比例的相等。您可以通过爆炸形图案在徽标的水平和垂直方向识别和定义数十条这样的扫描线,在对角线上也可以识别/定义更多条。称这些为“签名扫描线”。

签名扫描线

在目标图像中搜索此签名很简单,只需扫描水平条中的图像即可。在红色通道中寻找一个高频(指示从红色区域移到白色区域),一旦找到,请查看它是否跟随训练中确定的频率节律之一。一旦找到匹配项,您将立即知道扫描线在徽标中的方向和位置(如果您在培训期间跟踪这些内容),因此从那里识别徽标的边界很简单。

如果这不是线性高效算法,或者几乎不是线性高效算法,我会感到惊讶。它显然不能解决您的水壶歧视问题,但至少您会拥有徽标。

(更新:对瓶承认我会找焦(棕色液体)相邻的标志-那就是, 瓶内或者说,在一个空瓶子的情况下,我会找一个上限 ,这将始终有基本形状,大小和与徽标的距离相同,通常为白色或红色。搜索相对于徽标应有帽子的纯色椭圆形。当然,这并非万无一失,但您的目标是快速找到简单的对象。)

(距离我的图像处理工作已经过去了几年,所以我将建议从总体上讲是概念性的。我认为这可能与人眼的操作方式略有相似,或者至少是我的大脑的操作方式!)

收藏
评论

我会检测到红色矩形:RGB-> HSV,过滤红色->二进制图像, 关闭 (先膨胀然后腐蚀,在matlab中称为imclose

然后从最大到最小浏览矩形。可以删除在已知位置/比例下具有较小矩形的矩形(假定瓶比例是恒定的,较小的矩形将是瓶盖)。

这会使您留下红色矩形,然后您需要以某种方式检测徽标以判断它们是红色矩形还是可乐罐。类似于OCR,但带有已知徽标?

收藏
评论

我真的很喜欢Darren Cook堆垛机对这个问题的回答 。我当时正对这些想法发表评论,但我相信我的方法太过具有答案性,无法离开这里。

简而言之,您已经确定了一种算法,该算法可确定在空间的特定位置是否存在可口可乐徽标。您现在正在尝试针对任意方向和任意缩放比例确定一种启发式方法,以区分可口可乐与其他对象,包括:与该标志性徽标相关联的瓶子广告牌广告可口可乐用具 。您没有在问题陈述中提到很多其他情况,但我认为它们对于算法的成功至关重要。

这里的秘诀之一就是确定视觉特征一罐含有,或者通过负空间,特点是本作中不存在对罐外焦产品是什么。为此, 当前的最高答案勾勒出了一种基本方法,即当且仅当通过瓶盖,液体或其他类似的视觉启发法未识别出“瓶”时,才选择“罐”。

问题是这崩溃了。例如,瓶子可能是空的,并且没有瓶盖,导致误报。或者,它可能是带有其他特征的不完整瓶子 ,从而再次导致错误检测。不用说,这不是很优雅,也不符合我们的目的。

为此,罐的最正确选择标准如下:

  • 正如您在问题中所概述的那样,对象轮廓的形状是否正确?如果是这样,请+1。
  • 如果我们假设存在自然光或人造光,是否会在瓶子上检测到铬轮廓,以表明其是否由铝制成?如果是这样,请+1。
  • 我们是否确定相对于我们的光源,物体的镜面特性是正确的(关于光源检测的 说明性视频链接 )?如果是这样,请+1。
  • 我们是否可以确定关于对象的任何其他属性,将其标识为罐,包括但不限于徽标的拓扑图像歪斜,对象的方向,对象的并置(例如,在平面上)例如桌子或其他罐头),以及是否有拉片?如果是这样,则每个+1。

然后,您的分类可能如下所示:

  • 对于每个候选匹配项,如果检测到存在可口可乐徽标,则绘制灰色边框。
  • 对于每次+2的比赛,请绘制红色边框。

这在视觉上向用户突出显示了检测到的内容,强调了可以正确检测为扭曲罐的弱阳性。

对每个属性的检测会带来非常不同的时间和空间复杂度,对于每种方法,快速通过http://dsp.stackexchange.com来确定最正确,最有效的算法是合理的。我的意图是纯粹地和简单地强调, 通过使候选检测空间的一小部分无效检测某物是否是罐子,并不是解决此问题的最有效或最有效的解决方案,理想情况下,您应该采取适当的措施相应地。

嘿,恭喜《黑客新闻》发布!总体而言,这是一个非常棒的问题,值得其宣传。 :)

收藏
评论

另一种方法是使用尺度不变特征变换 (SIFT)或加速鲁棒特征 (SURF)提取特征(关键点)。

它在OpenCV 2.3.1中实现。

您可以使用Feature2D + Homography中的功能找到一个不错的代码示例, 以查找已知对象

两种算法对于缩放和旋转都是不变的。由于它们可以使用功能,因此您也可以处理遮挡 (只要可见足够的关键点)。

在此处输入图片说明

图片来源:教程示例

SIFT的处理过程需要几百毫秒,SURF速度更快,但是不适用于实时应用。 ORB使用的FAST在旋转不变性方面较弱。

原始论文

收藏
评论

请查看Zdenek Kalal的“ 捕食者”追踪器 。它需要一些培训,但是它可以主动学习被跟踪对象如何看待不同方向和比例并实时进行操作!

源代码可在他的网站上找到。它在MATLAB中 ,但是社区成员可能已经完成了Java实现。我已经成功地在C#中重新实现了TLD的跟踪器部分。如果我没记错的话,TLD正在使用蕨类作为关键点检测器。我使用SURF或SIFT代替(@stacker已经建议)以重新获取对象,如果该对象被跟踪器丢失了。跟踪器的反馈使您可以轻松地随时间构建动态的筛选/冲浪模板列表,这些列表可以随着时间的流逝以很高的精度重新捕获对象。

如果您对我的C#跟踪器实现感兴趣,请随时提出。

收藏
评论

如果您不仅仅局限于一个不受限制的相机,也许您可以转向使用Xbox Kinect等距离传感器。使用此功能,您可以对图像进行基于深度和颜色的匹配分割。这样可以更快地分离图像中的对象。然后,您可以使用ICP匹配或类似的技术来匹配罐的形状,而不是仅匹配罐的轮廓或颜色,并且鉴于罐是圆柱形的,如果您以前对目标进行了3D扫描,那么这对于任何方向都是有效的选择。这些技术通常很快,特别是在用于解决速度问题的特定目的时。

我也可以建议,不一定出于准确性或速度的考虑,而是为了娱乐,您可以在色相分割的图像上使用经过训练的神经网络来识别罐子的形状。这些速度非常快,通常可以达到80/90%的准确度。培训将是一个漫长的过程,尽管您必须手动识别每个图像中的罐头。

收藏
评论

嗯,实际上,我认为我正在做某事 (这是有史以来最有趣的问题-因此,即使找到了可接受的答案,也不能继续尝试找到“完美”的答案是可耻的)。 。

一旦找到徽标,麻烦就解决了一半。然后你只需要搞清楚什么之间的标识周围的差异。另外,我们想做的越少越好。我认为这实际上是这容易的部分...

什么周围的标志?对于罐子,我们可以看到金属,尽管受到照明的影响,金属的基本颜色也不会改变。只要知道标签的角度,我们就可以知道标签正上方的角度,因此我们正在研究它们之间的区别:

在此,徽标上方和下方的内容完全是深色的,颜色一致。在这方面相对容易。

在这里,上方和下方是浅色,但颜色仍然一致。它是全银的,实际上,全银的金属以及银色通常都很少见。此外,它的外壳较细,滑行距离已经确定的红色足够近,因此您可以在其整个长度上追踪其形状,以计算出可以视为罐中金属环的百分比。确实,您只需要在罐子上的任何一小部分就可以知道它是罐子的一部分,但是您仍然需要找到一个平衡点,以确保它不仅仅是一个空瓶,里面没有金属。

最后,棘手的一个。但是并不是那么棘手,一旦我们只按照我们在红色包装上方(和下方)可以看到的内容进行操作。它是透明的,这意味着它将显示其背后的内容。很好,因为它后面的东西不可能像罐子里的银色圆形金属那样颜色一致。背后可能有很多不同的东西,这告诉我们它是一个空的(或充满透明液体的)瓶子,或者颜色一致,这可能意味着它充满了液体,或者瓶子只是在一个瓶子的前面纯色。我们正在使用最接近顶部和底部的颜色,并且正确的颜色出现在正确的位置的可能性相对较小。我们知道它是一个瓶子,因为它没有罐子的关键视觉元素,与瓶子后面的东西相比,它相对简单。

(最后一个是我能找到的最大的空可口可乐瓶最好的-有趣的是瓶盖和戒指是黄色的,表明瓶盖的红色可能不应该依赖)

在罕见的情况下,即使在塑料被提取后,瓶子后面仍然有相似的银色阴影,或者瓶子以某种方式填充了相同的银色液体阴影,我们可以回过头来大致估算出银的形状-如我所提到的,是圆形的,并且遵循罐的形状。但是,即使我在图像处理方面缺乏某些知识,听起来也很慢。更好的是,为什么不通过一次检查徽标的侧面以确保那里没有相同的银色来推断这一点呢?啊,但是如果罐子后面有同样的银色阴影怎么办?然后,我们确实确实必须更加注意形状,再次查看罐的顶部和底部。

取决于所有这些工具的完美程度,它可能会很慢,但是我想我的基本概念是首先检查最简单和最接近的事情。在努力确定其他元素的形状之前,先在已经匹配的形状(无论如何这似乎是最琐碎的部分)周围进行色差检查。要列出它,它去了:

  • 找到主要的吸引力(红色徽标背景,可能还有徽标本身的方向,尽管如果罐头掉了,则您需要专注于红色)
  • 验证形状和方向,再次通过非常独特的红色进行验证
  • 检查形状周围的颜色(因为它既快速又无痛)
  • 最后,如果需要,请验证主要吸引力周围的这些颜色的形状,以确保正确的圆度。

如果您无法做到这一点,则可能意味着罐子的顶部和底部被盖住了,而人类用来可靠地区分罐子和瓶子的唯一可能的方法就是闭塞和反射的就可以了,这将是一个更难的战斗过程。但是,要走得更远,您可以使用其他答案中提到的半透明扫描技术,按照罐子/瓶子的角度检查更多类似瓶子的特征。

有趣的其他噩梦可能包括一个可以方便地坐在瓶子后面的罐子,其距离恰好使它的金属恰好显示在标签的上方和下方,只要您沿红色的整个长度进行扫描,它仍然会失效。标签-实际上更多的是问题,因为您没有在可能的位置检测到罐子,而不是考虑实际上是在检测瓶子,包括偶然发现的罐子。在这种情况下,玻璃杯是空的!


作为免责声明,我对此问题没有经验,也从未考虑过图像处理,但是它很有趣,使我对它进行了深入的思考,在阅读了所有其他答案之后,我认为这可能是最简单最有效的方法来完成它。就我个人而言,我很高兴我实际上不必考虑对此编程!

编辑

MS油漆罐中的不良绘图此外,请看一下我在MS Paint中所做的这张图……这绝对是可怕的,而且还很不完整,但是仅根据形状和颜色,您就可以猜出它可能是什么样的。从本质上讲,这些是唯一需要扫描的内容。当您看到非常独特的形状和如此紧密的颜色组合时,还可能是什么?我没有画的白色背景应该被认为是“任何不一致的地方”。如果背景透明,则可以覆盖几乎所有其他图像,您仍然可以看到它。

收藏
评论

即使人类在第二个图像中区分瓶子和罐头也不难(前提是瓶子的透明区域被隐藏了)?

除了很小的区域外,它们几乎是相同的(也就是说,罐头顶部的宽度略小,而瓶子的包装纸的宽度在整个宽度上都是相同的,但是有小的变化吗?)

我想到的第一件事是检查瓶子的红顶。但是,如果瓶子没有顶部,或者部分隐藏(如上所述),仍然是一个问题。

我想到的第二件事是关于瓶子的透明度。 OpenCV在查找图像中的透明对象方面有一些工作。检查以下链接。

特别要看一下,以了解他们检测玻璃的准确性:

查看其执行结果:

在此处输入图片说明

他们说这是K. McHenry和J. Ponce在CVPR 2006上发表的“用于寻找玻璃的测地线主动轮廓框架”的实现。

这可能对您的情况有所帮助, 但是如果装满瓶子问题就会再次出现。

因此,我认为在这里,您可以首先搜索瓶子的透明主体,或者搜索横向连接到两个透明对象(显然是瓶子)的红色区域。 (理想工作时,图像如下)。

在此处输入图片说明

现在,您可以删除黄色区域,也就是瓶子的标签,然后运行算法以查找罐头。

无论如何,该解决方案也有其他解决方案中存在的其他问题。

  1. 仅在您的瓶子为空时才起作用。在这种情况下,您将必须搜索两种黑色之间的红色区域(如果可口可乐液体为黑色)。
  2. 如果覆盖了透明部分,则是另一个问题。

但是无论如何,如果图片中没有上述问题,那似乎是更好的方法。

收藏
评论

有趣的问题:当我瞥了一眼您的酒瓶图像时,我认为它也是一个罐头。但是,作为一个人类,我所做的与众不同之处在于我后来发现它也是一个瓶子……

因此,要区分罐头和瓶子,首先简单地扫描瓶子怎么样?如果找到一个,在寻找罐子之前先将标签遮盖。

如果您已经在做罐头,则实施起来并不难。真正的缺点是它将处理时间加倍。 (但是考虑到现实世界的应用程序,您最终还是想做瓶子;-)

收藏
评论

看形状

在罐子/瓶子红色部分的形状上a一口。请注意,在瓶子标签是笔直的情况下,罐子如何在顶部稍微变细。您可以通过比较红色部分的宽度和长度来区分这两个部分。

看重点

区分瓶子和罐头的一种方法是材料。瓶子是用塑料制成的,而罐子是用铝金属制成的。在光线充足的情况下,查看镜面反射性将是从罐头标签分辨瓶子标签的一种方法。

据我所知,这就是人类如何分辨两种标签之间的区别。如果照明条件较差,则无论如何将两者区分开肯定会有一些不确定性。在这种情况下,您将必须能够检测到透明/半透明瓶本身的存在。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号