【问题标题】:Vessel segmentation in retina image视网膜图像中的血管分割
【发布时间】:2020-06-03 03:05:33
【问题描述】:

我正在尝试在视网膜图像中追踪血管。目前我正在使用 cv2 的阈值函数来使血管与周围的视网膜形成更多对比:

from matplotlib import pyplot as plt
import cv2

img = cv2.imread('misc images/eye.jpeg',0)
img = cv2.medianBlur(img,5)

ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)

titles = ['Original Image', 'Global Thresholding (v = 127)',
            'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]

for i in range(4):
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

结果如下:

所有 3 种方法仍然有来自视网膜其余部分的大量背景噪音。如何提高血管追踪的准确性?

【问题讨论】:

    标签: python opencv computer-vision


    【解决方案1】:

    这是另一种使用除法归一化然后对轮廓区域进行过滤来对图像进行阈值处理的方法。

    • 读取输入
    • 转换为灰色
    • 应用形态扩张(或应用 gaussianBlur)
    • 将输入除以扩展结果
    • 阈值
    • 倒置,使容器在黑底白字
    • 查找所有轮廓
    • 过滤轮廓以丢弃太小的轮廓
    • 在黑色图像上以白色绘制剩余轮廓作为蒙版
    • 将蒙版应用于阈值图像作为第一个结果
    • 将掩码应用于输入作为第二个结果
    • 保存结果


    输入

    import cv2
    import numpy as np
    
    # read the image
    img = cv2.imread('retina_eye.jpg')
    
    # convert to gray
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    # apply morphology
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (5,5))
    morph = cv2.morphologyEx(gray, cv2.MORPH_DILATE, kernel)
    
    # divide gray by morphology image
    division = cv2.divide(gray, morph, scale=255)
    
    # threshold
    thresh = cv2.threshold(division, 0, 255, cv2.THRESH_OTSU )[1] 
    
    # invert
    thresh = 255 - thresh
    
    # find contours and discard contours with small areas
    mask = np.zeros_like(thresh)
    contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    
    area_thresh = 10000
    for cntr in contours:
        area = cv2.contourArea(cntr)
        if area > area_thresh:
            cv2.drawContours(mask, [cntr], -1, 255, 2)
    
    # apply mask to thresh
    result1 = cv2.bitwise_and(thresh, mask)
    mask = cv2.merge([mask,mask,mask])
    result2 = cv2.bitwise_and(img, mask)
    
    # save results
    cv2.imwrite('retina_eye_division.jpg',division)
    cv2.imwrite('retina_eye_thresh.jpg',thresh)
    cv2.imwrite('retina_eye_mask.jpg',mask)
    cv2.imwrite('retina_eye_result1.jpg',result1)
    cv2.imwrite('retina_eye_result2.jpg',result2)
    
    # show results
    cv2.imshow('morph', morph)  
    cv2.imshow('division', division)  
    cv2.imshow('thresh', thresh)  
    cv2.imshow('mask', mask)  
    cv2.imshow('result1', result1)  
    cv2.imshow('result2', result2)  
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    


    分区图:

    阈值图像:

    面具图片:

    结果 1:

    结果 2:

    【讨论】:

      猜你喜欢
      • 2020-10-16
      • 1970-01-01
      • 2013-11-03
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多