# Simple technique to segment out optical disk and vessels from retinography

I'm looking for simple techniques to segment out the optical disk and vessels from a retinography. By simple I mean using techniques taught during an introductory course on digital image processing.

I looked for papers on the subject but all of them included more advanced or complicated techniques.

Do you have any suggestions?

It doesn't need to achieve a very high accuracy of segmentation and it doesn't need to be extremely robust.

• My slight problem with your question is that I don't know the entry-level image processing course you're thinking about -- which sadly puts exactly you in the best position to answer your own question. Maybe you'd want to illustrate by explaining a few approaches that have crossed your mind so far! Commented May 31, 2017 at 7:12
• By "entry-level" I mean anything in the Gonzalez and Woods book for example. I've tried thresholding the green channel to segment out the optic disk (the brighter section). The result is not good, whether you segment too much or too little around the optic disk. I'm experimenting right now with the vessels. I posted the question because by looking the papers on the subject it seemed like a very difficult task. Commented May 31, 2017 at 13:20

I managed to get a decent segmentation of the optical disk and vessels by applying some basic operations to the input image, starting with loading and grayscaling it:

img = imread("TBoV2.jpg")
img = rgb2gray(img)


Then I obtained the edge map of the image using a Sobel filter:

edge_map = sobel(img)


The segmentation itself is based on the Otsu threshold of the edge map:

t = threshold_otsu(edge_map)

segmented = np.zeros_like(edge_map)
segmented[edge_map < t/4] = 0
segmented[edge_map > t/4] = 255


Keep in mind that I played around with the t value (mostly by dividing by different factors) before I find a good foreground/background partition. Generally speaking, plotting the histograms of the images you are working with is a good practice, as they will help you make informed decisions when segmenting. Although I did that, I will not upload them here to keep my answer brief and to the point. Finally, the noise in the segmented image was cleaned using morphological operations:

segmented_clean = area_opening(segmented, area_threshold=128, connectivity=1)


Here is my final result.

Note: this answer is loosely based on an answer I gave to this question. However, I took into consideration your requirements for a simple approach and did not use the Watershed algorithm. I hope you will find my work helpful.

Here is the complete code:

# Imports:
import numpy as np
from skimage.color import rgb2gray
from skimage.filters import threshold_otsu, sobel
from skimage.morphology import area_opening

# Solution:
img = rgb2gray(img)

edge_map = sobel(img)

t = threshold_otsu(edge_map)

segmented = np.zeros_like(edge_map)
segmented[edge_map < t/4] = 0
segmented[edge_map > t/4] = 255

segmented_clean = area_opening(segmented, area_threshold=128, connectivity=1)

• Finding the edges of vessels is not the same as finding the vessels. Typically you’d use 2nd order derivatives for this. Sobel filters estimate the 1st order derivatives, which are strong at edges. 2nd order derivatives are strong at ridges (the middle of the vessel). Commented Apr 14, 2023 at 13:28
• This is correct, but the question asks for a simple approach which does not have to be robust and achieve high accuracy. Therefore, I decided to not bother too much with technicalities. If someone is interested in more sophisticated and accurate approach towards the problem, you can find more information here. I managed to get near perfect results with the meijering filter mentioned in this tutorial. Commented Apr 14, 2023 at 18:55