Есть ли способ изменить алгоритм сегментации водораздела, используя python - PullRequest
0 голосов
/ 18 февраля 2020

Мой основной проект заключается в обнаружении свойств зерен почвы (Площадь), включенных в изображение, как показано ниже, однако моя основная проблема в сегментации зерен почвы на изображении, поэтому я установил следующий код, используя пакет scipy в python и это дает хорошую сегментацию на изображениях, обнаруженных по краям, с использованием алгоритма HED в большинстве случаев, однако я столкнулся с некоторыми проблемами в изображениях, как показано ниже, где маркеры, из которых перемещается сегментация водораздела, собирают более одного зерна в одну единицу, поэтому я хотел бы знать как изменить мой код, чтобы избежать или минимизировать эти ошибки, обнаруженные в изображении, чтобы получить лучшие результаты. Мой второй вопрос - случайная сегментация Уокера будет эффективной в этом случае. Заранее спасибо . enter image description here

enter image description here

import cv2
import numpy as np
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
import math
import random as rand
import xlwt
import matplotlib.pyplot as plt
path = 'D:\My work\image.jpg'
image = cv2.imread('path')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+ cv2.THRESH_OTSU)[1]
thresh=thresh/255
distance_map = ndimage.distance_transform_edt(thresh)
local_max = peak_local_max(distance_map, indices=False, min_distance=20, labels=thresh)
# Perform connected component analysis then apply Watershed
markers = ndimage.label(local_max, structure=np.ones((3, 3)))[0]
labels = watershed(-distance_map, markers, mask=thresh)
# Iterate through unique labels
n = 0
Areas = []
for label in np.unique(labels):
    if label == 0:
        continue
    # Create a mask
    mask = np.zeros(gray.shape, dtype="uint8")
    mask[labels == label] = 255

    # Find contours and determine contour area
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    c = max(cnts, key=cv2.contourArea)
    area = cv2.contourArea(c)
    Areas.append(area)
    n+=1
    print('Grain particle' ,'of number ' , n , 'has area = ',area)
    # total_area += area
    if n < 100:
        cv2.drawContours(image,[c],-1,(rand.randint(0,255),rand.randint(0,250),rand.randint(10,255)),-1)
    if n > 100 and n < 200:
        cv2.drawContours(image,[c],-1,(rand.randint(0,200),rand.randint(0,166),rand.randint(120,250)),-1)
    if n > 200 and n < 300:
        cv2.drawContours(image, [c], -1,(rand.randint(0,160),rand.randint(0,200),rand.randint(0,255)), -1)
    if n > 300 and n < 400:
        cv2.drawContours(image, [c], -1, (rand.randint(0,110),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 400 and n < 500:
        cv2.drawContours(image, [c], -1, (rand.randint(0,220),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 500 and n < 600:
        cv2.drawContours(image, [c], -1, (rand.randint(0,220),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 600 and n < 700:
        cv2.drawContours(image, [c], -1, (rand.randint(0,210),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 700 and n < 800:
        cv2.drawContours(image, [c], -1, (rand.randint(0,255),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 800 and n < 900:
        cv2.drawContours(image, [c], -1, (rand.randint(0,255),rand.randint(0,255),rand.randint(0,250)), -1)
    if n > 800 and n < 900:
        cv2.drawContours(image, [c], -1, (rand.randint(0, 255), rand.randint(0, 255), rand.randint(0, 250)), -1)
    if n > 900:
        cv2.drawContours(image, [c], -1, (rand.randint(0, 255), rand.randint(0, 255), rand.randint(0, 250)), -1)
cv2.imshow('result',image)
cv2.waitkey(0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...