在python中使用分水岭分割时遇到问题

2024-06-08 16:42:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用此算法分割图像中显示的土壤颗粒时遇到困难,但是它将所有颗粒作为一个对象并计算其面积,但这不是我的愿望,因为我希望将每个颗粒单独分割,因此我可以修改以下算法以增强其检测每个颗粒的性能个别地

第二幅图像是使用该算法的结果

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

# Load in image, convert to gray scale, and Otsu's threshold
image = cv2.imread('sample64pxfor1mm.jpg')
image = cv2.bilateralFilter(image,15,75,75)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
image = cv2.morphologyEx(image,cv2.MORPH_CLOSE,kernel)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cv2.imshow('thresh',thresh)
cv2.waitKey(0)

# Compute Euclidean distance from every binary pixel
# to the nearest zero pixel then find peaks
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
total_area = []
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)
    total_area.append(area)
    n+=1
    print('Grain number' , ' of number ' , n , ' has area = ', area)
    # total_area += area
    cv2.drawContours(image, [c], -1, (36,255,12), 3)
cv2.imshow('image',image)
cv2.waitKey(0)

Tags: fromimageimportlabelslocalnpmaskarea