使用Python从图片中找到彩色形状的数量

15 投票
3 回答
18359 浏览
提问于 2025-04-16 13:39

我的问题是关于从图片中识别颜色的。在做微生物学的时候,我需要计算在显微镜拍摄的图片中有多少个细胞核。我用GIMP给细胞核标记了红色的点。现在我想写一个Python脚本,给定一张图片,能告诉我有多少个红点。图片中除了这些点没有其他红色。

我想到了一个比较复杂的解决方案,可能不是最好的:拍一张照片,然后开始逐个检查每个像素的颜色。如果是红色,就检查它周围8个最近的像素,再递归地检查每个红色像素的邻居,直到找不到更多的红色像素为止。然后细胞核的计数加一,并标记已经检查过的像素,以免再次检查。接着从停止的地方继续检查。这个方法感觉有点繁琐,所以我想问问,可能有人已经用更优雅的方法解决过类似的问题。

祝好,
Sander

3 个回答

2

一个简单的 Numpy / Scipy 解决方案可以是这样的:

import numpy, scipy
a = scipy.misc.imread("rgb.jpg") # Imports RGB to numpy array where a[0] is red, a[1] is blue, a[2] is green...
num_red = numpy.sum((a[:,:,0] == 255) * (a[:,:,1] == 0) * (a[:,:,2] == 0)) # Counts the number of pure red pixels

你也可以用 PIL 来读取图片。

补充说明:根据评论的内容,scipy.ndimage.measurements.label 会很有用,它还会返回一个值 num_features,这个值可以告诉你有多少个特征:

import numpy, scipy
from scipy import ndimage
a = scipy.misc.imread("rgb.jpg")
b = ((a[:,:,0] == 255) * (a[:,:,1] == 0) * (a[:,:,2] == 0))*1
labeled_array, num_features = scipy.ndimage.measurements.label(b.astype('Int8'))
4

我会这样做:

  • 使用OpenCVPython绑定),
  • 只取RGB图像中的红色部分,
  • 对红色部分进行二值化处理,这样只留下最红的像素,
  • 使用一些物体或特征检测的方法来找到这些点,比如ExtractSURF。

评论:这方法可能不是最快的,也不一定总是准确。 但做这个会很有趣——因为计算机视觉总是很有趣——而且只需要10行代码。只是一个随意的想法。

至于更适合实际应用的建议:

  • 其实我觉得你的想法很好,如果认真考虑的话,可以进行并行处理;
  • 在OpenCV中使用斑点检测(cvBlobsLib)。

但最优雅的解决方案就是在GIMP中计算标记的细胞核,正如Ocaso Protal上面提到的那样。这样既准确又快。其他方法容易出错,而且慢得多,所以我说的只是一些随意的想法,更多的是为了好玩。

16

计算细胞核数量

这段代码是从Python图像教程中改编而来的。下面是教程中输入的带有细胞核的图像:

细胞核

#!/usr/bin/env python
import scipy
from scipy import ndimage

# read image into numpy array
# $ wget http://pythonvision.org/media/files/images/dna.jpeg
dna = scipy.misc.imread('dna.jpeg') # gray-scale image


# smooth the image (to remove small objects); set the threshold
dnaf = ndimage.gaussian_filter(dna, 16)
T = 25 # set threshold by hand to avoid installing `mahotas` or
       # `scipy.stsci.image` dependencies that have threshold() functions

# find connected components
labeled, nr_objects = ndimage.label(dnaf > T) # `dna[:,:,0]>T` for red-dot case
print "Number of objects is %d " % nr_objects

# show labeled image
####scipy.misc.imsave('labeled_dna.png', labeled)
####scipy.misc.imshow(labeled) # black&white image
import matplotlib.pyplot as plt
plt.imsave('labeled_dna.png', labeled)
plt.imshow(labeled)

plt.show()

输出结果

Number of objects is 17 

标记的细胞核

撰写回答