2016-04-30 579 views
6

我在做瞳孔检测为我的学校项目。这是我第一次使用Python 3.4.2和OpenCV 3.1.0与OpenCV和Python合作。在OpenCV和Python中的瞳孔检测

我正在使用Raspberry Pi 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

相关:[加快在numpy的量化眼睛跟踪算法(https://stackoverflow.com/questions/35996257/speeding-up-vectorized-eye-tracking-algorithm-in-numpy) 。您也可以检查循环性([示例代码](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

删除不圆

可以使另一个假设是,学生通常为圆形检测,你可以删除所有检测是不是“圆”就够了。一个简单的圆度测量就是看周长与面积的比率。

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

圆形度为在右侧的阴影和1.31瞳孔约2.72。

提高圆度

你发现,你的瞳孔的轮廓并不是完美的圆形,因为反射。您可以通过计算轮廓的凸包来改善这一点。

contour = cv2.convexHull(contour) 

如果你在计算面积和周长之前这样做,你得到的圆形度值为1.01和1.37。 (一个完美圆的圆形度为1)这意味着反射的缺陷几乎完美地被修复了。在这种情况下,这可能不是必要的,但在具有更多思考的情况下可能会有用。

enter image description here

+0

谢谢!我设置了一个限制循环1.1,并且很好地工作。我想让这个项目'实时'。由于形态学(在我看来),随着内核尺寸变大,FPS会下降。我可以改善形态表现吗? –