I have the following retina image and I'm trying to trace the vessels (the darker lines coming out of the circle). Here is the original image:
I have tried thresholding the image using division normalization followed by filtering on contour area (as per a different stackoverflow solution):
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()
Here is the final output I got:
It ended up tracing the vessels, but it also had some background noise.
Ideally I am looking for this output:
Any suggestions for achieving this result?


