Tôi đang cố gắng phân đoạn các mạch máu trong hình ảnh võng mạc bằng cách sử dụng Python và OpenCV. Dưới đây là hình ảnh ban đầu:Làm thế nào để phân đoạn mạch máu python opencv
Lý tưởng nhất là tôi muốn tất cả các mạch máu là rất rõ ràng như thế này (hình ảnh khác nhau):
Dưới đây là những gì tôi đã cố gắng cho đến nay . Tôi lấy kênh màu xanh lục của hình ảnh.
img = cv2.imread('images/HealthyEyeFundus.jpg')
b,g,r = cv2.split(img)
Sau đó, tôi đã cố gắng để tạo ra một bộ lọc phù hợp bằng cách làm theo this article và đây là những gì hình ảnh đầu ra là:
Sau đó, tôi đã cố gắng làm tối đa entropy ngưỡng:
def max_entropy(data):
# calculate CDF (cumulative density function)
cdf = data.astype(np.float).cumsum()
# find histogram's nonzero area
valid_idx = np.nonzero(data)[0]
first_bin = valid_idx[0]
last_bin = valid_idx[-1]
# initialize search for maximum
max_ent, threshold = 0, 0
for it in range(first_bin, last_bin + 1):
# Background (dark)
hist_range = data[:it + 1]
hist_range = hist_range[hist_range != 0]/cdf[it] # normalize within selected range & remove all 0 elements
tot_ent = -np.sum(hist_range * np.log(hist_range)) # background entropy
# Foreground/Object (bright)
hist_range = data[it + 1:]
# normalize within selected range & remove all 0 elements
hist_range = hist_range[hist_range != 0]/(cdf[last_bin] - cdf[it])
tot_ent -= np.sum(hist_range * np.log(hist_range)) # accumulate object entropy
# find max
if tot_ent > max_ent:
max_ent, threshold = tot_ent, it
return threshold
img = skimage.io.imread('image.jpg')
# obtain histogram
hist = np.histogram(img, bins=256, range=(0, 256))[0]
# get threshold
th = max_entropy.max_entropy(hist)
print th
ret,th1 = cv2.threshold(img,th,255,cv2.THRESH_BINARY)
Đây là kết quả tôi nhận được, rõ ràng là không hiển thị tất cả các mạch máu:
Tôi cũng đã thử chụp phiên bản bộ lọc phù hợp của hình ảnh và lấy độ lớn các giá trị sobel của nó.
img0 = cv2.imread('image.jpg',0)
sobelx = cv2.Sobel(img0,cv2.CV_64F,1,0,ksize=5) # x
sobely = cv2.Sobel(img0,cv2.CV_64F,0,1,ksize=5) # y
magnitude = np.sqrt(sobelx**2+sobely**2)
Điều này làm cho các mạch máu bật ra hơn:
Sau đó, tôi đã cố gắng Otsu ngưỡng trên nó:
img0 = cv2.imread('image.jpg',0)
# # Otsu's thresholding
ret2,th2 = cv2.threshold(img0,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img0,(9,9),5)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
one = Image.fromarray(th2).show()
one = Image.fromarray(th3).show()
Otsu không cho kết quả đầy đủ. Nó kết thúc bao gồm tiếng ồn trong các kết quả:
Any help is appreciated về cách tôi có thể phân khúc các mạch máu thành công.