c - 改善CocaCola形状识别 算法

  显示原文与译文双语对照的内容

在过去的几年里,我一直在做的一个最有趣的项目,因为我仍然是一个学生,是一个关于图像处理的最终项目。 我们的目标是研发一个系统,以便能够识别可口可乐 ( 注意,我强调了这个词,你会明白为什么) 。 你可以看到下面的一个示例,它可以在绿色矩形中识别比例和旋转。

Template matching

项目的一些约束条件:

  • 背景可能非常嘈杂。
  • 可以有任意比例或者旋转或者方向( 在合理的限制范围内)
  • 图像可能有某种程度的fuziness ( 轮廓可能不是直线)
  • 图像中可能有可口可乐瓶子,该算法只能检测到 !
  • 图像的亮度可能会变化很多( 所以你不能依靠"太多"颜色检测 on 。
  • 可以部分隐藏在侧面或者中间( 可能部分隐藏在瓶子的后面) !
  • 图像中根本没有罐子,在这种情况下你必须找东西,然后写一条留言。

这样你就可以得到像这样的( 在这种情况下,我的算法完全失败了):

Total fail

现在我已经做这个项目很明显,因为它比较前一段时间,有很多的乐趣的访问时间以及我所提供的正统的实现。 下面是关于我的实现的一些细节:

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

Pre-processing: 关于图像 Pre-processing,我意味着如何以更原始的形式转换它给算法。 我使用了 2种方法:

  1. 从RGB到 HSV ( 色调饱和度值 ) 和变色域滤波基于"红色"色调,饱和度超过一定阈值以避免orange-like颜色和过滤产生的音色较低的值,以避免。 最终结果是一个黑白黑白图像,其中所有白色像素都代表匹配这里阈值的像素。 显然,图像中仍然有很多垃圾,但这减少了你必须使用的维度数量。 Binarized image
  2. 使用中值滤波( 取所有邻居的中值像素值并用该值替换像素) 滤除噪声的噪声滤波。
  3. 使用 Canny边缘检测过滤器获取 2个引用步骤后所有项的轮廓。 Contour detection

算法: 我为此任务选择的算法本身取自这个( awesome ) book的特征提取,名为广义Hough变换( 和普通的霍夫变换完全不同) 。 它基本上说了一些事情:

  • 你可以在不了解它的解析方程( 这里是什么情况)的情况下,在空间中描述对象。
  • 像缩放和旋转这样的图像变形是经得起的,因为它将根据比例因子和旋转因子的每个组合来测试图像。
  • 它使用一个基本模型( 模板),算法将"学习"。
  • 轮廓图像中剩下的每个像素将为另一个像素投票,这将是你的对象的中心( 就重力而言),基于它从模型中学到的。

最后,你会得到一个投票的热点图,比如这里的所有像素都会投票为重心投票,所以你会在对应的像素中投票,在热映射中看到一个峰值。

GHT

只要你用了,一个简单的threshold-based演算法可以给你尺度和旋转中心点的位置,像素,可以从这些类派生,然后在它的周围( 最终比例和旋转因子显然与原始模板相对应) plot 你的小矩形。 理论上至少。。

结果: 现在,虽然这种方法在基本情况下工作,但在某些方面却严重不足:

  • 它的太慢了 ! 我还没有足够的压力。 处理 30测试图像需要整整一整天的时间,因为我有一个非常高的旋转和平移比例因子,因为有些罐子很小。
  • 这是完全失去了瓶在图像时,由于某种原因几乎总是发现瓶子而不是可以(也许是因为瓶子更大,因此有更多的像素,从而更多的选票)
  • 模糊的图像也不好,因为投票结果是以像素为中心的随机位置,因此以非常嘈杂的热映射结束。
  • 实现了平移和旋转的不变性,但不在方向上,这意味着不能直接面对摄像机目标。

你能帮我提高我的特定算法,完全使用 opencv的特性,解决四个具体mentionned问题?

我希望一些人也会从中学习一些东西,毕竟我不仅认为那些提问的人应该学习:)

时间:

另一种方法是使用 scale-invariant特性转换 ( 筛选) 或者来提取特性( keypoints ) 或者加速了( 冲浪) 。

它是在 OpenCV 2.3.1中实现的。

你可以找到一个很好的代码示例,使用 Features2D + 单例中的特性来查找一个已知的对象

两个算法都不适应缩放和旋转。 因为它们处理特性,你还可以处理遮挡 ( 只要有足够的keypoints可见) 。

Enter image description here

图像源:教程示例

处理需要几百毫秒的SIFT,冲浪速度稍微快一些,但不适用于实时应用。 ORB使用了相对于旋转不变性较弱的速度。

原始文件

可口可乐为了加快检测速度,我将能够利用这一事实,你不是想求到任意的图像/对象,具体而言是一。 这是非常重要的,因为这个 logo 非常独特,它应该有一个特性,scale-invariant签名在频域,特别是在红色的通道。 在水平扫描线( 在水平对齐的logo 上训练) red-to-white-to-red面临一变化特点,也就是说,将产生截然不同的"节奏"logo 。作为它通过中心轴, 这种节奏将在不同的比例和方向上"加速"或者"减速",但将保持比例相等。 在一个星爆pattern,你能辨认出/定义几十个这样扫描线模式,水平或者垂直皆通过对角,. logo 和几个更多 调用这些"签名扫描行"。"

Signature scan line

在目标图像中搜索这里签名是一个简单的扫描水平条带图像的问题。 寻找中的high-frequency red-channel ( 指示从红色区域移动到白色区域),而一旦找到,看看它后面是其中一个频率节奏中标识用户培训。 找到匹配后,你将立即知道scan-line和 logo ( 如果你在训练中跟踪那些东西) 中的位置的方向,因此识别 logo的边界是微不足道的。

如果这不是linearly-efficient算法,我很惊讶。 它显然不满足你的can-bottle识别,但至少你会有你的徽标。

他会在瓶子( 更新,对于识别我焦炭( 褐色液体) 紧邻 logo --即 瓶子内部。 或者,在一个空瓶子,会寻找章总是会有相同的基本形状、大小和距离 logo,通常将所有白色或红色。 搜索一个纯色eliptical形状帽子应该的,相对于 logo 。 当然不简单,但你的目标应该是寻找容易 快。)

( 自从我的图像处理几天以来已经过了几年,所以我将这个建议保持在高层次和概念上) 。 我认为它可能有点近似人类的眼睛如何操作--或者至少我的大脑如何)!

有趣的问题:当我看到你的瓶子图像时,我觉得它是一个可以的。 但是,作为一个人,我所做的区别在于,我发现它也是一个瓶子。

所以,要区分罐子和瓶子,先扫描瓶子? 如果你找到了一个,在寻找罐子之前屏蔽标签。

如果你已经在做罐头,就不难实现。 真正的缺点是它加倍了你的处理时间。 ( 但是考虑到现实世界的应用,你最终会想要做瓶子;)

即使是人类在第二个图像( 提供透明的瓶子透明区域) 中辨别瓶子和罐子也不困难?

它们几乎是一样的,除了一个很小的区域( 也就是说,罐子顶部的宽度有点小,瓶子的包装宽度是一样的,但change的变化很小) 。

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

第二个我想的是瓶子的透明度。 OpenCV在图像中找到透明对象的一些工作。 检查下面的链接。

特别要看一下,看看它们检测玻璃的准确程度:

查看他们的implmentation结果:

Enter image description here

他们说这是纸的实现 "A Geodesic Active Contour Framework for Finding Glass" by K. McHenry and J. Ponce, CVPR 2006.( 下载纸张) web

这可能对你的案例有帮助,但如果瓶子被填满,问题会再次出现。

所以我想这里,你可以先搜索瓶子的透明体,或者是一个红色的区域,连接到两个透明的物体上,这显然是瓶子。 ( 理想情况下,图像如下所示。)

Enter image description here

现在你可以删除黄色区域,即瓶子的标签,并运行你的算法来查找。

无论如何,这个解决方案也有不同的问题,比如其他解决方案。

  1. 只有当你的瓶子是空的才管用。 在这种情况下,你必须在两个黑色的( 如果可口可乐液体是黑色的) 之间搜索红色区域。
  2. 如果透明部件被覆盖则另一个问题。

但是,如果图片中没有上述问题,这似乎是一种更好的方式。

在形状, 期待

看看罐子的红色部分的形状。 注意,瓶子的顶部可以略微变细,瓶子的标签是直的。 你可以通过比较红色部分的宽度来区分它们。

在高光, 期待

区别瓶子和罐子的一种方法是。 瓶子是用塑料制成的,而可以用铝制成。 在充分的well-lit场景中,查看镜面反射是一种告诉瓶子标签的方法。

就我所知,人类是如何区分两种标签之间的差异的。 如果光线条件较差,那么在分辨这两者时肯定会有一些不确定因素。 在这种情况下,你必须能够检测透明/半透明瓶子本身的存在。

我非常喜欢 Darren的烹调和回答堆栈编辑器的问题。 我正在把我的想法放到一个评论中,但我相信我的方法太 answer-shaped,不能离开这里。

简而言之,你已经确定了一个判定可口可乐 logo 在空间特定位置的算法。 在其他对象,非独占of,你现在正试图确定,对于任意取向和任意尺度因子,利用启发式适用于区分可口可乐罐 : 有了这个标志性瓶,广告牌,广告,或者可口可乐用具所有 associated. 你没有在你的问题语句中调用这些附加案例,但是我觉得它们对你的算法的成功至关重要。

这里的秘密是判定当前的视觉特征一个 包含或者,通过负空间,哪些特性是可以为其他焦炭产品的已经不存在的罐。 为此目的,当前最顶的回答草图描述了一个基本的方法用于选择"可以"当且仅当未标识"瓶子",或者通过一个瓶盖,液体的存在,或者其他类似的视觉试探法。

问题是这个问题。 一个瓶子可以是空的,而且没有盖子,导致了一个假的正。 或者,它可以被一个部分瓶带附加功能的改变后,进而产生再次误检。 不用说,这不优雅,也不适合我们的目的。

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

  • 你的问题中,correct,对象的形状的轮廓,作为你是否能勾勒出来? 如果是,+1.
  • 如果我们假设存在自然或者人造光,我们会检测到瓶子的Chrome 轮廓,这表示它是由铝制成的? 如果是,+1.
  • 我们是否确定的高光属性对象是正确的,相对于我们的光源( 演示视频链接光源检测)? 如果是,+1.
  • 我们可以确定任何其他对象的属性,这些属性将它的识别为 logo,但不限于的拓扑图像倾斜,对象的方向,对象( 例如在一个平面表面或者其他容器的上下文中)的并列,以及拉标签的存在? 如果是,对于每一个 +1.

你的分类可能如下所示:

  • 对于每个候选匹配,如果检测到可口可乐 logo的存在,请绘制灰色边框。
  • 对于 +2上的每个匹配项,绘制一个红色边框。

已经检测到这个鲜明的视觉形象给用户什么,重点在于弱阳性可能,正确,被探测为改变后的罐头。

每个属性的检测都有一个非常不同的时间和空间复杂度,对于每种方法,快速通过 http://dsp.stackexchange.com 比确定最正确和最高效的算法更合理。 这里我的意图是,纯粹和简单,以强调检测如果一个东西是可以通过使一个小型部分的候选检测不进行空间最可靠的失效或者有效解决这里问题,并相应地在理想情况下,你应该采取适当的行动。

嘿,恭喜的黑客新闻发布 ! 的,这是一个非常值得注意的问题,值得关注。 : )

请查看 Zdenek 的kalal捕食者跟踪程序。 它需要一些训练,但它可以主动学习跟踪的对象如何看待不同的方向和比例,并实时进行 !

源代码在他的网站上可用。 它在 MATLAB 中,但是可能有一个社区成员已经完成了一个Java实现。 中我成功的re-implemented跟踪器tld.的一部分 如果我记错了,TLD会使用蕨类植物作为关键点检测器。 我使用可以冲浪或者筛选替代( 已经暗示了 @stacker) 以重新获取该对象如果是丢失你的追踪器 随时间的反馈跟踪器使得我们很容易构建了动态的过筛 List/冲浪的模板与时间启用reacquiring该对象,具有很高的精度。

如果你对我的跟踪器的C# 实现感兴趣,请随时询问。

享受=D !

如果你不仅仅局限于一个不在你的限制中的摄像机,也许你可以移动一个像 Xbox Kinect的范围感应器。 使用这里选项,你可以根据图像的匹配分割进行深度和颜色。 这样可以加快图像中对象的分离。 然后,你可以使用匹配的或者类似的技术,甚至匹配形状的形状,而不是仅仅是它的轮廓或者颜色,如果你有一个目标,那么它是任何方向的一个有效选项。 这些技术通常非常快速,特别是当你用来解决你的速度问题时。

我也可以建议,不是为了准确或者速度,而是为了好玩,你可以在你的色调分割图像上使用一个训练的神经网络来识别can的形状。 这些速度非常快,通常最多可以达到 80/90% 。 训练将是一个漫长的过程,尽管你必须手动识别每个图像中的。

这是一个有趣的问题,它的深度和帅气,很好 !

这可能是一个非常幼稚的想法( 或者根本不能工作),但是所有的焦炭罐的尺寸都是固定的。 如果相同的图像同时包含一个罐子和一个瓶子,那么你可以根据大小来区分它们,( 瓶子会更大) 。 由于缺少深度( 例如 。 3 D 映射到 2个映射( 可能会出现瓶颈),并且没有大小差异。 你可以使用 stereo-imaging 恢复某些深度信息,然后恢复原始大小。

我会检测红色矩形: RGB -> HSV,滤镜红色-> 二进制图像,关闭,在matlab中被称为 imclose

然后从最大到最小查看矩形。 在已知位置/比例中具有较小矩形的矩形可以同时删除( 假设瓶子的比例是恒定的,那么小的矩形就是一个瓶盖) 。

这将留下红色矩形,然后你需要以某种方式检测这些标志,以判断它们是红色矩形还是焦炭。 像 OCR,但有一个已知的logo?

...