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

Cha*_*guy 1585 c++ algorithm opencv image-processing

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

模板匹配

对项目的一些限制:

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

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

总失败

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

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

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

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

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

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

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

GHT

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

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

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

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

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

sta*_*ker 647

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

它在OpenCV 2.3.1中实现.

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

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

在此输入图像描述

图片来源:教程示例

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

原始论文

  • 你怎么能接受这个作为答案......没有一个特征描述符可以区分瓶子和罐头......它们都只是查看不变的局部模式描述符.我同意SIFT,SURF,ORB,FREAK等可以帮助你进行功能匹配,但是..你的问题的其他部分如闭塞,瓶与罐头等等.我希望这不是一个完整的解决方案,如果你愿意的话有可能第一个结果只是这个答案. (59认同)
  • 警告提示:尽管我喜欢SIFT/SURF以及他们对我做了什么,但他们受到了专利保护.这*可能是一个问题,取决于许多条件,包括地理位置AFAIK. (28认同)
  • 因此,请尝试OpenCV的ORB或FREAK,它们没有专利问题.ORB比SIFT快得多.ORB它的体积和光线变化有点差,但我自己测试一下. (12认同)
  • @ G453你是绝对正确的!可能他对SHIFT的表现很着迷,忘记了特征提取和匹配不是问题...... (10认同)
  • 我同意@stacker - SIFT是一个很好的选择.它对比例和旋转操作非常强大.它对透视变形有一定的鲁棒性(这可以通过堆栈器建议来改进:具有所需对象的不同透视图的模板数据库).根据我的经验,它的阿基里斯的脚跟将是强烈的光线变化和非常昂贵的计算.我不知道任何Java实现.我知道OpenCV实现并使用了适合实时性能的GPU c ++/Windows([SiftGPU](http://cs.unc.edu/~ccwu/siftgpu/))实现. (6认同)
  • 听起来不错.此算法是否也处理方向不变性(即,如果can不直接面对相机的目标)?这是我的算法失败的主要原因之一. (2认同)
  • 镜像链接[Features2D + Homography查找已知对象](http://docs.opencv.org/2.4/doc/tutorials/features2d/feature_homography/feature_homography.html) (2认同)

kmo*_*ote 366

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

签名扫描线

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

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

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

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

  • 是的,它经常被遗忘(在精确的领域)*近似*算法对于大多数实时,真实世界建模任务是必不可少的.(我根据这个概念建立了我的[论文](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.163.2733).)为有限的区域保存你的时间要求算法(修剪错误阳性).请记住:在机器人技术中,您通常不限于单个图像.假设一个移动机器人,一个快速的alg可以在更短的时间内搜索来自不同角度的数十个图像,而不是复杂的algs花费在一个上,从而显着减少假阴性. (37认同)
  • @karlphillip:如果你隐藏签名,即徽标,那么基于寻找徽标的*any*方法将会失败. (31认同)
  • 我喜欢使用什么相当于条形码扫描仪来快速**检测可口可乐标识.+1! (27认同)
  • 这是一个很好的建议,我特别喜欢这个算法应该非常快的事实,即使它可能会有很多漏报.我隐藏的目标之一是对机器人技术实时使用这种检测,这可能是一个很好的妥协! (19认同)
  • 在这种情况下寻找签名的问题是,如果我们将罐头转向另一侧,即隐藏签名,算法将无法检测到罐头. (6认同)
  • @ Li-aungYip很好的解决方法,但是签名方法还有其他限制,例如,如果罐子的标签有点损坏或罐头有点破碎,检测将失败.现实是,这个问题是一个艰难的**研究**问题.它太复杂了,它的当前格式引发了扩展讨论.人们没有意识到有专家每天都在研究这种类型的东西.这个问题不会在SO线程中解决. (5认同)
  • 这是迄今为止最好的建议,应该是这个问题的解决方案; 它简单优雅,看不见东西,它在问题中找到了一个黑客,是我们观察世界的捷径.这就是人工视觉识别的关键所在. (2认同)
  • @Stefan - 我非常尊重你在徽标识别方面所做的工作,但我只想指出我的"解决方案"确实解决了OP的具体问题.他没有要求一般解决方案; 他想要一个满足规定要求的*fast*解决方案.有时候,作为专家,当一个简单的"临时"方法可能会让你只需要一小部分努力时,我们就太快跳到过度设计的解决方案了.(但总的来说,我应该指出我的方法确实是可扩展的,理论上可以在任何数量的标识上进行培训.) (2认同)
  • 难道你还不需要检查整个图像中的每一行/行组,*360用于每个可能的旋转,这个"行"标识符?我不认为人工神经网在这个问题上会有所帮助吗? (2认同)

Dar*_*ook 154

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

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

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

  • 如果有一个与"可口可乐"平行的红色帽子(或环),它很可能是一个瓶子. (39认同)
  • 基本上这是一个合理的方向.我的短语略有不同:首先找到所有候选人,然后为每个候选人确定它是瓶子,罐子还是其他东西. (7认同)
  • 是的,我也考虑过这个,但没有太多时间去做.你怎么认出一个瓶子,因为它的主要部分看起来像一个缩放的罐子?我也在考虑寻找红色插头,看看它是否与瓶装中心对齐,但这看起来不太稳健. (5认同)
  • 该算法的优点在于,您只需要**一个**模板进行训练,然后它会应用所有转换以将其与其他潜在的罐头匹配。我使用此模板的二值化和基于轮廓的版本进行训练,因此罐头和瓶子之间的唯一区别是插头,但我担心它会带来更多误报,因为重心将位于边缘的某个地方或在瓶子外面。我想值得一试。但这会让我的处理时间加倍,我会哭的;) (2认同)
  • 我真的很喜欢这种方法!不幸的是,它缺乏足够的概括性,因为_瓶子并不是唯一可能检测到的看似合理的误报。_我已经继续并[将其纳入答案](http://stackoverflow.com/a/10272868/517815 ),因为这里的评论太多了。:) (2认同)

Abi*_*n K 122

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

它们几乎是相同的,除了一个非常小的区域(也就是说,罐子顶部的宽度有点小,而瓶子的包装纸在整个宽度相同,但是稍微改变一下吧?)

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

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

特别注意这一点,看看它们检测玻璃的准确程度如何:

查看他们的实施结果:

在此输入图像描述

他们说这是由K. McHenry和J. Ponce,CVPR 2006撰写的"A Geodesic Active Contour Framework for Finding Glass"论文的实施.

它可能对您的情况有所帮助,但如果瓶子被填满则会再次出现问题.

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

在此输入图像描述

现在,您可以删除黄色区域,即瓶子的标签,并运行算法以查找罐头.

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

  1. 它只适用于您的瓶子是空的.在这种情况下,您将不得不搜索两种黑色之间的红色区域(如果可口可乐液体是黑色的).
  2. 覆盖透明部分的另一个问题.

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

  • 如果瓶子的标志前面放了一个罐头怎么办? (2认同)

MrG*_*mez 48

我真的很喜欢Darren Cook堆叠器对这个问题的回答.我正在把我的想法投入评论那些,但我相信我的方法太具有答案性,不能离开这里.

简而言之,您已经确定了一种算法,以确定在太空中的特定位置存在可口可乐徽标.您现在正在尝试确定任意方向和任意缩放因子,适用于区分可口可乐与其他物体的启发式方法,包括:瓶子,广告牌,广告可口可乐用具,所有这些都与此标志性标识相关联.您没有在问题陈述中调出许多其他案例,但我认为它们对您的算法的成功至关重要.

这里的秘诀在于确定可以包含哪些视觉特征,或者通过负空间确定哪些特征可用于其他可用于罐头的可乐产品.为此,当前的最佳答案概述了选择"罐头"的基本方法,当且仅当"瓶子"未被识别时,通过瓶盖,液体或其他类似的视觉启发法的存在.

问题是这会破裂.例如,瓶子可能是空的并且没有盖子,导致假阳性.或者,它可能是一个部分瓶子,其他功能被破坏,再次导致错误检测.毋庸置疑,这不是优雅的,对我们的目的也没有效果.

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

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

您的分类可能如下所示:

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

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

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

嘿,恭喜黑客新闻发布!总的来说,这是一个非常好的问题,值得它收到的宣传.:)

  • 这是一个有趣的方法,至少值得一试,我真的很喜欢你对这个问题的推理 (2认同)

tsk*_*zzy 39

看着形状

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

看着亮点

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

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

  • 如果光源在罐子后面怎么办?我想你不会看到亮点. (2认同)

小智 35

请看一下Zdenek Kalal的Predator追踪器.它需要一些培训,但它可以主动了解被跟踪对象在不同方向和比例下的看法,并实时进行!

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

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

  • NB 几年后,链接现在已经死了 (3认同)

Fan*_*Fox 31

如果你不仅限于一个不在你的约束条件下的相机,也许你可以转向使用像Xbox Kinect这样的范围传感器.通过这种方式,您可以执行基于深度和颜色的图像匹配分割.这允许更快地分离图像中的对象.然后,您可以使用ICP匹配或类似技术来匹配罐的形状,而不仅仅是它的轮廓或颜色,并且假设它是圆柱形的,如果您对目标进行了先前的3D扫描,则这可能是任何方向的有效选项.这些技术通常非常快,特别是在用于解决速度问题的特定目的时.

我也可以建议,不一定是为了准确性或速度,但为了好玩,你可以在你的色调分割图像上使用训练有素的神经网络来识别罐子的形状.这些速度非常快,通常可达到80/90%的准确度.虽然您需要手动识别每个图像中的罐头,但培训过程有点长.

  • 实际上我没有在帖子中解释过,但是对于这个任务我给了一组大约30张图像,并且必须做一个算法,在所描述的各种情况下都能匹配它们.当然,一些图像最终被用来测试算法.但我喜欢Kinect传感器的想法,我想更多地了解这个主题! (3认同)
  • 如果您的图像集是预定义且有限的,那么只需要硬编完美的结果;) (2认同)

Ale*_*x L 22

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

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

这将留下红色矩形,然后您需要以某种方式检测徽标,以告知它们是红色矩形还是可乐.像OCR一样,但有一个已知的标志?

  • 像这样在DSP被移动的短时间内被讨论,一些瓶子可能没有插头;)或插头可能部分隐藏. (2认同)

Sha*_*rad 20

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

  • 实际上没有:没有大小或方向的限制(或方向,但我没有真正处理),所以你可以在背景中有一个很远的瓶子,前景中有一个罐子,罐子会更大比瓶子. (3认同)
  • 再解释一下.假设can在z = 0并且瓶子在z = -100.由于瓶子远远落后,它看起来会更小.但是如果我知道瓶子在z = -100并且可以在z = 0,那么如果两者都被转换为z = 0,我可以计算罐子/瓶子的预期尺寸.所以现在它们处于相同的深度,因此我可以根据尺寸做出决定. (3认同)
  • 我还检查过瓶子和罐子的宽高比非常相似,所以这也不是一个真正的选择。 (2认同)
  • 这只是一个评论,而不是一个答案,但它比上面有 120 票的评论作为答案更接近答案。 (2认同)

Dej*_*eji 20

嗯,我实际上认为我正在做某件事(这就像有史以来最有趣的问题 - 所以尽管找到了一个可以接受的答案,但不继续试图找到"完美"答案是一种耻辱). .

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

什么周围的标志?对于罐头,我们可以看到金属,尽管有照明效果,但它的基本颜色不会改变.只要我们知道标签的角度,我们就可以知道标签的正上方,所以我们看看它们之间的区别:

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

在这里,上面和下面的是光,但颜色仍然一致.这是全银色,全银色金属实际上看起来非常罕见,以及一般的银色.此外,它处于一个薄的滑动位置并且足够接近已经识别的红色,因此您可以在其整个长度上追踪其形状,以计算可以被视为罐的金属环的百分比.实际上,你只需要沿着罐子里的一小部分就可以告诉它是它的一部分,但你仍然需要找到一个平衡点,以确保它不仅仅是一个空瓶子,背后有金属.

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

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

在罕见的情况下,瓶子背后有类似的银色阴影,即使在取出塑料之后,或者瓶子以某种方式填充了相同的银色液体,我们可以回到我们可以粗略估计的是银的形状 - 正如我所提到的,是圆形的并且遵循罐的形状.但即使我在图像处理方面缺乏某些知识,这听起来也很慢.更好的是,为什么不一次检查一下标识的两侧以确保那里没有相同的银色?啊,但如果罐子后面有相同的银色呢?然后,我们确实需要更多地关注形状,再次看到罐头的顶部和底部.

取决于所有这些都需要完美无瑕,它可能会非常慢,但我想我的基本概念是首先检查最简单和最接近的东西.在努力计算出其他元素的形状之前,先考虑已经匹配的形状(这似乎是最无聊的部分)周围的颜色差异.要列出它,它会:

  • 找到主要的景点(红色标志背景,可能还有标志本身的方向,但如果罐头被拒之外出,你需要专注于红色的单独)
  • 通过非常独特的红色再次验证形状和方向
  • 检查形状周围的颜色(因为它快速且无痛)
  • 最后,如果需要,验证主要景点周围的那些颜色的形状以获得正确的圆度.

如果你不能做到这一点,它可能意味着罐头的顶部和底部被覆盖,并且人类可以用来可靠地区分罐头和瓶子的唯一可能的东西是遮挡和反射罐,这将是一个难的战斗来处理.然而,为了更进一步,您可以使用罐/瓶的角度来检查更多瓶状特征,使用其他答案中提到的半透明扫描技术.

有趣的额外噩梦可能包括一个可以方便地坐在瓶子后面的距离,使得它的金属恰好显示在标签的上方和下方,只要你沿着整个红色长度扫描,它仍会失败标签 - 这实际上更像是一个问题,因为你没有检测到你可以拥有的罐子,而不是考虑到你实际上是在检测瓶子,包括罐头.在这种情况下,玻璃是半空的!


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

编辑

在MS油漆中绘制一个罐头 另外,看看我在MS Paint中所做的这张图...这绝对是非常糟糕且非常不完整,但仅基于形状和颜色,你可以猜出它可能是什么.从本质上讲,这些是人们需要进行扫描的唯一内容.当你看到那种非常独特的形状和颜色组合如此接近时,还有什么可能呢?我没画的那个,白色的背景,应该被认为是"任何不一致的".如果它有一个透明的背景,它几乎可以覆盖任何其他图像,你仍然可以看到它.

  • 红色的特殊色调主要是主观的,并且受到照明考虑和白平衡的强烈影响.你可能会惊讶于它们可以改变多少.考虑,例如,此[棋盘错觉](http://web.mit.edu/persci/people/adelson/checkershadow_illusion.html). (10认同)
  • @Octopus 发布的链接更新:http://persci.mit.edu/gallery/checkershadow (4认同)
  • 感知错觉不会影响您的网络摄像头看到的内容(即您的代码得到的内容),只会影响人眼如何有效(?)欺骗大脑。 (2认同)

tec*_*rer 15

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

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

  • 我也有同样的想法,但我认为罐子顶部的银色衬里会根据图片上罐子的角度发生巨大变化。它可以是一条直线或一个圆。也许他可以将两者都用作参考? (2认同)

eda*_*gac 13

我认为,我喜欢这个挑战,并希望给出一个解决问题的答案.

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

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

如果我错了,请给出反馈.谢谢.


Abh*_*aji 11

回答这个问题已经晚了几年.随着CNN在过去5年中将技术发展到极限,我现在不会使用OpenCV来完成这项任务!(我知道你在问题中特别想要OpenCv功能)我觉得像OpenCV功能这样的物体检测算法,如Faster-RCNN,YOLO,SSD等,可以显着提高这个问题.如果我现在要解决这个问题(6年后!!)我绝对会使用Faster-RCNN.

  • OP表示有30张高分辨率图像,这可能不是训练ConvNets的最佳方案。它们不仅太少(甚至没有增加),高分辨率部分也会破坏ConvNets。 (2认同)

Gui*_*tas 10

有许多颜色描述符用于识别对象,下面的文章比较了很多对象.当与SIFT或SURF结合使用时,它们特别强大.单独的SURF或SIFT在可口可乐图像中不是很有用,因为它们不识别很多兴趣点,需要颜色信息来帮助.我在项目中使用带有SURF的BIC(边界/内部像素分类),它可以很好地识别物体.

Web图像检索的颜色描述符:比较研究


aar*_*ell 9

我喜欢你的问题,无论是否偏离主题:P

一个有趣的一面; 我刚刚完成了我的学位课程,其中包括机器人和计算机视觉.我们这个学期的项目与你描述的项目非常相似.

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

您可以在关于该主题的博客文章中阅读我们的方法:)

  • 有趣的项目,但它只适用于您的特定设置. (2认同)

Sem*_*maz 9

深度学习

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

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

一旦您将图像提供给先前训练的深度学习模型(例如GoogleNet),而不是使用神经网络的决策(最终)层进行分类,请使用先前的图层数据作为功能来训练您的分类器.

OpenCV和Google Net: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


小智 9

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

我建议深度学习,深入学习这会成为一个微不足道的问题.

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

如何重新定义新类别的初始层.

在这种情况下,您将训练卷积神经网络将对象分类为可口可乐可以与否.

  • 热狗还是不热狗? (2认同)

mad*_*uci 6

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

仅提取罐可以是有用的,并且可以与透明对象的检测组合.


Dar*_*nas 5

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

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