Image segmentation with Canny Edge opencv

4

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)


cv2.imshow('bordas',bordas)
cv2.waitKey(0)
cv2.destroyAllWindows()

Original Image:

ImageafterbinarizingandgoingthroughCanny:

  

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

    
asked by anonymous 01.11.2018 / 04:41

1 answer

2

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

Detectionofcircles

DetectsthepupilcirclewithHoughCircles

RegionofInterestandGrabCut

Createtheregionofinterest(ROI)withthecoordinatesofthecirclefoundandusetheGrabCuttoextractthepupil

Code

importcv2importnumpyasnpimporturllib.requestresp=urllib.request.urlopen("https://i.stack.imgur.com/NL10Y.jpg")
img = np.asarray(bytearray(resp.read()), 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()
        r=r+50
        # Desenha o círculo encontrado
        cv2.circle(copia, (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]))
    cv2.waitKey(0)
    
02.11.2018 / 18:17