眼底血管形态学阈值分割

眼底血管形态学阈值分割_第1张图片

 

import numpy as np
import cv2, os

def CVShow(img, title = 'unNamed', max_h = 950, max_w = 1800):
    img = np.array(img)
    cv2.namedWindow(title, cv2.WINDOW_KEEPRATIO)
    H,W = img.shape[:2]
    if H > max_h:
        ratio = max_h / H
        H, W = int(ratio * H), int(ratio * W)
    if W > max_w :
        ratio = max_w / W
        H, W = int(ratio * H), int(ratio * W)
    cv2.resizeWindow(title, W, H)
    cv2.imshow(title, img)  # 自动适应图片大小的,不能缩放
    key = cv2.waitKey(0)
    if key == ord('s'):  # wait for key to write or exit
        cv2.imwrite(title+'.jpg', img)
    cv2.destroyAllWindows()
    return key

def Access_e_ophtha_MA(rootpath):
    subdirs, imgpaths = os.listdir(rootpath), []
    for subdir in subdirs:  # 访问子文件夹
        subdirpath = os.path.join(rootpath, subdir)
        imgnames = os.listdir(subdirpath)
        if 'Thumbs.db' in imgnames:imgnames.remove('Thumbs.db')
        for name in imgnames:  # 访问子文件夹下的图片
            imgpaths.append((os.path.join(subdirpath, name), name))
    return imgpaths

def enhance(img):
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    return clahe.apply(img)

def Morph_Operate(img):
    r1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)), iterations=1)
    R1 = cv2.morphologyEx(r1, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)), iterations=1)
    r2 = cv2.morphologyEx(R1, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)), iterations=1)
    R2 = cv2.morphologyEx(r2, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)), iterations=1)
    r3 = cv2.morphologyEx(R2, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (23, 23)), iterations=1)
    R3 = cv2.morphologyEx(r3, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (23, 23)), iterations=1)
    return R3

def Vessels_Mask(f5):
    ret, f6 = cv2.threshold(f5, 15, 255, cv2.THRESH_BINARY)  # 用来计算 mask
    # f7 = cv2.morphologyEx(f6, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)), iterations=1)
    mask = np.ones(f5.shape[:2], dtype="uint8") * 255
    _, contours, hierarchy = cv2.findContours(f6, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        if cv2.contourArea(cnt) <= 200:
            cv2.drawContours(mask, [cnt], -1, 0, -1)
    im = cv2.bitwise_and(f5, f5, mask=mask)
    ret, fin = cv2.threshold(im, 15, 255, cv2.THRESH_BINARY_INV)
    newfin = cv2.erode(fin, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=1)
    return newfin

def Vessels_Extract(newfin):
    fundus_eroded = cv2.bitwise_not(newfin)
    xmask = np.ones(fundus_eroded.shape[:2], dtype="uint8") * 255
    _, xcontours, xhierarchy = cv2.findContours(fundus_eroded.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    for cnt in xcontours:
        shape = "unidentified"
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.04 * peri, False)
        condition = len(approx) > 4 and cv2.contourArea(cnt) <= 3000 and cv2.contourArea(cnt) >= 100
        shape = "circle" if condition else "veins"
        if shape == "circle": cv2.drawContours(xmask, [cnt], -1, 0, -1)
    finimage = cv2.bitwise_and(fundus_eroded, fundus_eroded, mask=xmask)
    blood_vessels = cv2.bitwise_not(finimage)
    return blood_vessels

def Vessel_Segmentation_Demo(path):
    img = cv2.imread(path)
    _, green, _ = cv2.split(img)
    contrast_enhanced_green = enhance(green)
    morph_contrast_enhanced_green = Morph_Operate(contrast_enhanced_green)
    f4 = cv2.subtract(morph_contrast_enhanced_green, contrast_enhanced_green)
    f5 = enhance(f4)
    newfin = Vessels_Mask(f5)
    blood_vessels = Vessels_Extract(newfin)
    result1 = np.hstack([contrast_enhanced_green, morph_contrast_enhanced_green])
    result2 = np.hstack([f4, f5])
    result3 = np.hstack([newfin, blood_vessels])
    return np.vstack([result1, result2, result3])

if __name__ == '__main__':
    e_ophtha_MA = r'J:\Image Projects\Microaneurysm Detection\Datasets\2013_e_ophtha\e_ophtha_MA'
    imgpaths = Access_e_ophtha_MA(e_ophtha_MA + '\MA - CutBlack')
    for path,name in imgpaths:
        result = Vessel_Segmentation_Demo(path)
        key = CVShow(result, name)
        if key == ord('b'): break

 

你可能感兴趣的:(眼底血管形态学阈值分割)