Подсчет частиц с использованием обработки изображений в PythonPython

Программы на Python
Ответить
Anonymous
 Подсчет частиц с использованием обработки изображений в Python

Сообщение Anonymous »

Существует ли какой-нибудь хороший алгоритм для обнаружения частиц на изменяющейся интенсивности фона?
Например, если у меня есть следующее изображение:

Изображение


Есть ли способ подсчитать маленькие белые частицы, даже с явно отличающимся фоном, который появляется ближе к левому нижнему углу?

Чтобы внести немного большей ясности, я хотел бы пометить изображение и подсчитать частицы с помощью алгоритма, который считает эти частицы значимыми:

Изображение


Я пробовал много вещей с PIL, cv , scipy , numpy и т. д. модули.
Я получил несколько подсказок из этого очень похожего вопроса SO, и на первый взгляд кажется, что вы можете использовать такой простой порог:

Код: Выделить всё

im = mahotas.imread('particles.jpg')
T = mahotas.thresholding.otsu(im)

labeled, nr_objects = ndimage.label(im>T)
print nr_objects
pylab.imshow(labeled)
но из-за меняющегося фона вы получаете вот это:
Изображение


Я также пробовал другие идеи, например найденный мной метод измерения лап, который я реализовал следующим образом:

Код: Выделить всё

import numpy as np
import scipy
import pylab
import pymorph
import mahotas
from scipy import ndimage
import cv

def detect_peaks(image):
"""
Takes an image and detect the peaks usingthe local maximum filter.
Returns a boolean mask of the peaks (i.e.  1 when
the pixel's value is the neighborhood maximum, 0 otherwise)
"""

# define an 8-connected neighborhood
neighborhood = ndimage.morphology.generate_binary_structure(2,2)

#apply the local maximum filter; all pixel of maximal value
#in their neighborhood are set to 1
local_max = ndimage.filters.maximum_filter(image, footprint=neighborhood)==image
#local_max is a mask that contains the peaks we are
#looking for, but also the background.
#In order to isolate the peaks we must remove the background from the mask.

#we create the mask of the background
background = (image==0)

#a little technicality: we must erode the background in order to
#successfully subtract it form local_max, otherwise a line will
#appear along the background border (artifact of the local maximum filter)
eroded_background = ndimage.morphology.binary_erosion(background, structure=neighborhood, border_value=1)

#we obtain the final mask, containing only peaks,
#by removing the background from the local_max mask
detected_peaks = local_max - eroded_background

return detected_peaks

im = mahotas.imread('particles.jpg')
imf = ndimage.gaussian_filter(im, 3)
#rmax = pymorph.regmax(imf)
detected_peaks = detect_peaks(imf)
pylab.imshow(pymorph.overlay(im, detected_peaks))
pylab.show()
но и это не дает результатов, показывая такой результат:

Изображение


Используя функцию регионального максимума, я получаю изображения, которые почти точно дают правильную идентификацию частиц, но их либо слишком много, либо слишком мало частиц в неправильных местах в зависимости от моей гауссовской фильтрации (изображения имеют гауссов фильтр 2,3 и 4):

Изображение
Изображение
Изображение


Кроме того, необходимо будет работать и с изображениями, подобными этому:

Изображение


Это изображение того же типа, что и выше, только с гораздо более высокой плотностью частиц.

РЕДАКТИРОВАНИЕ: Решенное решение: Мне удалось получить достойное рабочее решение этой проблемы, используя следующий код:

Код: Выделить всё

import cv2
import pylab
from scipy import ndimage

im = cv2.imread('particles.jpg')
pylab.figure(0)
pylab.imshow(im)

gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5,5), 0)
maxValue = 255
adaptiveMethod = cv2.ADAPTIVE_THRESH_GAUSSIAN_C#cv2.ADAPTIVE_THRESH_MEAN_C #cv2.ADAPTIVE_THRESH_GAUSSIAN_C
thresholdType = cv2.THRESH_BINARY#cv2.THRESH_BINARY #cv2.THRESH_BINARY_INV
blockSize = 5 #odd number like 3,5,7,9,11
C = -3 # constant to be subtracted
im_thresholded = cv2.adaptiveThreshold(gray, maxValue, adaptiveMethod, thresholdType, blockSize, C)
labelarray, particle_count = ndimage.measurements.label(im_thresholded)
print particle_count
pylab.figure(1)
pylab.imshow(im_thresholded)
pylab.show()
Это покажет изображения следующим образом:

Изображение
(это данное изображение)

и

Изображение


(это подсчитанное количество частиц)

и вычислите количество частиц как 60.

Подробнее здесь: https://stackoverflow.com/questions/161 ... -in-python
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»