Ask Your Question
1

reduce the searching area for eye detection

asked 2015-11-05 16:13:09 -0600

elp14smaa gravatar image

updated 2015-11-05 16:13:51 -0600

I'm trying to reduce the searching area for eye detection . I have passed a rect (ROI) like this :

Rect region_of_interest = Rect(gray_img(faces[i].x),gray_img(faces[i].y) + gray_img(faces[i].height)/5,gray_img(faces[i].width), gray_img(faces[i].height)/3);
   Mat image_roi = region_of_interest;

I getting this errors and I don't know if what I'm doing is right can you help me please to do it correctly , I want to search for the eye in a rectangle area that contains the eyes not the whole face . Thanks for help

error: invalid conversion from 'int' to 'const cv::Range*' [-fpermissive]|
error: no matching function for call to 'cv::Rect_<int>::Rect_(cv::Mat, cv::MatExpr, cv::Mat, cv::MatExpr)
error: conversion from 'cv::Rect' to non-scalar type 'cv::Mat' requested|

The full function is :

  Mat cap_img,gray_img;
  vector<Rect> faces, eyes;
  while(1)
{
capture >> cap_img;
waitKey(10);
cvtColor(cap_img, gray_img, CV_BGR2GRAY);
cv::equalizeHist(gray_img,gray_img);
face_cascade.detectMultiScale(gray_img, faces, 1.1, 10, CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0), cvSize(300,300));
for(int i=0; i < faces.size();i++)
{
    Point pt1(faces[i].x+faces[i].width, faces[i].y+faces[i].height);
    Point pt2(faces[i].x,faces[i].y);

   Rect region_of_interest = Rect(gray_img(faces[i].x),gray_img(faces[i].y) + gray_img(faces[i].height)/5,gray_img(faces[i].width), gray_img(faces[i].height)/3);
   Mat image_roi = region_of_interest;

    eye_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30,30));
    for(size_t j=0; j< eyes.size(); j++)
    {
        //Point center(faces[i].x+eyes[j].x+eyes[j].width*0.5, faces[i].y+eyes[j].y+eyes[j].height*0.5);
        Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
        int radius = cvRound((eyes[j].width+eyes[j].height)*0.25);
        circle(cap_img, center, radius, Scalar(255,0,0), 2, 8, 0);
    }
    rectangle(cap_img, pt1, pt2, cvScalar(0,255,0), 2, 8, 0);
}
edit retag flag offensive close merge delete

Comments

sturkmen gravatar imagesturkmen ( 2015-11-06 03:44:12 -0600 )edit

it is not clear to me, I just want an example of how to set the ROI using rect to search for the eyes

elp14smaa gravatar imageelp14smaa ( 2015-11-06 08:12:37 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-11-06 13:27:46 -0600

updated 2015-11-06 16:10:45 -0600

i recommend you to use official OpenCV samples like objectDetection.cpp. the code in the question seems outdated.

in objectDetection.cpp focus on the lines below.

you will find the answer Mat faceROI = frame_gray( faces[i] );

//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

for ( size_t i = 0; i < faces.size(); i++ )
{
    Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
    ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

   faces[i].height = faces[i].height / 2 ; // you can reduce height meaning only top part of the face
    Mat faceROI = frame_gray( faces[i] );
    std::vector<Rect> eyes;

    //-- In each face, detect eyes
    eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CASCADE_SCALE_IMAGE, Size(30, 30) );
edit flag offensive delete link more

Comments

in Mat faceROI = frame_gray( faces[i] ); the whole face is passed to eyes_cascade ,

I want to pass only the region that contains the eyes not the full face. I think this should do it ,

 cv::Rect roi(x, y, width, height);
 cv::Mat image_roi = frame(roi);

but what should be the value of my x,y, width, height

elp14smaa gravatar imageelp14smaa ( 2015-11-06 14:50:23 -0600 )edit

try faces[i].height = faces[i].height / 2 ; before Mat faceROI = frame_gray( faces[i] );

sturkmen gravatar imagesturkmen ( 2015-11-06 16:12:28 -0600 )edit

Thanks but ,what about x,y and the width ?

elp14smaa gravatar imageelp14smaa ( 2015-11-06 16:49:48 -0600 )edit

you don't need to update x,y and width. to be sure you can show the roi by imshow("faceROI", faceROI);please try and see the result.

sturkmen gravatar imagesturkmen ( 2015-11-06 17:05:07 -0600 )edit

I have used it like this

    Rect Roi;
    Roi.x=faces[i].x;
    Roi.y=faces[i].y;
    Roi.width = (faces[i].width);
    Roi.height = (faces[i].height)/5;

    cv::Mat crop = frame(Roi);
    imshow("ROI", crop);

but the eyes are not inside this rect , it shows the forehead

this is the output : Image

elp14smaa gravatar imageelp14smaa ( 2015-11-08 04:40:40 -0600 )edit

I want to pass eye region like this red rectangle area around the eyes Image

elp14smaa gravatar imageelp14smaa ( 2015-11-08 05:17:51 -0600 )edit

use

Rect Roi = faces[i];
Roi.height = Roi.height / 4;
Roi.y = Roi.y + Roi.height;

cv::Mat crop = frame(Roi);
imshow("ROI", crop);
sturkmen gravatar imagesturkmen ( 2015-11-08 06:01:11 -0600 )edit

I used this :

Rect Roi = faces[ic];
    Roi.height = Roi.height / 4;
    Roi.y = Roi.y + Roi.height;

    cv::Mat crop = frame(Roi);
    cvtColor(crop, gray, CV_BGR2GRAY);
    imshow("ROI", gray);
    eye_cascade.detectMultiScale(gray, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(20, 20));

    for (size_t j = 0; j < eyes.size(); j++)
    {
        Rect r(faces[ic].x + eyes[j].x, faces[ic].y + eyes[j].y, eyes[j].width, eyes[j].height);

        rectangle(frame, r, Scalar(255, 0, 0), 3, 1, 0);
    }
}

The eye region is like this :Image I think is better than before ,

But when I pass it to detect eyes the eye is not detected correctly is appears on the forehead like this

Image

elp14smaa gravatar imageelp14smaa ( 2015-11-08 08:32:59 -0600 )edit

you must replace faces[ic] with Roi

for (size_t j = 0; j < eyes.size(); j++)
{
    Rect r(Roi.x + eyes[j].x, Roi.y + eyes[j].y, eyes[j].width, eyes[j].height);

    rectangle(frame, r, Scalar(255, 0, 0), 3, 1, 0);
}

if you will ask another question please post your code complately :)

sturkmen gravatar imagesturkmen ( 2015-11-08 09:16:11 -0600 )edit

Thanks @sturkmen for helping me , I have one final question . after detecting eyes using Roi ,

I converted the detected eye region to Y channel here is the code for this . Is this right method ?

for (size_t j = 0; j < eyes.size(); j++)
    {
        Rect r(Roi.x + eyes[j].x, Roi.y + eyes[j].y, eyes[j].width, eyes[j].height);


        rectangle(frame, r, Scalar(255, 0, 0), 3, 1, 0);


        Mat eye_region = frame(eyes[j]).clone();

        Mat eye_region_YCbCr;

        cvtColor(eye_region, eye_region_YCbCr, CV_BGR2YCrCb);

        vector<Mat> channels;

        split(eye_region_YCbCr, channels);

        Mat eye_region_Ychannel = channels[0].clone();

        imshow("Y", eye_region_Ychannel);

    }
}

Full code is Here

elp14smaa gravatar imageelp14smaa ( 2015-11-08 18:25:19 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-11-05 16:13:09 -0600

Seen: 658 times

Last updated: Nov 06 '15