Поиск количества цветных фигур с помощью Python
Моя проблема связана с распознаванием цветов из изображений. Выполняя микробиологию, мне нужно подсчитать количество ячеек клеток, присутствующих на снимке, сделанном с помощью камеры микроскопа. Я использовал GIMP для маркировки ядер красными точками. Теперь мне нужно сделать script в python, который, учитывая изображение, скажет мне, сколько красных точек присутствует. На картинке нет красных изображений, кроме точек.
Я подумал о довольно сложном решении, которое, вероятно, не самое лучшее: сделайте снимок и начните повторять через пиксели, проверяя каждый цвет. Если это красный цвет, проверьте все 8 ближайших пикселей, рекурсивно проверьте каждый красный сосед, пока не будут найдены более соседние красные пиксели. Затем увеличивайте количество ядер на единицу и отметьте пройденные пиксели, чтобы они не повторялись снова. Затем продолжите итерацию с того места, где она остановилась. Кажется, это тяжело, поэтому я подумал, что спрошу, может, кто-то уже более разбирался в подобной проблеме.
С уважением,
Sander
Ответы
Ответ 1
Число ядер
Код, адаптированный из 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]()
Ответ 2
Я бы сделал это следующим образом:
- используйте OpenCV (python привязок),
- возьмите только R-компонент изображения RGB,
- бинарный порог компонента R, так что он оставляет только красные пиксели,
- использовать обнаружение объектов/признаков для обнаружения точек, fe. ExtractSURF
Комментарии:
он будет не самым быстрым, он не всегда будет точным.
Но это будет весело, так как CV всегда весело - и готово в 10 строках кода. Просто сообразительная мысль.
Что касается более готовых к выпуску предложений:
- На самом деле, я думаю, что ваша идея очень хорошая, и она может быть распараллелирована, если дать какую-то мысль;
- используйте обнаружение blob в OpenCV (cvBlobsLib).
Но самым изящным решением было бы просто подсчитать помеченные ядра в GIMP, как предложил Ocaso Protal выше. Точный и быстрый. Все остальное будет подвержено ошибкам и намного медленнее, поэтому мои просто свободные идеи, больше удовольствия, чем что-либо.
Ответ 3
Простое решение 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 для чтения изображения.
EDIT: В свете комментариев 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'))