6

===已解决===

感谢您的建议和意见。通过研究Beginning Python Visualization book(第9章-图像处理)中给出的flood_fill算法,我已经实现了我想要的。我可以计算对象,获取每个对象的封闭矩形(因此是高度和宽度),最后可以为每个对象构造 NumPy 数组或矩阵。

尽管它不是一种优化的方法,但它可以满足我的要求。我使用的源代码 (lab2.py) 和 png 文件 (lab2-particles.png) 已放在http://code.google.com/p/ccnworks/source/browse/#svn/trunk/AtSc450下.

您需要安装 NumPy 和 PIL,并使用 matplotlib 来查看直方图。代码的核心位于发生主要递归对象搜索操作的 objfind 函数中。

进一步更新:

SciPy 的ndimage.label()也完全符合我的要求。

为 NumPy 和 SciPy 邮件列表中的David-Warde FarleyZachary Pincus欢呼,因为他们将这一点指向了我的眼睛 :)

==============

你好,

我有一张图像,其中包含由粒子光谱仪测量的冰粒子的阴影。我希望能够识别每个对象,以便以后可以在计算中进一步分类和使用它们。

本质上,我愿意做的是简单地实现一个模糊选择工具,我可以简单地选择每个实体。

我怎样才能轻松解决这个问题?(最好使用 Python)

谢谢。

注意:在我的问题中,我将每个特定的连接像素称为对象或实体。我打算提取它们并创建 NumPy 数组表示,如下所示。(这里我使用左上角的对象;如果存在像素,则使用 1,如果不使用 0。该对象的形状是 3 x 3,对应的 3 像素高 x 3 像素宽。这些是真实冰粒子在 2D 域上的投影, 在它们是球形的假设下,等效半径是 (height+width)/2, 后来一些缩放——从像素到实际大小和体积计算将随之而来)

import numpy as np

np.array([[1,1,1], [1,1,1], [0,0,1]])

array([[1, 1, 1],
       [1, 1, 1],
       [0, 0, 1]])

这是我将要使用的图像的一部分。

截图 http://img43.imageshack.us/img43/2327/particles.png

4

5 回答 5

5
  1. 扫描每个正方形(例如从左上角、从左到右、从上到下)

  2. 当你击中一个蓝色方块时:

    一个。将此方格记录为新对象的位置

    湾。找到所有其他相邻的蓝色方块(例如,通过查看这个方块的邻居,以及这些邻居的邻居等)并将它们标记为同一对象的一部分

  3. 继续扫描

  4. 当你找到另一个蓝色方块时,在进行第 2 步之前测试它是否是已知对象的一部分;或者在步骤 2b 中,将任何方块与对象关联后擦除它

于 2009-09-19T18:29:19.207 回答
3

查看您提供的图像,您接下来需要做的就是应用一个简单的区域增长算法

如果我使用 MATLAB,我会使用bwlabel / bwboundaries函数。我相信在Numpy的某个地方有一个等效的函数,或者按照@kwatford 的建议将OpenCV与 python 包装器一起使用

于 2009-09-19T18:31:15.007 回答
3

我曾经对显微照片进行这种分析,最终将我需要的所有东西都放入了一个用 C 语言编写的、通过 Tcl 驱动的图像处理和分析包中。(它只适用于 512 x 512 的图像,这解释了为什么 512 如此频繁地出现。分配了各种大小的像素的图像,但大部分工作都是用 8 位像素完成的,这解释了为什么会有这样的业务0xff 和图像上的最大有意义计数 254。)

简而言之,Tcl 命令开头的“zz”将行的剩余部分发送到包的解析器,该解析器使用给定的参数调用适当的 C 例程。'zz' 之后是一个参数,指示命令的输入和输出。(可以有多个输入,但只有一个输出。)“r”表示 512 x 512 x 8 位图像。第三个词是要调用的命令的名称;'graphs' 标记图像,如下文所述。所以,“zz rr graphs”的意思是“调用 ZZ 解析器;将 r 图像输入到 graphs 命令并取回 r 图像。Tcl 命令行的其余部分指定使用哪个预分配的映像。('g' 图像是一个 ROI,即感兴趣区域图像;几乎所有 ZZ 操作都是在 ROI 控制下完成的。)所以,'

我不认为它在任何地方都可以在线获得,但如果你想通过源代码挑选甚至编译整个 shebang,我很乐意将它发送给你。这是手册的摘录(但我想我在这么晚的时候在手册中看到了一些错误 --- 这很尴尬......):

示例 6. 计数特征。

问题

计数是一项常见的任务。计数的项目称为“特征”,通常需要仔细准备图像,使特征与要计数的真实对象一一对应。然而,在这里,我们忽略了图像准备,而是考虑了计数的机制。第一个计数练习是找出 ./cells 目录中的图像上有多少特征?

方法

首先,让我们定义“特征”。特征是最大的一组“集合”(非零)像素,所有这些像素都可以通过从一个集合像素沿北-南-东-西(上-下-右-左)路线行进到另一个集合像素,开始从给定的集合像素。在图像上检测和标记此类特征的 zz 命令是“zz rr graphs R:src R:dest G:ROI”,之所以这么称呼是因为此类特征的数学术语是“图形”。如果设置了图像上的所有像素,则图像上只有一个图形,但它包含 262144 个像素(512 * 512)。如果像素在棋盘图案中设置并清除(等于零),则将有 131072 (512 * 512 / 2) 个图形,但每个图形仅包含一个像素。简要说明,“zz rr graphs”从图像的左上角开始,从左到右扫描随后的每一行,直到找到一个集合像素,然后找到通过北、南、东或西边界连接到该像素的所有集合像素( “4 连接”)。然后它将该图中的所有像素设置为 1 (0x01)。找到并标记图 1 后,它会在第一次发现图 1 之后的像素处再次开始扫描,这一次忽略任何已经属于图的像素。它找到的前 254 个图形将被唯一标记;但是,此后找到的所有图形都将标有值 255 (0xff),因此无法相互区分。能够准确统计任意数量的图的关键是对每张图像进行分阶段处理,即求一张图像上的图的数量,如果数量大于254,擦除刚刚找到的 254 个图形,重复该过程直到找到 254 个或更少的图形。Tcl 语言提供了设置对这个操作的控制的方法。

让我们开始构建所需的命令,将 ZZ 图像文件读入 R 图像并检测和标记图形。在处理循环之前,我们声明一个变量并将其归零以保存图像系列中的特征总数。在处理循环中,我们首先将图像文件读入 R 图像并检测和标记图形。

zz ur to $inDir/$img r1
zz rr graphs r1 r1 g8

接下来,我们将一些变量归零以跟踪计数,然后使用“ra max”命令来确定是否检测到超过 254 个图。

set nGraphs [ zz ra max r1 a1 g1 ]

如果 nGraphs 确实等于 255,则应将 254 个准确计数的图形添加到总数中,应删除从 1 到 254 的图形,并重复计数以将图形数量减少到 255 以下。

while {$nGraphs == 255} {
  incr sumGraphs 254
  zz rbr lt r1 155 r1 g1 0 255 
  set sumGraphs 0
  zz rr graphs r1 r1 g8
  set nGraphs [ zz ra max r1 a1 g8 ]
}

当“while”循环退出时,变量 nGraphs 必须保存一个小于 255 的数字,即精确计数的图的数量;这被添加到图像系列中不断增加的特征总数中。

incr sumGraphs $nGraphs

在处理循环之后,打印出系列中找到的特征总数。

puts “Total number of features in $inDir \
images $beginImg through $endImg is $sumGraphs.”

在处理循环之后,打印出系列中找到的特征总数。

于 2009-09-20T14:27:17.210 回答
2

OpenCV有一个 Python 接口,您可能会发现它很有用。

于 2009-09-19T18:23:26.387 回答
2

连接组件分析可能是您正在寻找的。

于 2009-09-20T14:32:23.273 回答