Подсчет ячеек в изображении с ненужными функциями - PullRequest
0 голосов
/ 21 марта 2020

Я хотел бы посчитать ячейки и коллонии клеток на изображении (показано в ссылке). Он имеет одну ячейку примерно в 3 часа и колонию / блоб ячейки примерно в 8 часов.

Я пытался работать с пакетом cv2:

import cv2
import numpy as np
import math

image = cv2.imread("C:\\Users\\Tadas\\Desktop\\img-r.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret,th = cv2.threshold(image,155,255,cv2.THRESH_BINARY)
cnts,_ = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

minimum_area = 10
average_cell_area = 14
connected_cell_area = 30
large_collony = 100

cells = 0
cells_individual=0
collonies=0

for c in cnts:
    area = cv2.contourArea(c)
    if area > minimum_area:
        cv2.drawContours(th, [c], -1, (255,2,1), 1)
        if area > connected_cell_area:
            cells += math.ceil(area / average_cell_area)
            if area > large_collony:
                collonies += 1
        else:
            cells += 1
            cells_individual +=1
print('Cells: {}'.format(cells))
print('Individual cells: {}'.format(cells_individual))
print('Collonies: {}'.format(collonies))
th=cv2.resize(th,(819,819))
cv2.imshow('image', th)
cv2.waitKey()

И это несколько работает, если я обрежу клетки из этой картины. Как я мог игнорировать это? А может быть, есть лучший способ фильтрации изображения, чем пороговое значение? Спасибо за помощь!

cell image Одиночная ячейка около 3 часов и колония / капля клеток около 8:00.

1 Ответ

2 голосов
/ 22 марта 2020

Я бы предложил использовать адаптивный порог в Python / OpenCV следующим образом:

import cv2
import numpy as np
import math

# read image
image = cv2.imread("C:\\Users\\Tadas\\Desktop\\img-r.jpg")

# convert to grayscale
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# apply adaptive thresholding and invert
th = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 55, 30)
th = 255 - th

# remove everything outside radius from center using a circle mask
radius = 1900
hh, ww = image.shape[:2]
cx = ww // 2
cy = hh // 2
mask = np.zeros_like(th)
cv2.circle(mask, (cx,cy), radius, 255, -1)
th[mask==0] = 0

# get contours
cnts = cv2.findContours(th, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

minimum_area = 10
average_cell_area = 14
connected_cell_area = 30
large_collony = 100


cells = 0
cells_individual=0
collonies=0

# filter contours
for c in cnts:
    area = cv2.contourArea(c)
    if area > minimum_area:
        cv2.drawContours(th, [c], -1, (255,2,1), 1)
        if area > connected_cell_area:
            cells += math.ceil(area / average_cell_area)
            if area > large_collony:
                collonies += 1
        else:
            cells += 1
            cells_individual +=1

# report cells
print('Cells: {}'.format(cells))
print('Individual cells: {}'.format(cells_individual))
print('Collonies: {}'.format(collonies))
th=cv2.resize(th,(819,819))
cv2.imshow('image', th)
cv2.waitKey()


Полученные результаты:

Cells: 25
Individual cells: 1
Collonies: 1


...