image - How to segment blood vessels python opencv -


i trying segment blood vessels in retinal images using python , opencv. here original image:

enter image description here

ideally want blood vessels visible (different image):

enter image description here

here have tried far. took green color channel of image.

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

then tried create matched filter following this article , output image is:

enter image description here

then tried doing max entropy thresholding:

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 maximum     max_ent, threshold = 0, 0      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 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 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,      return threshold   img = skimage.io.imread('image.jpg') # obtain histogram hist = np.histogram(img, bins=256, range=(0, 256))[0] # threshold th = max_entropy.max_entropy(hist) print th  ret,th1 = cv2.threshold(img,th,255,cv2.thresh_binary) 

this result i'm getting, not showing blood vessels:

enter image description here

i've tried taking matched filter version of image , taking magnitude of sobel values.

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) 

this makes vessels pop out more:

enter image description here

then tried otsu thresholding on it:

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)  1 = image.fromarray(th2).show() 1 = image.fromarray(th3).show() 

otsu doesn't give adequate results. ends including noise in results:

enter image description here

any appreciated on how can segment blood vessels successfully.

i worked on retina vessel detection bit few years ago, , there different ways it:

  • if don't need top result fast, can use oriented openings, see here , here.
  • then have other version using mathematical morphology version here.

for better results, here ideas:


Comments

Popular posts from this blog

javascript - Slick Slider width recalculation -

jsf - PrimeFaces Datatable - What is f:facet actually doing? -

angular2 services - Angular 2 RC 4 Http post not firing -