Image segmentation with Canny Edge opencv

Posted on

Question :

I’m trying to target both the iris and pupil edge using opencv’s Canny Edge, but all of the parameters I’ve used do not meet the criteria of making the two borders well delimited. The only way I found of segmenting at least the edge of the iris was binarizing it and then applying the Canny Edge and actually gave a good return.

  • Is there any way to improve the result? Or is it trial and error?

  • How do I target the pupil?

Attempt to target only the binarizing pupil in the dark range:

#'guarda' o pixel se ele estiver no intervalo que é preto
for x in range(0,suavizada.shape[0]):
    for y in range(0,suavizada.shape[1]):
        if img[x][y] >=0 and suavizada[x][y] <65:
            escala[x][y] = 255

Iris targeting code:

img = cv2.imread('path',0)
suavizada = cv2.medianBlur(img,7)
_,limites = cv2.threshold(suavizada,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

bordas = cv2.Canny(limites,0,0)


Original Image:



I’m using Python 3.x with the library installed via PyPi


Answer :

Canny Edge in the way it is being implemented is leaving a pupil very small and similar to the noises created by eyelashes.

I think black slice is the best choice for pupil removal, then use Hough Circles to find pupil cuticle and Grab Cut to remove the pupil.

Black Slice

Extract from the image what is in the range of (0, 0, 0) to (60, 60, 60) of the BGR color space






img = np.asarray(bytearray(, dtype="uint8")
img = cv2.imdecode(img, cv2.IMREAD_COLOR)

copia = img.copy()
# Extrai as cores entre o intervalo BGR definido
mask = cv2.inRange(img, (0, 0, 0), (60, 60, 60))
## slice no preto
imask = mask > 0
preto = np.zeros_like(img, np.uint8)
preto[imask] = img[imask]

preto = cv2.cvtColor(preto, cv2.COLOR_BGR2GRAY)
cv2.imshow('Preto', preto)

# detecção de círculos
circles = cv2.HoughCircles(preto, cv2.HOUGH_GRADIENT, 1, 100,
                           param1=30, param2=30, minRadius=20, maxRadius=100)

#param do Grab Cut
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

# pelo menos um círculo encontrado
if circles is not None:
    # converte para int
    circles = np.round(circles[0, :]).astype("int")

    # loop nas coordenadas (x, y) e raio dos círculos encontrados
    for (x, y, r) in circles:
        roi = img.copy()
        # Desenha o círculo encontrado, (x, y), r - 25, (0, 255, 0), 4)
        # Desenha o retângulo do centro do círculo
        cv2.rectangle(copia, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
        # Região de interesse com a pupila
        roi = roi[y-r:y+r, x-r:x+r]
        roi_x, roi_y, _ = roi.shape
        #Grab Cut da Pupila
        mask = np.zeros(roi.shape[:2], np.uint8)
        rect = (10, 10,roi_x-10, roi_y-10)
        cv2.grabCut(roi, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
        mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
        roi_grab = roi * mask2[:, :, np.newaxis]
        # Mostra o Grab Cut
        cv2.imshow("Grab Cut", np.hstack([roi, roi_grab]))

    # Mostra a imagem com o círcuto e centro encontrado pelo Hough Circle
    cv2.imshow("output", np.hstack([img, copia]))


Leave a Reply

Your email address will not be published. Required fields are marked *