2016-04-30 164 views
6

私の学校プロジェクトでは瞳孔検出を行っています。 OpenCVとPythonを使って、Python 3.4.2とOpenCV 3.1.0を使っています。OpenCV&Pythonでの瞳孔検出

私はラスベリーパイNoIRカメラを使用しており、良好な画像が得られます。

しかし、私は理由輝き、まつげと影の(うまく瞳を検出することはできません を、私はウェブ上でいくつかのコードを参照し、次のそのコードの一部です

... 

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) 

    ... 

入力画像。。:

enter image description here

出力画像:

enter image description here

上記のように、瞳孔に関連していない画像の部分を削除するにはどうすればよいですか?

回答に加えて、ヒントも歓迎します。

+0

関連:(https://stackoverflow.com/questions/35996257/speeding-up-vectorized-eye-tracking-algorithm-in-numpy)numpyの中ベクトル視線追跡アルゴリズムの高速化] 。循環性([example code](https://github.com/Itseez/opencv/blob/3.1.0/modules/features2d/src/blobdetector.cpp#L222))も確認できます)。 – Catree

+0

その他のオプション:[HoughCircles](http://docs.opencv.org/3.1.0/dd/d1a/group__imgproc__feature.html#ga47849c3be0d0406ad3ca45db65a25d2d)で直接円を検出したり、内側の領域が暗い場合は輪郭のみを保持してください外側。目が常に中央にあり、同じ距離にある場合は、関心領域(ROI)+領域を定義することもできます。 – Catree

+0

バイナリイメージで[erode](http://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode)を使用して、単純に[HoughCircles](http: //docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html)を使用して、画像内の最も重要な円を検出します。 – 0x90

答えて

4

あなたができることはいくつかあります。どのくらいうまく機能するかは、アルゴリズムを適用したい画像にどの程度のばらつきがあるかによって決まります。あなたはいくつかの仮定をして、それらに合致しないすべての候補者を捨てることができます。

最初は、私はあなたのループの先頭に次の行を追加しては小さすぎる候補を削除することを検討します小型の検出に

を削除:

if area < 100: 
    continue 

しきい値はランダムに選ばれ、このためによく働きました。特定の画像。それはほとんどすべての誤検出を取り除いた。最大のものだけが残っています。しかし、あなたは他のイメージと照らし合わせてそれをあなたのニーズに適応させなければなりません。

enter image description here

丸くなっていない検出

を削除するには、作ることができるもう一つの仮定は、生徒が丸い通常であり、あなたは十分に「ラウンド」ではありませんすべての検出を削除することができるということです。丸みの単純な尺度の1つは、円周率の比率を見ることです。

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

円形度は、右側の影で約2.72、瞳孔で約1.31です。丸み

を向上

あなたの瞳の輪郭があるため、反射の完全な円形ではないことを、注意してください。これを改善するには、輪郭の凸包を計算します。

contour = cv2.convexHull(contour) 

あなたは面積と円周を計算する前に、あなたが1.01と1.37の真円度の値を取得することを行う場合。 (真円は真円度1です)これは、反射による欠陥がほぼ完全に修復されたことを意味します。この場合、これは必要ではないかもしれませんが、反射が多い場合には役立ちます。

enter image description here

+0

ありがとう!私は限界円形度1.1を設定し、うまく動作します。私はこのプロジェクトを「リアルタイム」にしたいと思っています。 (私の見解では)形態のために、カーネルのサイズが大きくなるにつれてFPSは低下します。形態学的性能を向上させることができますか? –