2016-04-30 22 views
6

Ich mache Pupille Erkennung für mein Schulprojekt. Ich arbeite zum ersten Mal mit OpenCV und Python, mit Python Version 3.4.2 und OpenCV 3.1.0.Pupille Erkennung in OpenCV & Python

Ich benutze die Raspberry Pi NoIR Kamera, und ich bekomme gute Bilder. .

Aber ich schön einen Schüler nicht erkennen kann (wegen der Glitzern, Wimpern und Schatten verweise ich auf einige Code auf dem Netz und die folgende ist ein Teil dieser Code

... 

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) 

# capture frames from the camera 
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): 

    image = frame.array 
    cv2.imshow("image", image) 


    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 
    retval, thresholded = cv2.threshold(gray, 80, 255, 0) 
    cv2.imshow("threshold", thresholded) 

    closed = cv2.erode(cv2.dilate(thresholded, kernel, iterations=1), kernel, iterations=1) 
    #closed = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel) 

    cv2.imshow("closed", closed) 

    thresholded, contours, hierarchy = cv2.findContours(closed, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) 

    drawing = np.copy(image) 
    cv2.drawContours(drawing, contours, -1, (255, 0, 0), 2) 

    for contour in contours: 

     area = cv2.contourArea(contour) 
     bounding_box = cv2.boundingRect(contour) 

     extend = area/(bounding_box[2] * bounding_box[3]) 

     # reject the contours with big extend 
     if extend > 0.8: 
      continue 

     # calculate countour center and draw a dot there 
     m = cv2.moments(contour) 
     if m['m00'] != 0: 
      center = (int(m['m10']/m['m00']), int(m['m01']/m['m00'])) 
      cv2.circle(drawing, center, 3, (0, 255, 0), -1) 

     # fit an ellipse around the contour and draw it into the image 
     try: 
      ellipse = cv2.fitEllipse(contour) 
      cv2.ellipse(drawing, box=ellipse, color=(0, 255, 0)) 
     except: 
      pass 

    # show the frame 
    cv2.imshow("Drawing", drawing) 

    ... 

Eingabebild.:

enter image description here

Ausgabebild:

enter image description here

Wie kann ich die Teile des Bildes entfernen, die nicht auf die Pupille bezogen sind, wie oben gezeigt?

Neben den Antworten sind auch Hinweise willkommen.

+0

Verwandte: [Beschleunigung vektorisiert Eye-Tracking-Algorithmus in numpy] (https://stackoverflow.com/questions/35996257/speeding-up-vectorized-eye-tracking-algorithm-in-numpy) . Sie können auch nach Zirkularität suchen ([Beispielcode] (https://github.com/Itseez/opencv/blob/3.1.0/modules/features2d/src/blobdetector.cpp#L222)). – Catree

+0

Andere Optionen: Erkennen Sie direkt Kreise mit [HoughCircles] (http://docs.opencv.org/3.1.0/dd/d1a/group__imgproc__feature.html#ga47849c3be0d0406ad3ca45db65a25d2d) und/oder behalten Sie nur die Kontur, wenn die Region darin dunkler ist als draußen. Wenn das Auge immer zentriert und in der gleichen Entfernung ist, können Sie auch eine Region von Interesse (ROI) definieren und die Fläche verwenden. – Catree

+0

Ich würde [erode] (http://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode) auf dem binären Bild verwenden und dann einfach [HoughCircles] (http: //docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html), um den wichtigsten Kreis im Bild zu erkennen. – 0x90

Antwort

4

Es gibt mehrere Dinge, die Sie tun können. Wie gut sie funktionieren, hängt davon ab, wie viel Variation in den Bildern vorhanden ist, auf die Sie den Algorithmus anwenden möchten. Sie könnten mehrere Annahmen machen und dann alle Kandidaten verwerfen, die sie nicht erfüllen.

entfernen kleine Erkennungen

Zuerst würde ich entfernen Kandidaten berücksichtigen, die zu klein sind, um am Anfang der Schleife diese Zeile hinzu:

if area < 100: 
    continue 

Die Schwelle zufällig ausgewählt wurde und funktionierte gut für diese bestimmtes Bild. Es hat fast die gesamte falsche Erkennung entfernt. Nur der Größte bleibt übrig. Aber du musst es mit deinen anderen Bildern vergleichen und es an deine Bedürfnisse anpassen.

enter image description here

Erkennungen entfernen, die

Eine weitere Annahme nicht rund sind Sie machen können, ist, dass die Schüler in der Regel rund sind und Sie können jede Erkennung entfernen, die nicht ‚rund‘ genug ist. Ein einfaches Maß für die Rundheit ist das Verhältnis von Umfang zu Fläche.

circumference = cv2.arcLength(contour,True) 
circularity = circumference ** 2/(4*math.pi*area) 

Die Zirkularität ist etwa 2,72 für den Schatten auf der rechten Seite und 1,31 für die Schüler.

Verbesserung der Rundheit

Sie bemerken, dass die Kontur der Pupille wegen Reflexionen nicht perfekt rund ist. Sie können dies verbessern, indem Sie die konvexe Hülle der Konturen berechnen.

Wenn Sie dies tun, bevor Sie die Fläche und den Umfang berechnen, erhalten Sie Kreisförmigkeitswerte von 1.01 und 1.37. (Ein perfekter Kreis hat eine Kreisförmigkeit von 1) Dies bedeutet, dass der Defekt der Reflexion nahezu perfekt repariert wurde. Dies ist möglicherweise in diesem Fall nicht notwendig, könnte aber in Fällen mit mehr Reflexionen nützlich sein.

enter image description here

+0

danke! Ich setze eine Limitzirkularität 1.1 und arbeite gut. Ich möchte dieses Projekt in Echtzeit umsetzen. wegen der Morphologie (meiner Ansicht nach), werden die FPS fallen, wenn die Kernelgröße größer wird. Kann ich die Morphologie verbessern? –