【问题标题】:Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition图像处理:“可口可乐罐”识别的算法改进
【发布时间】:2012-04-27 11:05:06
【问题描述】:

过去几年我参与的最有趣的项目之一是关于image processing 的项目。目标是开发一个能够识别可口可乐'cans'的系统(注意我强调的是'cans'这个词,你马上就会明白为什么)。您可以在下面看到一个示例,在 绿色矩形 中识别出罐头,并带有缩放和旋转。

项目的一些限制:

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

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

我前段时间做过这个项目,做起来很有趣,而且我的实现也不错。以下是关于我的实现的一些细节:

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

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

  1. 将颜色域从 RGB 更改为HSV 并基于“红色”色调进行过滤,饱和度高于某个阈值以避免类似橙色的颜色,并过滤低值以避免暗色调。最终结果是二值黑白图像,其中所有白色像素都代表与此阈值匹配的像素。显然,图像中仍然有很多废话,但这减少了您必须处理的维度数量。
  2. 噪声过滤使用中值滤波(取所有邻居的中值像素值并以此值替换像素)来降低噪声。
  3. 使用Canny Edge Detection Filter 获取前两步后所有项目的轮廓。

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

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

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

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

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

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

您能帮我改进我的特定算法,使用OpenCV功能解决上述四个特定问题吗?

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

【问题讨论】:

  • 可能会说这个问题在 dsp.stackexchange.com 或 stats.stackexchange.com 上更合适,您当然也应该考虑在这些网站上重新提问。
  • 这里首先要分析为什么会发生不同的失败案例。例如,分离出瓶子获胜的地方、图像模糊的地方等示例,并执行一些统计分析以了解它们的 Hough 表示与您希望它检测到的表示之间的差异。一些了解替代方法的好地方是herehere
  • @stacker 提出了一个很好的观点。为了速度,您希望获得计算成本低廉的功能,例如定向梯度的直方图。一个非常幼稚的第一种方法是在一些训练图像中手动标记一堆罐头矩形,并使用这些加上随机负样本来训练 SVM 或决策树分类器。训练将花费更长的时间,但对新图像的执行会快得多。当我有更多空闲时间来包含正确的参考时,我计划编写此方法。
  • 类似reCAPTCHA的方法怎么样? ;)
  • 为什么从dsp.stackexchange.com 移出?似乎该站点比stackoverflow更适合o_O

标签: c++ algorithm image-processing opencv


【解决方案1】:

另一种方法是使用scale-invariant feature transform (SIFT) 或Speeded Up Robust Features (SURF) 提取特征(关键点)。

您可以在此页面上的 JavaC++Python 中找到一个不错的 OpenCV 代码示例:Features2D + Homography to find a known object

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

图片来源:教程示例

SIFT 的处理需要几百毫秒,SURF 稍微快一点,但不适合实时应用。 ORB 使用 FAST,在旋转不变性方面较弱。

原始论文

【讨论】:

  • 我同意@stacker - SIFT 是一个很好的选择。它对缩放和旋转操作非常强大。它对透视变形有些鲁棒(这可以按照 stacker 的建议进行改进:具有所需对象的不同透视图的模板数据库)。根据我的经验,它的致命弱点是强烈的光照变化和非常昂贵的计算。我不知道任何Java实现。我知道 OpenCV 实现,并使用了适合实时性能的 GPU c++/Windows (SiftGPU) 实现。
  • 警告说明:尽管我很喜欢 SIFT/SURF 以及他们对我所做的一切,但它们是受专利保护的。这可能是个问题,具体取决于包括地理位置 AFAIK 在内的多种条件。
  • 所以试试没有专利问题的 OpenCV 的 ORB 或 FREAK。 ORB 比 SIFT 快得多。 ORB 根据我的经验,它的规模和光线变化有点差,但你自己测试一下。
  • 你怎么能接受这个作为答案......没有一个特征描述符可以区分瓶子和罐头......他们都只是查看不变的局部模式描述符。我同意 SIFT、SURF、ORB、FREAK 等可以帮助您进行特征匹配,但是.. 问题的其他部分,例如遮挡、Bottle vs Can 等,我希望这不是一个完整的解决方案,如果您愿意的话谷歌搜索你的问题可能第一个结果就是这个答案。
  • @G453 你是对的!可能他被 SHIFT 的性能迷住了,忘记了特征提取和匹配不是问题......
【解决方案2】:

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

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

如果这不是一个线性有效的算法,或者几乎是这样,我会感到惊讶。它显然不能解决你对罐头的歧视,但至少你会有你的标志。

(更新:为了识别瓶子,我会寻找与标志相邻的可乐(棕色液体)——也就是说,在瓶子里面。或者,如果是空瓶子,我会寻找一个 cap,它始终具有相同的基本形状、大小和与徽标的距离,并且通常都是白色或红色。搜索一个纯色椭圆形,其中有一个帽子 应该,相对于标志。当然不是万无一失,但你的目标应该是找到简单快速。)

(距离我的图像处理时代已经过去几年了,所以我将这个建议保持在高层次和概念性上。我认为它可能稍微近似于人眼的运作方式——或者至少是我的大脑的运作方式!)

【讨论】:

  • 这是一个很好的建议,我特别喜欢这个算法应该非常快的事实,即使它可能会有很多假阴性。我的一个隐藏目标是实时将此检测用于机器人技术,因此这可能是一个很好的折衷方案!
  • 是的,人们经常忘记(在以精度为特征的领域)近似算法对于大多数实时、真实世界的建模任务都是必不可少的。 (我的thesis 基于这个概念。)为有限的区域节省时间要求的算法(以修剪误报)。请记住:在机器人技术中,您通常不限于单个图像。假设一个移动机器人,一个快速算法可以从不同角度搜索数十张图像,而不是复杂算法花费在一张上的时间,从而显着减少误报。
  • 我喜欢使用相当于条码扫描器的工具来极快检测可口可乐标识。 +1!
  • 这种情况下寻找签名的问题是,如果我们把罐子翻到另一边,即隐藏签名,算法就会检测不到罐子。
  • @karlphillip:如果你隐藏了签名,即标志,那么基于寻找标志的任何方法都会失败。
【解决方案3】:

有趣的问题:当我看了你的瓶子图片时,我还以为它也是一个罐头。但是,作为一个人类,我所做的区别在于我注意到它也是一个瓶子......

那么,要区分罐头和瓶子,先简单地扫描瓶子怎么样?如果你找到了,在找罐头之前先把标签遮住。

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

【讨论】:

  • 是的,我也想过这个问题,但没有太多时间去做。你如何识别一个瓶子,因为它的主要部分看起来像一个有鳞的罐头?我也在考虑寻找红色插头,看看它是否与瓶装中心对齐,但这似乎不是很坚固。
  • 如果有一个与“可口可乐”平行的红色盖子(或圆环),它很可能是一个瓶子。
  • 这个算法的优势在于你只需要一个模板来训练,然后它会应用所有的转换来匹配其他潜在的罐子。我正在使用这个模板的二值化和基于轮廓的版本来训练,所以罐头和瓶子之间的唯一区别就是塞子,但我担心它会带来更多的误报,因为重心会在边缘的某个地方或瓶外。我想值得一试。但这会使我的处理时间加倍,我要哭了;)
  • 基本上这是一个合理的方向。我的措辞略有不同:首先找到所有候选人,然后为每个候选人确定它是瓶子、罐头还是其他东西。
  • 我真的很喜欢这种方法!不幸的是,它缺乏足够的概括性,因为瓶子并不是唯一可能被检测到的似是而非的误报。我继续说rolled this into an answer,因为这里评论太多了。 :)
【解决方案4】:

在第二张图片中,即使是人类也很难区分瓶子和罐子(假设瓶子的透明区域被隐藏了)?

除了一个很小的区域外,它们几乎相同(即罐顶部的宽度有点小,而瓶子的包装纸的宽度始终相同,但有细微的变化吧?)

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

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

特别注意这个,看看他们检测玻璃的准确度:

查看他们的实现结果:

他们说是论文"A Geodesic Active Contour Framework for Finding Glass" by K. McHenry and J. Ponce, CVPR 2006的实现。

这可能对你的情况有一点帮助,但如果瓶子被装满,问题就会再次出现。

所以我想在这里,你可以先搜索瓶子的透明体,也可以搜索横向连接两个透明物体的红色区域,这显然是瓶子。 (理想情况下,如下图。)

现在您可以移除黄色区域,即瓶子的标签,然后运行您的算法来找到罐子。

不管怎样,这个解决方案和其他解决方案也有不同的问题。

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

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

【讨论】:

  • +1 我考虑过这一点,并且正在实施这种方法。但是,@linker 应该分享他的一组图像,以便我们可以尝试做更有根据的猜测。
  • 是的.. 我也觉得如果有更多的图片就好了。
  • 考虑我们是否只有瓶子/罐头的标签,而没有其他区分瓶盖或透明度或罐顶/底部的因素 - 瓶子的宽度与罐头的宽度不同.
  • 如果在瓶子的标志前面放一个罐子怎么办?
【解决方案5】:

我真的很喜欢 Darren Cook'sstacker's answers 来解决这个问题。我正在将我的想法投入到对这些的评论中,但我相信我的方法太像答案了,不能离开这里。

简而言之,您已经确定了一种算法来确定可口可乐徽标是否出现在太空中的特定位置。您现在正尝试针对任意方向和任意比例因子确定适用于区分可口可乐 与其他对象的启发式方法,包括:bottles广告牌广告可口可乐用具都与这个标志性的标志相关联。您没有在问题陈述中提到许多这些额外的案例,但我认为它们对您的算法的成功至关重要。

这里的秘诀是确定一个包含哪些视觉特征,或者通过负空间确定其他可乐产品存在哪些罐头不具备的特征。为此,the current top answer 勾勒出一种选择“罐头”的基本方法,当且仅当“瓶子”未通过瓶盖、液体或其他类似的视觉启发法识别时。

问题是这坏了。例如,一个瓶子可能是空的并且没有盖子,从而导致误报。或者,它可能是一个部分瓶子,附加功能受损,再次导致错误检测。不用说,这既不优雅,也不符合我们的目的。

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

  • 对象轮廓的形状,如you sketched out in your question,正确吗?如果是这样,+1。
  • 如果我们假设存在自然光或人造光,我们是否会检测到瓶子的镀铬轮廓,表明它是否由铝制成?如果是这样,+1。
  • 相对于我们的光源(illustrative video link on light source detection),我们确定对象的specular properties 是正确的吗?如果是这样,+1。
  • 我们能否确定对象的任何其他属性以将其识别为罐头,包括但不限于徽标的拓扑图像倾斜、对象的方向、对象的并置(例如,在像桌子这样的平面或在其他罐头的情况下),以及拉片的存在?如果是这样,每个人都 +1。

您的分类可能如下所示:

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

这在视觉上向用户突出显示检测到的内容,强调可能被正确检测为破损罐头的弱阳性结果。

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

嘿,恭喜the Hacker News posting! 总的来说,这是一个非常棒的问题,值得它得到宣传。 :)

【讨论】:

  • 这是一个有趣的方法,至少值得一试,我真的很喜欢你对这个问题的推理
  • 这就是我的想法:不排除特定类型的误报。确定可乐罐的更多特征。但我想知道:你怎么处理压扁的罐头?我的意思是,如果你踩到可乐罐,它仍然是可乐罐。但它不再具有相同的形状。或者这个问题是 AI-Complete 吗?
【解决方案6】:

看形状

看看罐子/瓶子的红色部分的形状。注意罐子顶部是如何逐渐变细的,而瓶子标签是直的。您可以通过比较红色部分的宽度与长度来区分这两者。

看亮点

区分瓶子和罐头的一种方法是材料。瓶子由塑料制成,而罐头由铝金属制成。在光线充足的情况下,观察镜面反射是区分瓶子标签和罐头标签的一种方式。

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

【讨论】:

  • 我喜欢这个主意,但您似乎需要一些非常好的照明条件。例如,在同时有罐头和瓶子的示例图像中,这似乎有点难以区分。
  • 在您的示例中,请注意塑料标签的镜面反射比罐头上的亮点更加分散?这就是你可以分辨的方式。
  • 我明白了,在这种情况下,您会使用哪种颜色空间表示来捕捉算法中的镜面反射?这似乎很难在 RGB 或 HSV 中获得
  • 如果光源在罐子后面怎么办?我想你不会看到亮点。
【解决方案7】:

请查看 Zdenek Kalal 的 Predator tracker。它需要一些训练,但它可以主动学习被跟踪对象在不同方向和比例下的外观并实时进行!

源代码可在他的网站上找到。它在MATLAB 中,但也许社区成员已经完成了Java 实现。我已经成功地在 C# 中重新实现了 TLD 的跟踪器部分。如果我没记错的话,TLD 使用蕨类植物作为关键点检测器。如果对象被跟踪器丢失,我会使用 SURF 或 SIFT(@stacker 已经建议)来重新获取对象。跟踪器的反馈使得随着时间的推移构建筛选/冲浪模板的动态列表变得容易,随着时间的推移,这些模板能够以非常高的精度重新获取对象。

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

【讨论】:

  • 感谢您提供看起来很有趣的链接。关于训练,为了达到合理的结果,训练集的大小是合理的?如果您甚至在 c# 中也有实现,那也会非常有帮助!
  • 在研究 TLD 时,我发现另一个用户正在寻找 C# 实现——有什么理由不把你的工作放在 Github 上吗? stackoverflow.com/questions/29436719/…
  • 注:多年后,链接现在失效了
【解决方案8】:

如果您不仅限于使用不受限制的相机,也许您可​​以转而使用诸如 Xbox Kinect 之类的距离传感器。有了这个,您可以对图像执行基于深度和颜色的匹配分割。这允许更快地分离图像中的对象。然后,您可以使用 ICP 匹配或类似技术来匹配罐的形状,而不仅仅是其轮廓或颜色,并且鉴于它是圆柱形的,如果您之前对目标进行了 3D 扫描,这可能是任何方向的有效选项。这些技术通常非常快,尤其是当用于应该解决您的速度问题的特定目的时。

我还可以建议,不一定是为了准确性或速度,而是为了好玩,您可以在您的色调分割图像上使用经过训练的神经网络来识别罐头的形状。这些速度非常快,通常可以达到 80/90% 的准确率。培训将是一个漫长的过程,因为您必须手动识别每张图像中的罐头。

【讨论】:

  • 实际上我并没有在帖子中解释这一点,但对于这项任务,我得到了一组大约 30 张图像,并且必须执行一种算法来匹配所描述的各种情况下的所有图像。当然,最后还是拿出了一些图像来测试算法。但我喜欢 Kinect 传感器的想法,我很想阅读更多关于该主题的内容!
  • 要获得令人满意的结果,使用神经网络的训练集的大小大概是多少?这种方法的好处还在于我只需要一个模板即可匹配几乎所有内容。
  • 如果您的图像集是预定义的和有限的,那么您的程序中只有铁杆完美的结果;)
  • 是的,如果我在数据集上进行训练,我将对其运行算法,我肯定会得到完美的结果 :) 但是例如对于这个作业,该程序由老师在以一组保留的图像结束。我想做一些稳健且不会过度拟合训练数据的事情。
  • 训练集的数量各不相同,但您必须注意以下几点:不要过度训练,您可能需要一个测试集来显示您的准确性如何。此外,训练集的数量将取决于您将使用的层数。
【解决方案9】:

我会检测红色矩形:RGB -> HSV,过滤红色 -> 二值图像,close(先扩张后腐蚀,在 matlab 中称为 imclose

然后从大到小查看矩形。在已知位置/比例中具有较小矩形的矩形都可以被删除(假设瓶子比例恒定,较小的矩形将是瓶盖)。

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

【讨论】:

  • 搬家的时候在DSP上讨论过这个,有些瓶子可能没有塞子;)或者塞子可能被部分隐藏了。
【解决方案10】:

这可能是一个非常幼稚的想法(或者可能根本行不通),但所有可乐罐的尺寸都是固定的。如果同一张图片同时包含罐头和瓶子,那么您可以根据尺寸考虑将它们区分开来(瓶子会更大)。现在由于缺少深度(即 3D 映射到 2D 映射),瓶子可能看起来缩小并且没有尺寸差异。您可以使用stereo-imaging 恢复一些深度信息,然后恢复原始大小。

【讨论】:

  • 实际上没有:没有尺寸或方向的限制(或方向,但我没有真正处理),所以你可以在背景很远的地方放一个瓶子,在前台放一个罐子,而且罐子会比瓶子大得多。
  • 我还检查了瓶子和罐子的宽高比非常相似,所以这也不是一个真正的选择。
  • 标签比例(作为商标)是一样的。因此,如果(较大的)瓶子在图片上稍远一些,它的尺寸将与罐头的尺寸完全相同。
  • 是的,这正是我建议立体成像首先恢复深度的原因。通过使用立体成像,您可以获得深度,然后通过添加深度信息来评估实际大小。
  • 再解释一下。假设罐在 z=0 并且瓶在 z=-100。由于瓶子远远落后,它看起来会更小。但是如果我知道瓶子在 z=-100 并且罐子在 z=0,那么如果两者都转换为 z=0,我可以计算罐子/瓶子的预期尺寸。所以现在它们处于相同的深度,因此我可以根据大小做出决定。
【解决方案11】:

嗯,我实际上认为我在 something (这是有史以来最有趣的问题 - 所以如果不继续尝试找到“完美”的答案将是一种耻辱,即使虽然找到了一个可以接受的)...

一旦找到徽标,您的麻烦就解决了一半。然后你只需要弄清楚周围标志之间的区别。此外,我们希望尽可能少做额外的事情。我认为这实际上是这个简单的部分......

标志周围是什么?对于罐子,我们可以看到金属,尽管有灯光的影响,但它的基本颜色并没有发生任何变化。只要我们知道标签的角度,我们就可以知道它正上方是什么,所以我们正在研究它们之间的区别:

在这里,徽标的上方和下方是完全黑暗的,颜色一致。在这方面相对容易。

在这里,上面和下面是浅色的,但颜色仍然一致。它是全银的,而且全银金属实际上看起来非常罕见,一般来说也是银色。此外,它在一个薄薄的滑行中,并且与已经识别的红色足够接近,因此您可以追踪其整个长度的形状,以计算可以被认为是罐头金属环的百分比。确实,您只需要在罐子上的任何地方占一小部分就可以判断它是其中的一部分,但您仍然需要找到一个平衡点,以确保它不仅仅是一个空瓶子,后面有金属东西。

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

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

在罕见的情况下,即使在塑料被提取后,瓶子后面也有类似的银色,或者瓶子以某种方式充满了相同的银色液体,我们可以依靠我们可以粗略估计的东西作为银的形状 - 正如我提到的,它是圆形的,并且遵循罐头的形状。但是,即使我缺乏图像处理方面的任何知识,这听起来也很慢。更好的是,为什么不通过检查徽标的侧面 来推断出这一点,以确保那里没有相同的银色?啊,但是如果罐子后面有同样的银色呢?然后,我们确实需要更多地关注形状,再看看罐头的顶部和底部。

取决于这一切需要多么完美,它可能会很慢,但我想我的基本概念是首先检查最简单和最接近的东西。在努力计算其他元素的形状之前,先检查已经匹配的形状周围的颜色差异(无论如何这似乎是最微不足道的部分)。要列出它,它是:

  • 找到主要的吸引力(红色徽标背景,可能还有用于定位的徽标本身,但如果罐子被转开,您需要只专注于红色)
  • 再次通过非常独特的红色验证形状和方向
  • 检查形状周围的颜色(因为它快速且无痛)
  • 最后,如果需要,验证主要景点周围颜色的形状是否正确。

如果您无法做到这一点,则可能意味着罐子的顶部和底部都被盖住了,人类可以用来可靠地区分罐子和瓶子的唯一可能的东西是罐子的遮挡和反射,这将是一场非常难以处理的战斗。但是,更进一步,您可以使用其他答案中提到的半透明扫描技术,按照罐子/瓶子的角度检查更多类似瓶子的特征。

有趣的其他噩梦可能包括一个罐子,方便地放在瓶子后面,距离很远,以至于它的金属恰好显示在标签的上方和下方,只要您沿着整个长度扫描,它仍然会失败红色标签 - 这实际上是一个更大的问题,因为你没有检测到你可以拥有的罐子,而不是考虑到你实际上是在偶然检测到一个瓶子,包括罐子。在那种情况下,杯子是半空的!


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

编辑

此外,看看我在 MS Paint 中绘制的这幅图……它非常糟糕而且非常不完整,但仅根据形状和颜色,你就可以猜出它可能会是什么。从本质上讲,这些是唯一需要费心扫描的东西。当你如此近距离地观察那个非常独特的形状和颜色组合时,它还能是什么?我没有画的那一点,白色背景,应该被认为是“任何不一致的东西”。如果它有一个透明的背景,它几乎可以覆盖任何其他图像并且你仍然可以看到它。

【讨论】:

  • 特定的红色阴影大多是主观的,并且受到照明考虑和白平衡的强烈影响。您可能会对这些变化有多大感到惊讶。例如,考虑一下这个checkerboard illusion
  • @Octopus 发布的链接的更新:persci.mit.edu/gallery/checkershadow
  • 感知错觉不会影响您的网络摄像头看到的内容 - 即您的代码获得的内容 - 只有人眼如何帮助(?)愚弄大脑。
【解决方案12】:

我不知道 OpenCV,但从逻辑上看问题,我认为您可以通过更改您正在寻找的图像(即可口可乐)来区分瓶子和罐头。你应该加入直到罐头的顶部,因为可口可乐的顶部有银色衬里,而瓶子则没有这样的银色衬里。

但显然,如果罐子顶部被隐藏,该算法将失败,但在这种情况下,即使是人类也无法区分两者(如果瓶子/罐子只有可口可乐部分可见)

【讨论】:

  • 我也有同样的想法,但我认为罐头顶部的银色衬里会根据图片上罐头的角度而发生巨大变化。它可以是直线或圆。也许他可以将两者作为参考?
【解决方案13】:

回答这个问题晚了几年。在过去 5 年中,随着 CNN 将最先进的技术推向极限,我现在不会使用 OpenCV 来完成这项任务! (我知道你特别想要问题中的 OpenCv 功能)我觉得对象检测算法,如 Faster-RCNN、YOLO、SSD 等,与 OpenCV 功能相比,会以显着的优势解决这个问题。如果我现在(6 年后!!)解决这个问题,我肯定会使用 Faster-RCNN

【讨论】:

  • OP 说有 30 张高分辨率图像,这可能不是训练 ConvNets 的最佳场景。它们不仅太少(甚至增强),而且高分辨率部分会破坏 ConvNet。
【解决方案14】:

我喜欢这个挑战,我想给出一个解决问题的答案。

  1. 提取标志的特征(关键点、描述符,如 SIFT、SURF)
  2. 将点与徽标的模型图像匹配(使用匹配器,例如 Brute Force )
  3. 估计刚体的坐标(PnP 问题 - SolvePnP)
  4. 根据刚体估计帽盖位置
  5. 进行反投影并计算瓶盖的图像像素位置 (ROI)(我假设您有相机的内在参数)
  6. 使用方法检查盖子是否存在。如果有,那么这就是瓶子

检测上限是另一个问题。它可以是复杂的,也可以是简单的。如果我是你,我会简单地检查 ROI 中的颜色直方图以做出简单的决定。

如果我错了,请提供反馈。谢谢。

【讨论】:

    【解决方案15】:

    我喜欢你的问题,不管它是否离题:P

    一个有趣的旁白;我刚刚完成了我的学位课程,其中涵盖了机器人技术和计算机视觉。我们本学期的项目与您描述的项目非常相似。

    我们必须开发一种机器人,该机器人使用 Xbox Kinect 在各种照明和环境条件下检测任何方向的可乐瓶和易拉罐。我们的解决方案涉及在 Hue 通道上使用带通滤波器并结合霍夫圆变换。我们能够稍微限制环境(我们可以选择机器人和 Kinect 传感器的位置和方式),否则我们将使用 SIFT 或 SURF 变换。

    您可以在my blog post on the topic 上阅读我们的方法:)

    【讨论】:

    • 有趣的项目,但它只适用于您非常具体的设置。
    【解决方案16】:

    深度学习

    收集至少几百张包含可乐罐的图像,将它们周围的边界框注释为正类,包括可乐瓶和其他可乐产品,将它们标记为负类以及随机对象。

    除非您收集非常大的数据集,否则请执行将深度学习功能用于小数据集的技巧。理想情况下使用支持向量机 (SVM) 与深度神经网络的组合。

    将图像输入到先前训练的深度学习模型(例如 GoogleNet)后,不要使用神经网络的决策(最终)层进行分类,而是使用先前层的数据作为特征来训练您的分类器。

    OpenCV 和谷歌网络: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

    OpenCV 和 SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html

    【讨论】:

      【解决方案17】:

      用于识别物体的颜色描述符有很多,下面的论文比较了很多。当与 SIFT 或 SURF 结合使用时,它们特别强大。单独的 SURF 或 SIFT 在可口可乐罐图像中不是很有用,因为它们不能识别很多兴趣点,您需要颜色信息来提供帮助。我在一个项目中使用 BIC(边界/内部像素分类)和 SURF,它在识别物体方面效果很好。

      Color descriptors for Web image retrieval: a comparative study

      【讨论】:

        【解决方案18】:

        您需要一个能够从经验中有机地学习和提高分类准确性的程序。

        我会建议深度学习,通过深度学习,这将成为一个微不足道的问题。

        您可以在 Tensorflow 上重新训练 inception v3 模型:

        How to Retrain Inception's Final Layer for New Categories.

        在这种情况下,您将训练一个卷积神经网络来将一个对象分类为可口可乐罐或不可口可乐。

        【讨论】:

          【解决方案19】:

          作为所有这些不错的解决方案的替代方案,您可以训练自己的分类器并使您的应用程序对错误具有鲁棒性。例如,您可以使用Haar Training,提供大量目标的正面和负面图像。

          只提取罐头很有用,可以结合透明物体的检测。

          【讨论】:

            【解决方案20】:

            MVTec 有一个名为 HALCON 的计算机视觉包,它的演示可以为您提供很好的算法思路。有很多与您的问题类似的示例,您可以在演示模式下运行,然后查看代码中的运算符,看看如何从现有的 OpenCV 运算符中实现它们。

            我已经使用这个包为此类问题快速构建了复杂算法的原型,然后找到了如何使用现有的 OpenCV 特性来实现它们。特别是对于您的情况,您可以尝试在 OpenCV 中实现嵌入在运算符 find_scaled_shape_model 中的功能。一些运营商指出有关算法实现的科学论文可以帮助找出如何在 OpenCV 中做类似的事情。

            【讨论】:

            • HALCON 是一个专有软件,是否有任何开源软件包提供与 opencv 类似的解决方案。
            • 如果有的话,MVTec 早就倒闭了。他们的软件真的很贵!
            【解决方案21】:

            也许晚了很多年,但仍然是一个值得尝试的理论。

            红色标识区域的边框与瓶/罐整体尺寸的比例不同。如果是罐头,应该是 1:1,而在瓶子(有盖或没有盖)中会有所不同。 这应该很容易区分两者。

            更新: 由于 Can 和 Bottle 各自的尺寸不同,标识区域的水平曲率会有所不同。如果您的机器人需要拿起罐子/瓶子,并且您相应地决定抓握,这可能特别有用。

            【讨论】:

              【解决方案22】:

              如果您对它是实时的感兴趣,那么您需要添加一个预处理过滤器,以确定使用重型材料扫描的内容。一个很好的快速、非常实时的预处理过滤器,它可以让您扫描更有可能是可口可乐罐的东西,而不是在移动到更不确定的东西之前是这样的:在图像中搜索最大的补丁与可口可乐罐的sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) 有一定公差的颜色。从非常严格的颜色容差开始,然后逐步降低到更宽松的颜色容差。然后,当您的机器人用完分配的时间来处理当前帧时,它会将当前找到的瓶子用于您的目的。请注意,您必须调整 sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) 中的 RGB 颜色才能使它们恰到好处。

              另外,这看起来真的很愚蠢,但是您是否确保在编译 C 代码时打开 -oFast 编译器优化?

              【讨论】:

                【解决方案23】:

                我首先要寻找的是颜色——比如红色,当在图像中进行红眼检测时——有一定的颜色范围需要检测,考虑到周围区域的一些特征,例如与其他区域的距离眼睛,如果它确实在图像中可见。

                1:第一个特征是颜色,红色非常占主导地位。检测到可口可乐红后,有几个感兴趣的项目 1A:这个红色区域有多大(它的数量是否足以确定一个真正的罐头 - 10个像素可能不够), 1B:它是否包含标签的颜色 - “可口可乐”或波浪。 1B1:是否足以考虑它是标签的高概率。

                第 1 项是一种捷径 - 如果图像中不存在该内容,则进行预处理 - 继续。

                因此,如果是这种情况,我可以利用我的图像的那部分并开始查看更多缩小问题区域 - 基本上查看周围区域/边缘......

                2:给定上述图像区域 ID 为 1 - 验证相关项目的周围点 [边缘]。 A: 有没有看起来像罐头或罐底的东西——银? B:瓶子可能看起来是透明的,但玻璃桌子也可能是透明的——是否有玻璃桌子/架子或透明区域——如果有的话,会有多种可能的结果。一个瓶子可能有一个红色的盖子,它可能没有,但它应该具有瓶盖/螺纹螺钉的形状,或者一个盖子。 C:即使这失败了 A 和 B,它仍然可以是一个罐头 - 部分.. 当它是部分的时,这会更复杂,因为部分瓶子/部分罐可能看起来相同,因此对红色区域边缘到边缘的测量进行更多处理..小瓶子的大小可能相似..

                3:经过上述分析后,我会查看字母和波浪徽标 - 因为我可以定向搜索单词中的一些字母因为您可能没有所有文本,因为没有所有的可以,波浪会在某些点与文本对齐(距离),所以我可以搜索那个概率并知道在距离 x 的那个点应该存在哪些字母。

                【讨论】:

                  猜你喜欢
                  • 2011-10-17
                  • 2013-03-09
                  • 1970-01-01
                  • 2012-12-06
                  • 2019-06-21
                  • 2019-07-19
                  • 1970-01-01
                  相关资源
                  最近更新 更多