Ask Your Question

Revision history [back]

Like stated above, you will need more than the basic functionality provided by OpenCV. Look at gaze estimation algorithms. I know of a paper that uses Cascade Classifiers to define a rough angle, and which is fully integrated into OpenCV. Have a look here: https://lirias.kuleuven.be/retrieve/376252

click to hide/show revision 2
No.2 Revision

updated 2019-01-20 08:46:20 -0500

berak gravatar image

Like stated above, you will need more than the basic functionality provided by OpenCV. Look at gaze estimation algorithms. I know of a paper that uses Cascade Classifiers to define a rough angle, and which is fully integrated into OpenCV. Have a look here: https://lirias.kuleuven.be/retrieve/376252

@StevenPuttemans, hope you don't mind me pirating your answer, but it works amazingly well ;)

VideoCapture cap(0);
CascadeClassifier right("c:/p/opencv/data/haarcascades/haarcascade_profileface.xml");
while(1) {
    Mat frame, gray;
    cap.read(frame);
    pyrDown(frame,frame);
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
    std::vector<cv::Rect> faces_right,faces_left;
    std::vector<int> lvl_right,lvl_left;
    std::vector<double> weights_right,weights_left;
    right.detectMultiScale(gray, faces_right, lvl_right, weights_right, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    flip(gray,gray,1);
    right.detectMultiScale(gray, faces_left, lvl_left, weights_left, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    float angle = 0;
    if (weights_right.size()>0 && weights_right[0]>0)
        angle += 90 * weights_right[0] / 4;
    if (weights_left.size() && weights_left[0]>0)
        angle += -90 * weights_left[0] / 4;
    cout << angle << endl;

    imshow("F",frame);
    if (waitKey(10) > -1) break;
}
click to hide/show revision 3
No.3 Revision

updated 2019-01-20 09:07:18 -0500

berak gravatar image

Like stated above, you will need more than the basic functionality provided by OpenCV. Look at gaze estimation algorithms. I know of a paper that uses Cascade Classifiers to define a rough angle, and which is fully integrated into OpenCV. Have a look here: https://lirias.kuleuven.be/retrieve/376252

@StevenPuttemans, hope you don't mind me pirating "pirating" your answer, but given it's so simple, -- it works amazingly well !! ;)

VideoCapture cap(0);
CascadeClassifier right("c:/p/opencv/data/haarcascades/haarcascade_profileface.xml");
while(1) {
    Mat frame, gray;
    cap.read(frame);
    pyrDown(frame,frame);
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
    std::vector<cv::Rect> faces_right,faces_left;
    std::vector<int> lvl_right,lvl_left;
    std::vector<double> weights_right,weights_left;
    right.detectMultiScale(gray, faces_right, lvl_right, weights_right, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    flip(gray,gray,1);
    right.detectMultiScale(gray, faces_left, lvl_left, weights_left, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    float angle = 0;
    if (weights_right.size()>0 && weights_right[0]>0)
        angle += 90 * weights_right[0] / 4;
    if (weights_left.size() && weights_left[0]>0)
        angle += -90 * weights_left[0] / 4;
    cout << angle << endl;

    imshow("F",frame);
    if (waitKey(10) > -1) break;
}
click to hide/show revision 4
No.4 Revision

updated 2019-01-20 10:44:23 -0500

berak gravatar image

Like stated above, you will need more than the basic functionality provided by OpenCV. Look at gaze estimation algorithms. I know of a paper that uses Cascade Classifiers to define a rough angle, and which is fully integrated into OpenCV. Have a look here: https://lirias.kuleuven.be/retrieve/376252

@StevenPuttemans, hope you don't mind me "pirating" your answer, but given it's so simple, -- it works amazingly well !! ;)

VideoCapture cap(0);
CascadeClassifier right("c:/p/opencv/data/haarcascades/haarcascade_profileface.xml");
profile("c:/p/opencv/data/haarcascades/haarcascade_profileface.xml");
while(1) {
    Mat frame, gray;
    cap.read(frame);
    pyrDown(frame,frame);
    cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
    std::vector<cv::Rect> faces_right,faces_left;
    std::vector<int> lvl_right,lvl_left;
    std::vector<double> weights_right,weights_left;
    right.detectMultiScale(gray, // right face side
    profile.detectMultiScale(gray, faces_right, lvl_right, weights_right, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    // flip, and apply again for left one
    flip(gray,gray,1);
    right.detectMultiScale(gray, profile.detectMultiScale(gray, faces_left, lvl_left, weights_left, 1.2, 1, 0, cv::Size(30, 30), Size(), true);
    float angle = 0;
0; // formula from paper: a=-90*l+90*r ;)
    if (weights_right.size()>0 && weights_right[0]>0)
        // 4: heuristic scale factor, though i'm pretty sure, this is not linear ;)
        angle += 90 * weights_right[0] / 4;
4; 
    if (weights_left.size() && weights_left[0]>0)
        angle += -90 * weights_left[0] / 4;
    cout << angle << endl;

    imshow("F",frame);
    if (waitKey(10) > -1) break;
}