标签: image-processing

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

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

模板匹配

对项目的一些限制:

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

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

总失败

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

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

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

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

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

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

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

GHT

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

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

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

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

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

c++ algorithm opencv image-processing

1585
推荐指数
20
解决办法
18万
查看次数

我怎样才能找到带有Mathematica的Waldo?

周末这让我很烦恼:什么是解决那些Waldo的好方法 [ 'Wally'在北美之外]使用Mathematica(图像处理和其他功能)进行拼图?

这是我到目前为止的功能,它通过调暗一些非红色来减少视觉复杂度:

whereIsWaldo[url_] := Module[{waldo, waldo2, waldoMask},
    waldo = Import[url];
    waldo2 = Image[ImageData[
        waldo] /. {{r_, g_, b_} /;
          Not[r > .7 && g < .3 && b < .3] :> {0, 0,
          0}, {r_, g_, b_} /; (r > .7 && g < .3 && b < .3) :> {1, 1,
          1}}];
    waldoMask = Closing[waldo2, 4];
    ImageCompose[waldo, {waldoMask, .5}]
]
Run Code Online (Sandbox Code Playgroud)

以及这个"有效"的网址示例:

whereIsWaldo["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"]
Run Code Online (Sandbox Code Playgroud)

(Waldo是收银台):

Mathematica图形

wolfram-mathematica image-processing

1538
推荐指数
5
解决办法
25万
查看次数

2D阵列中的峰值检测

我正在帮助一家兽医诊所测量狗爪下的压力.我使用Python进行数据分析,现在我不得不试图将爪子分成(解剖学)子区域.

我制作了每个爪子的2D阵列,它由爪子随时间加载的每个传感器的最大值组成.这是一个爪子的例子,我用Excel绘制了我想要"检测"的区域.这些是传感器周围的2×2个盒子,具有局部最大值,它们一起具有最大的总和.

替代文字

所以我尝试了一些实验并决定只查找每列和每行的最大值(由于爪子的形状,不能在一个方向上查看).这似乎可以很好地"检测"单独脚趾的位置,但它也标记了相邻的传感器.

替代文字

那么告诉Python哪些最大值是我想要的最好的方法是什么?

注意:2x2正方形不能重叠,因为它们必须是单独的脚趾!

我也采用2x2作为方便,欢迎任何更高级的解决方案,但我只是一个人类运动科学家,所以我既不是真正的程序员也不是数学家,所以请保持"简单".

这是一个可以加载版本np.loadtxt


结果

所以我尝试了@jextee的解决方案(见下面的结果).正如你所看到的,它在前爪上很有效,但后腿的效果不太好.

更具体地说,它无法识别出第四个脚趾的小峰值.这显然是循环看起来自上而下朝向最低值的事实所固有的,而不考虑这是什么.

有谁知道如何调整@jextee的算法,以便它也可以找到第4个脚趾?

替代文字

由于我还没有处理任何其他试验,我不能提供任何其他样品.但我之前提供的数据是每只爪子的平均值.该文件是一个数组,其最大数据为9个爪子,它们与盘子接触的顺序.

该图像显示了它们如何在空间上展开.

替代文字

更新:

我已经为任何感兴趣的人建立了一个博客,我已经设置了一个包含所有原始测量值的SkyDrive.所以对于要求更多数据的人来说:给你更大的力量!


新更新:

所以在我得到关于爪子检测爪子分类的问题的帮助后,我终于能够检查每个爪子的脚趾检测!事实证明,除了像我自己的例子中那样大小的爪子之外,它在任何东西上都不能很好地工作.事后看来,任意选择2x2是我自己的错.

这是一个错误的例子:钉子被识别为脚趾,"脚跟"如此宽,它被识别两次!

替代文字

爪子太大,因此在没有重叠的情况下采用2x2尺寸会导致一些脚趾被检测到两次.相反,在小型犬中,它经常无法找到第五个脚趾,我怀疑它是由2x2区域太大引起的.

对我的所有测量结果进行了当前的解决方案之后,我得出了令人吃惊的结论:几乎所有的小型犬都没有找到第5个脚趾,并且对于大型犬的50%以上的影响它会发现更多!

显然我需要改变它.我自己的猜测是将neighborhood小型狗的体型改为小型犬,大型犬则更大.但是generate_binary_structure不会让我改变数组的大小.

因此,我希望其他人有更好的建议来定位脚趾,也许脚趾区域尺寸与爪子尺寸一致?

python image-processing

843
推荐指数
18
解决办法
9万
查看次数

如何检测圣诞树?

哪些图像处理技术可用于实现检测以下图像中显示的圣诞树的应用程序?

我正在寻找适用于所有这些图像的解决方案.因此,需要训练haar级联分类器模板匹配的方法不是很有趣.

我正在寻找可以用任何编程语言编写的东西,只要它只使用开源技术.必须使用此问题上共享的图像测试解决方案.有6个输入图像,答案应显示处理每个图像的结果.最后,对于每个输出图像,必须有红线绘制以包围检测到的树.

您将如何以编程方式检测这些图像中的树?

c++ python opencv image-processing computer-vision

376
推荐指数
10
解决办法
2万
查看次数

代表和解决给定图像的迷宫

在给定图像的情况下,表示和解决迷宫的最佳方法是什么?

The Scope Issue 134的封面图片

给定一个JPEG图像(如上所示),读取它的最佳方法是什么,将其解析为一些数据结构并解决迷宫?我的第一直觉是逐像素地读取图像并将其存储在布尔值的列表(数组)中:True对于白色像素,False对于非白色像素(可以丢弃颜色).这种方法的问题是图像可能不是"像素完美".我只是说,如果墙上的某个地方有白色像素,可能会造成意想不到的路径.

另一种方法(经过深思熟虑后来找我)是将图像转换为SVG文件 - 这是在画布上绘制的路径列表.这样,路径可以被读入相同类型的列表(布尔值),其中True指示路径或墙,False指示可行进空间.如果转换不是100%准确,并且未完全连接所有墙壁,从而产生间隙,则会出现此方法的问题.

转换为SVG的另一个问题是线条不是"完美"直线.这导致路径是立方贝塞尔曲线.使用由整数索引的布尔值列表(数组),曲线不会轻易转移,并且必须计算曲线上所有的点,但不会与列表索引完全匹配.

我假设虽然这些方法中的一种可能有用(尽管可能不是),但鉴于这么大的图像,它们的效率非常低,并且存在更好的方法.如何最好(最有效和/或最简单)完成?有没有最好的方法?

然后是迷宫的解决方案.如果我使用前两种方法中的任何一种,我基本上会得到一个矩阵.根据这个答案,表示迷宫的好方法是使用树,解决它的好方法是使用A*算法.如何从图像中创建树?有任何想法吗?

TL; DR
最好的解析方法?进入什么数据结构?该结构将如何帮助/阻碍解决?

更新
我已经尝试过实现@Mikhail用Python编写的东西numpy,正如@Thomas推荐的那样.我觉得这个算法是正确的,但它没有像希望的那样工作.(下面的代码.)PNG库是PyPNG.

import png, numpy, Queue, operator, itertools

def is_white(coord, image):
  """ Returns whether (x, y) is approx. a white pixel."""
  a = True
  for i in xrange(3):
    if not a: break
    a = image[coord[1]][coord[0] * 3 + i] > 240
  return a

def bfs(s, e, i, visited):
  """ Perform a breadth-first search. …
Run Code Online (Sandbox Code Playgroud)

python algorithm matlab maze image-processing

258
推荐指数
8
解决办法
5万
查看次数

什么是最好的java图像处理库/方法?

我正在使用JAI媒体api和ImageMagick?

ImageMagick有一些可扩展性问题,而基于JNI的JMagick也没有吸引力.与ImageMagick相比,JAI在进行大小调整操作时效果不佳.

有没有人知道任何优秀的工具,无论是开源还是商业本土java并提供高质量的结果?

java image-manipulation image-processing

239
推荐指数
6
解决办法
22万
查看次数

如何使用C#裁剪图像?

如何编写将在C#中裁剪图像的应用程序?

c# image-processing

234
推荐指数
6
解决办法
24万
查看次数

建议使用ImageMagick压缩JPG文件

我想用ImageMagick压缩JPG图像文件,但不能在大小上有太大差异.默认情况下,输出大小大于输入.我不知道为什么,但在添加一些+配置文件选项并设置质量后,我可以获得更小的尺寸,但仍然与原版相似.

输入图像为255kb,处理后的图像为264kb(使用+ profile删除配置文件,设置质量为70%).有没有办法将该图像压缩到150kb至少?那可能吗?我可以使用哪些ImageMagick选项?

imagemagick image-processing

218
推荐指数
10
解决办法
13万
查看次数

如何改善我的爪子检测?

在我之前关于在每个爪子中发现脚趾的问题之后,我开始加载其他测量值以查看它将如何保持.不幸的是,我很快就遇到了上述步骤之一的问题:识别爪子.

你看,我的概念证明基本上是随着时间推移每个传感器的最大压力,并开始寻找每一行的总和,直到它找到!= 0.0.然后它对列进行相同的操作,一旦找到超过2行,再次为零.它将最小和最大行和列值存储到某个索引.

替代文字

正如您在图中所看到的,这在大多数情况下都能很好地工作.但是,这种方法有许多缺点(除了非常原始):

  • 人类可以拥有"空心脚",这意味着足迹内部有几排空行.因为我担心这种情况也会发生在(大)狗身上,所以在切断爪子之前,我等待至少2或3个空行.

    如果在到达多个空行之前在另一列中创建另一个联系,则会产生问题,从而扩展该区域.我想我可以比较列,看看它们是否超过某个值,它们必须是单独的爪子.

  • 当狗很小或走得更快时,问题会变得更糟.发生的事情是,前爪的脚趾仍在接触,而后爪的脚趾刚刚开始与前爪在同一区域内接触!

    使用我的简单脚本,它将无法拆分这两个,因为它必须确定该区域的哪些帧属于哪个爪子,而目前我只需要查看所有帧的最大值.

它开始出错的例子:

替代文字 替代文字

所以现在我正在寻找一种更好的识别和分离爪子的方法(之后我将解决决定它是哪个爪子的问题!).

更新:

我一直在修补Joe的(真棒!)答案,但是我很难从我的文件中提取实际的爪子数据.

替代文字

当应用于最大压力图像时,coded_pa​​ws显示了所有不同的爪子(见上文).但是,解决方案遍历每个帧(以分隔重叠的爪子)并设置四个Rectangle属性,例如坐标或高度/宽度.

我无法弄清楚如何获取这些属性并将它们存储在一些我可以应用于测量数据的变量中.因为我需要知道每个爪子,它在哪个框架中的位置是什么,并将它连接到哪个爪子(前/后,左/右).

那么如何使用Rectangles属性为每个爪子提取这些值呢?

我在我的公共Dropbox文件夹中的问题设置中使用了测量值(示例1,示例2,示例3).对于任何有兴趣的人我也建立了一个博客,让你保持最新:-)

python image-processing

196
推荐指数
2
解决办法
1万
查看次数

有没有办法检测图像是否模糊?

我想知道是否有办法通过分析图像数据来确定图像是否模糊.

opencv image-processing

193
推荐指数
9
解决办法
13万
查看次数