OpenCV& amp;中的瞳孔检测蟒蛇

时间:2016-04-30 14:44:52

标签: python opencv

我正在为我的学校项目做学生检测。这是我第一次使用Python版本3.4.2和OpenCV 3.1.0来使用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

如何删除与瞳孔无关的图像部分,如上所示?

除了答案,我们也欢迎任何提示。

2 个答案:

答案 0 :(得分:7)

你可以做几件事。它们的工作效果取决于您要应用算法的图像中的变化程度。您可以做出几个假设,然后丢弃所有不符合它们的候选人。

删除小检测

首先,我会考虑通过在循环开始时添加此行来删除太小的候选项:

if area < 100:
    continue

阈值是随机选择的,适用于此特定图像。它删除了几乎所有的错误检测。只剩下最大的一个。但是你必须根据你的其他图像进行检查,并根据你的需要进行调整。

enter image description here

删除非圆形的检测

您可以做出的另一个假设是,学生通常是圆形的,您可以删除每次“不圆”的检测。一个简单的圆度测量方法是观察周长与面积的比率。

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

答案 1 :(得分:0)

几年前,我意识到了一个非常相似的项目。对于上面添加的所有内容,我可以提出一个小技巧。

如您所见,您有来自任何光源的两次反射。一个在眼睛表面,另一个在玻璃表面反射。

如果您将移除玻璃(如果可能的话),您将在瞳孔中心几乎有一个非常明亮的反射。在这种情况下,您可以忽略没有这种明亮反射的所有对象。这也有助于您在相机附近的空间找到眼睛的位置