I have fundus images which are pictures of the retina which have already been processed, and I am looking at and am trying to remove the smaller blood vessels using morphological erosion. This appears to have worked in several of the papers I have read but the details of the exact operators are not included.
I have tried various approaches, morphological opening, morphological erosion then closing, I did a little bit of hit or miss. All of my work was done using the openCV2 python library.
This is the original image.
def erode(image):
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,2))
erosion = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=1)
erosion = cv2.erode(erosion, kernel, iterations=1)
return erosion
After morphological erosion and opening:
I am hoping to get more blood vessels removed while still retaining the thicker ones, does anyone have any good ideas for me to try? Or perhaps I am approaching the morphology incorrectly?
I think you have the right approach but just need to apply additional filtering. After eroding, you can find contours and filter using contour area. If the area is smaller than some threshold area, you can color in the contour to effectively remove the smaller vessels. The kernel size, iterations in cv2.morphologyEx()
, and threshold area can be tuned to remove more or less of the blood vessels. But be careful to not increase the kernel dimensions too much as there is a trade off: The larger the kernel, the more detail is removed
import cv2
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 100:
cv2.drawContours(opening, [c], -1, (0,0,0), -1)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.waitKey()