协慌网

登录 贡献 社区

图像处理:“可口可乐罐” 识别的算法改进

在过去的几年里,我参与过的最有趣的项目之一是关于图像处理的项目。我们的目标是建立一个能够识别可口可乐“罐头” 的系统 (请注意,我正在强调 '罐头' 这个词,你会在一分钟内看到原因)。您可以在下面看到一个示例,其中可以使用缩放和旋转在绿色矩形中识别。

模板匹配

对项目的一些限制:

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

所以你最终可能会遇到这样棘手的事情(在这种情况下,我的算法完全失败):

总失败

我不久前做了这个项目,并且做了很多乐趣,我有一个不错的实现。以下是有关我的实施的一些细节:

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

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

  1. 将颜色域从 RGB 更改为HSV并基于 “红色” 色调进行过滤,饱和度高于某个阈值以避免橙色样色,并过滤低值以避免暗色调。最终结果是二进制黑白图像,其中所有白色像素将表示与该阈值匹配的像素。显然,图像中仍有很多废话,但这会减少您必须使用的维度数量。 二值化图像
  2. 使用中值滤波进行噪声滤波(取所有邻居的中值像素值并用该值替换像素)以减少噪声。
  3. 使用Canny 边缘检测过滤器在 2 个先前步骤之后获取所有项目的轮廓。 轮廓检测

算法 :我为这个任务选择的算法本身取自本关于特征提取的神奇书籍,称为广义霍夫变换 (与常规 Hough 变换有很大不同)。它基本上说了几件事:

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

最后,你得到了一张投票的热图,例如,这里所有罐子轮廓的像素都会投票给它的引力中心,所以你会在同一个像素对应的投票中得到很多票。中心,并将在热图中看到如下峰值:

GHT

一旦你有了这个,一个简单的基于阈值的启发式可以给你中心像素的位置,你可以从中获得比例和旋转,然后围绕它绘制你的小矩形(最终的比例和旋转因子显然将相对于你原始模板)。理论上至少......

结果 :现在,虽然这种方法在基本情况下起作用,但在某些方面却严重缺乏:

  • 非常慢 !我并没有强调这一点。处理 30 个测试图像需要将近一整天,显然是因为我有一个非常高的旋转和平移比例因子,因为一些罐子非常小。
  • 当瓶子出现在图像中时,它完全丢失了,并且由于某种原因,几乎总是发现瓶子而不是罐子(可能因为瓶子更大,因此有更多的像素,因此更多的选票)
  • 模糊图像也不好,因为投票在中心周围的随机位置以像素结束,因此以非常嘈杂的热图结束。
  • 实现了平移和旋转的方差,但没有取向,这意味着没有直接面对相机物镜的罐子被识别出来。

你能帮助我改进我的特定算法,只使用OpenCV功能来解决上面提到的四个具体问题吗?

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

答案

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

它在OpenCV 2.3.1 中实现。

您可以使用Features2D + Homography中的功能找到一个很好的代码示例来查找已知对象

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

在此输入图像描述

图片来源:教程示例

对于 SIFT,处理需要几百毫秒,SURF 的速度要快一些,但它不适合实时应用。 ORB 使用 FAST,其在旋转不变性方面较弱。

原始论文

为了加快速度,我会利用这样一个事实:你不会被要求找到任意图像 / 物体,特别是有可口可乐标志的物体。这很重要,因为这个标识非常独特,它应该在频域中具有特征性的,尺度不变的特征,特别是在 RGB 的红色通道中。也就是说,水平扫描线(在水平对齐的徽标上训练)遇到的红色到白色到红色的交替图案在通过徽标的中心轴时将具有独特的 “节奏”。这种节奏将在不同的尺度和方向上 “加速” 或 “减速”,但仍将按比例保持等效。您可以通过徽标识别 / 定义几十条这样的扫描线,水平和垂直两个扫描线以及几个对角线的星形图案。将这些称为 “签名扫描线”。

签名扫描线

在目标图像中搜索此签名是一个简单的问题,即以水平条带扫描图像。寻找红色通道中的高频(指示从红色区域移动到白色区域),并且一旦找到,查看它是否跟随训练期间识别的频率节奏之一。找到匹配后,您将立即知道扫描线在徽标中的方向和位置(如果您在训练期间跟踪这些内容),那么从那里识别徽标的边界是微不足道的。

如果这不是一个线性有效的算法,或者差不多如此,我会感到惊讶。它显然没有解决你的罐装歧视,但至少你会有你的标志。

(更新:气瓶承认我会找焦(棕色液体)相邻的标志 - 那就是, 瓶内或者说,在一个空瓶子的情况下,我会找一个上限 ,这将永远有。与徽标相同的基本形状,大小和距离通常都是白色或红色。搜索相对于徽标应该是盖子的纯色椭圆形状。当然不是万无一失,但你的目标应该是快速找到容易的。)

(距离我的图像处理时间已经过去了几年,所以我把这个建议保持在高水平和概念上。我认为它可能会略微接近人眼的操作方式 - 或者至少我的大脑是如何操作的!)

有趣的问题:当我浏览你的瓶子图像时,我认为它也是一个可以。但是,作为一个人,我所做的就是告诉它不同之处在于我注意到它也是一个瓶子......

那么,为了区分罐头和瓶子,如何简单地先扫描瓶子?如果找到一个,在寻找罐头之前屏蔽标签。

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