检测眼睛是打开还是关闭

时间:2015-04-12 15:45:52

标签: android opencv detection matching

我正在开发一个Android应用程序,我需要检测眼睛的眨眼。到目前为止,我已经能够使用OpenCV检测到脸部和眼睛。但现在我需要检查眼睛是打开还是关闭。我在某处读到,我可以做的一种方法是测量像素强度(灰度级)。但是没有正确解释如何一步一步地做到这一点。我实际上是OpenCV的新手。所以有人可以帮助我,我该怎么做。这非常重要。

这是我的onCameraFrame方法:

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

    mRgba = inputFrame.rgba();
    mGray = inputFrame.gray();

    if (mAbsoluteFaceSize == 0) {
        int height = mGray.rows();
        if (Math.round(height * mRelativeFaceSize) > 0) {
            mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
        }
    }

    if (mZoomWindow == null || mZoomWindow2 == null)
       CreateAuxiliaryMats();

    MatOfRect faces = new MatOfRect();

        if (mJavaDetector != null)
            mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2,
                    2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                    new Size(mAbsoluteFaceSize, mAbsoluteFaceSize),
                    new Size());

    Rect[] facesArray = faces.toArray();
    for (int i = 0; i < facesArray.length; i++) {
        Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(),
                FACE_RECT_COLOR, 2);
        xCenter = (facesArray[i].x + facesArray[i].width + facesArray[i].x) / 2;
        yCenter = (facesArray[i].y + facesArray[i].y + facesArray[i].height) / 2;
        Point center = new Point(xCenter, yCenter);

        Rect r = facesArray[i];
        // compute the eye area
        Rect eyearea = new Rect(r.x + r.width / 20,
                (int) (r.y + (r.height / 20)), r.width - 2 * r.width / 20,
                (int) (r.height / 9.0));

        // split it
        Rect eyearea_right = new Rect(r.x + r.width / 6,
                (int) (r.y + (r.height / 4)),
                (r.width - 2 * r.width / 16) / 3, (int) (r.height / 4.0));
        Rect eyearea_left = new Rect(r.x + r.width / 11
                + (r.width - 2 * r.width / 16) / 2,
                (int) (r.y + (r.height / 4)),
                (r.width - 2 * r.width / 16) / 3, (int) (r.height / 4.0));
        // draw the area - mGray is working grayscale mat, if you want to
        // see area in rgb preview, change mGray to mRgba
        Core.rectangle(mRgba, eyearea_left.tl(), eyearea_left.br(),
                new Scalar(255, 0, 0, 255), 2);
        Core.rectangle(mRgba, eyearea_right.tl(), eyearea_right.br(),
                new Scalar(255, 0, 0, 255), 2);

        if (learn_frames < 5) {
            teplateR = get_template(mJavaDetectorEye, eyearea_right, 24);
            teplateL = get_template(mJavaDetectorEye, eyearea_left, 24);
            learn_frames++;
        } else {
            // Learning finished, use the new templates for template
            // matching
             match_eye(eyearea_right, teplateR, method); 
             match_eye(eyearea_left, teplateL, method); 

        }

    }

    return mRgba;
}

提前致谢。

3 个答案:

答案 0 :(得分:1)

我已经解决了这个问题和这个算法。它在这里实现了(C ++):https://github.com/maz/blinking-angel带算法:http://www.cs.bu.edu/techreports/pdf/2005-012-blink-detection.pdf

据我所知:

  • 你得到B&amp; W当前和100ms前帧
  • 你做新的(见github代码中的154)
  • 您应用阈值然后应用扩张过滤器
  • 您计算轮廓
  • 如果眼睛位置有blob with area > to a threshold,则意味着用户眨眼睛

在第316行查看is_blink函数。在他的情况下,他执行w * h of blob surrounding box > to a threshold

实际上它使用了眼睛/肤色之间的差异。在Github实现中,阈值>使用了5。

答案 1 :(得分:1)

我所做的是将眼睛区域从RGB转换为HSV并应用皮肤检测。我发现了HSV的肤色范围。如果皮肤像素的百分比大于阈值,则意味着眼睛接近,否则它是打开的。虽然由于光量存在,仍然存在一些准确性问题。谢谢大家给我一个开始:)

答案 2 :(得分:0)

一般来说,这个问题没有明显的解决方案,但是方法的数量非常多,所以我确信经过一些修改后你会发现一些足够好的东西。例如,你可以使用我提到的算法here(在“相关”btw中有这个问题的链接 - 检查该组中的其他链接)。

相关问题