Opencv - определяет, закрыт глаз или открыт

Привет, ребята, я работаю над проектом, в котором мы пытаемся определить, закрыт ли глаз или открыт на снимке... что мы сделали до сих пор, так это то, что мы обнаружили лицо, затем глаза, а затем применили грубое преобразование, надеясь, что Радужная оболочка была бы единственным кругом, когда глаз открыт, проблема в том, что, когда глаз закрыт... он также создает круг

Вот код:

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.imgproc.Imgproc;




public class FaceDetector {

    public static void main(String[] args) {



        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("\nRunning FaceDetector");

        CascadeClassifier faceDetector = new CascadeClassifier("D:\\CS\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
        CascadeClassifier eyeDetector = new CascadeClassifier("D:\\CS\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml");

        Mat image = Highgui.imread("C:\\Users\\Yousra\\Desktop\\images.jpg");
        Mat gray = Highgui.imread("C:\\Users\\Yousra\\Desktop\\eyes\\E7.png");

        String faces;
        String eyes;


        MatOfRect faceDetections = new MatOfRect();
        MatOfRect eyeDetections = new MatOfRect();

        Mat face;
        Mat crop = null;
        Mat circles = new Mat();
        faceDetector.detectMultiScale(image, faceDetections);

   for (int i = 0; i< faceDetections.toArray().length; i++){

            faces = "Face"+i+".png";

             face = image.submat(faceDetections.toArray()[i]);
             crop = face.submat(4, (2*face.width())/3, 0, face.height());
            Highgui.imwrite(faces, face);
             eyeDetector.detectMultiScale(crop, eyeDetections, 1.1, 2, 0,new Size(30,30), new Size()); 

             if(eyeDetections.toArray().length ==0){

                 System.out.println(" Not a face" + i);
             }else{

                 System.out.println("Face with " + eyeDetections.toArray().length + "eyes" );

                 for (int j = 0; j< eyeDetections.toArray().length ; j++){

                    System.out.println("Eye" );
                    Mat eye = crop.submat(eyeDetections.toArray()[j]);
                    eyes = "Eye"+j+".png";
                    Highgui.imwrite(eyes, eye);

                 }
             }
         }





             Imgproc.cvtColor(gray, gray, Imgproc.COLOR_BGR2GRAY);
             System.out.println("1 Hough :" +circles.size());
 float circle[] = new float[3];

             for (int i = 0; i < circles.cols(); i++)
             {
                     circles.get(0, i, circle);
                 org.opencv.core.Point center = new org.opencv.core.Point();
                 center.x = circle[0];
                 center.y = circle[1];
                 Core.circle(gray, center, (int) circle[2], new Scalar(255,255,100,1), 4);
                 }


             Imgproc.Canny( gray, gray, 200, 10, 3,false);  

             Imgproc.HoughCircles( gray, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 100, 80, 10, 10, 50 );
             System.out.println("2 Hough:" +circles.size());

             for (int i = 0; i < circles.cols(); i++)
             {
                     circles.get(0, i, circle);
                 org.opencv.core.Point center = new org.opencv.core.Point();
                 center.x = circle[0];
                 center.y = circle[1];
                 Core.circle(gray, center, (int) circle[2], new Scalar(255,255,100,1), 4);
                 }
             Imgproc.Canny( gray, gray, 200, 10, 3,false);  

             Imgproc.HoughCircles( gray, circles, Imgproc.CV_HOUGH_GRADIENT, 1, 100, 80, 10, 10, 50 );
             System.out.println("3 Hough" +circles.size());

             //float circle[] = new float[3];

             for (int i = 0; i < circles.cols(); i++)
             {
                     circles.get(0, i, circle);
                 org.opencv.core.Point center = new org.opencv.core.Point();
                 center.x = circle[0];
                 center.y = circle[1];
                 Core.circle(gray, center, (int) circle[2], new Scalar(255,255,100,1), 4);
                 }

            String hough = "afterhough.png";
            Highgui.imwrite(hough, gray);
   }     
}

Любые предложения о том, как сделать это более точным?

2 ответа

Решение

Циркулярное преобразование Хафа вряд ли будет работать хорошо в большинстве случаев, т.е. когда глаз частично открыт или закрыт. Было бы лучше выделить прямоугольные области (ограничивающие рамки) вокруг глаз и вычислить меру на основе интенсивности пикселей (уровней серого). Например, дисперсия пикселей в пределах области будет хорошим отличительным признаком между открытыми и закрытыми глазами. Получение ограничивающего прямоугольника вокруг глаз может быть выполнено достаточно надежно с использованием относительного положения ограничивающего прямоугольника, обнаруженного вокруг лица с использованием каскадов Хаара OpenCV. Рисунок 3 в этой статье дает некоторое представление о процессе определения местоположения.

http://personal.ee.surrey.ac.uk/Personal/J.Collomosse/pubs/Malleson-IJCV-2012.pdf

Вы можете проверить значение circle.cols(), если оно равно 2, тогда глаза открыты, а если значение равно 0, то глаза закрыты. Вы также можете обнаружить мерцание глаза, если значение circle.cols() изменится с 2 на 0. Несмотря на то, что преобразование не будет обнаруживать окружность, если глаза закрыты.

Другие вопросы по тегам