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

时间:2011-03-14 13:00:09

标签: python image-processing

我的问题与识别图片中的颜色有关。做微生物学我需要计算用显微镜照相机拍摄的照片上存在的细胞核数量。我用GIMP用红色点标记原子核。现在我需要在python中创建一个脚本,给出一个图像,它会告诉我有多少个红点。除了点之外,图片中没有红色。

我想到了一个相当复杂的解决方案,可能不是最好的解决方案:拍照并开始迭代检查每个颜色的像素。如果是红色,请检查所有8个最近的像素,再次递归检查每个红色的邻居,直到找不到更多相邻的红色像素。然后将核数增加1并标记遍历的像素,这样它们就不会再次迭代。然后从停止的地方继续迭代。看起来有点沉重所以我想我会问,也许有人已经更优雅地处理了类似的问题。

此致 桑德

3 个答案:

答案 0 :(得分:13)

计数细胞核

代码改编自Python Image Tutorial。使用教程中的核输入图像:

nuclei

#!/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 

labeled nuclei

答案 1 :(得分:3)

我会这样做:

  • 使用OpenCVpython bindings),
  • 仅拍摄RGB图像的R分量,
  • 二进制阈值R组件,因此它只留下最红的像素,
  • 使用一些物体/特征检测来检测点,fe。 ExtractSURF

评论: 它不会是最快的,也不会总是准确的。 但这样做很有趣 - 因为简历总是很有趣 - 并准备好10行代码。只是一个松散的想法。

关于更多可用于生产的建议:

  • 实际上我认为你的想法非常好,如果考虑一下,它可以并行化;
  • 在OpenCV中使用blob检测(cvBlobsLib)。

但最优雅的解决方案就是计算GIMP中标记的核,正如Ocaso Protal上面提到的那样。准确,快速。其他所有东西都会容易出错并且速度慢得多,因此我只是松散的想法,比任何事情都更有趣。

答案 2 :(得分:1)

一个简单的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'))