【问题标题】:How to segment blood vessels python opencv如何分割血管python opencv
【发布时间】:2016-07-15 18:48:13
【问题描述】:

我正在尝试使用 Python 和 OpenCV 分割视网膜图像中的血管。这是原图:

理想情况下,我希望所有血管都像这样非常明显(不同的图像):

这是我到目前为止所尝试的。我取了图像的绿色通道。

img = cv2.imread('images/HealthyEyeFundus.jpg')
b,g,r = cv2.split(img)

然后我尝试按照this article 创建匹配过滤器,这就是输出图像:

然后我尝试做最大熵阈值:

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)

这是我得到的结果,显然没有显示所有血管:

我还尝试获取图像的匹配过滤器版本并获取其 sobel 值的大小。

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)

这使得容器弹出更多:

然后我尝试了 Otsu 阈值:

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 没有给出足够的结果。它最终会在结果中包含噪音:

感谢任何关于我如何成功分割血管的帮助。

【问题讨论】:

    标签: python image opencv computer-vision edge-detection


    【解决方案1】:

    几年前我从事视网膜血管检测工作,有不同的方法可以做到:

    • 如果您不需要最高结果但需要快速的结果,您可以使用定向开口,see herehere
    • 那么你有另一个使用数学形态学的版本version here

    为了获得更好的结果,这里有一些想法:

    【讨论】:

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