2015-04-12 125 views
-3

我正在開發一個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; 
} 

在此先感謝。

回答

1

我已經工作在這個問題上和這個算法。它的實現(C++)在這裏:https://github.com/maz/blinking-angel,算法在這裏:http://www.cs.bu.edu/techreports/pdf/2005-012-blink-detection.pdf

至於我能記得:

  • 你得到乙& W通電和100ms的前框
  • 你新 - 老(見154 GitHub的代碼)
  • 您應用一個閾值,則一個擴張過濾
  • 您計算輪廓
  • 如果你有一個blob with area > to a threshold在眼睛的位置,這意味着用戶眨眼

請看0123行的is_blink函數。在他的情況下,他做了w * h of blob surrounding box > to a threshold

事實上,它用眼/皮膚顏色之間的差別。在Github實現中,使用閾值> 5。

+0

非常感謝。我會看看代碼。 –

+0

感謝您一步一步的解釋。所以現在我知道我需要遵循哪些步驟來感謝你。首先,我必須將RGBA圖像轉換爲B&W。我找不到任何Java代碼。你能給我發送到它的java代碼的鏈接嗎? –

+0

CvtColor:http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html –

0

一般是有這個問題沒有明顯的解決方案,但方案的數量是相當大的,所以我敢肯定這一點serching你會找到的東西夠你不錯的了。例如,你可以使用我提到的算法here(這裏有一個鏈接到「相關」btw這個問題 - 檢查來自這個組的其他鏈接)。

+0

你是對的。我在不同的地方看到了令我困惑的不同方式。現在我正在嘗試@Tom A告訴我的方法。你知道更好的方法嗎? –

1

我做什麼,我轉換的眼睛區域從RGB到HSV和應用皮膚檢測。我發現了HSV皮膚顏色的範圍。如果皮膚像素的百分比大於閾值,則意味着眼睛關閉,否則它是開放的。儘管由於光量的存在,仍然存在一些準確度問題。謝謝大家給我一個開始:)