Нахождение количества цветных фигур из картинки с использованием Python - PullRequest
13 голосов
/ 14 марта 2011

Моя проблема связана с распознаванием цветов по картинкам.Занимаясь микробиологией, мне нужно посчитать количество ядер клеток на снимке, сделанном камерой микроскопа.Я использовал GIMP, чтобы пометить ядра точками красного цвета.Теперь мне нужно сделать скрипт на python, который, учитывая изображение, скажет мне, сколько красных точек присутствует.На картинке нет красного, кроме точек.

Я подумал о довольно сложном решении, которое, вероятно, не самое лучшее: сделайте снимок и начните перебирать пиксели, проверяя цвет каждого из них.Если это красный, проверьте все 8 ближайших пикселей, рекурсивно проверяйте соседей каждого красного снова, пока больше не будет найдено соседних красных пикселей.Затем увеличьте число ядер на единицу и отметьте пройденные пиксели, чтобы они больше не повторялись.Затем продолжите итерацию с того места, где она остановилась.Кажется, тяжеловато, поэтому я подумал, что могу спросить, может быть, кто-то уже справился с подобной проблемой более элегантно.

С уважением, Сандер

Ответы [ 3 ]

13 голосов
/ 14 марта 2011

Количество ядер

Код, адаптированный из 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

3 голосов
/ 14 марта 2011

Я бы сделал это так:

  • использование OpenCV ( привязки Python ),
  • взять только R-компонент изображения RGB,
  • двоичный порог компонента R, так что он оставляет только самые красные пиксели,
  • использовать обнаружение некоторых объектов / объектов для обнаружения точек, например. ExtractSURF

Комментарии: это не будет самым быстрым, это не всегда будет точно. Но это будет весело, так как резюме всегда весело - и готово в 10 строк кода. Просто бесполезная мысль.

Что касается более готовых предложений:

  • на самом деле я думаю, что ваша идея очень хорошая, и ее можно распараллелить, если подумать;
  • использовать обнаружение BLOB-объектов в OpenCV ( cvBlobsLib ).

Но самым элегантным решением было бы просто подсчитать помеченные ядра в GIMP, как предложил Ocaso Protal выше. Точно и быстро. Все остальное будет подвержено ошибкам и намного медленнее, поэтому мои просто бесполезные идеи, более веселые, чем что-либо.

1 голос
/ 14 марта 2011

Простое решение 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'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...