Commit 4f8b7a01 authored by Thiago Santini's avatar Thiago Santini

Improves coarse location runtime

parent c6d5c265
...@@ -97,25 +97,25 @@ void EyeImageProcessor::process(Timestamp timestamp, const Mat &frame) ...@@ -97,25 +97,25 @@ void EyeImageProcessor::process(Timestamp timestamp, const Mat &frame)
INTER_AREA); INTER_AREA);
Rect coarseROI = {0, 0, downscaled.cols, downscaled.rows }; Rect coarseROI = {0, 0, downscaled.cols, downscaled.rows };
// If the user wants a coarse location and the method has none embedded, // If the user wants a coarse location and the method has none embedded,
// we further constrain the search using the generic one // we further constrain the search using the generic one
if (!pupilDetectionMethod->hasCoarseLocation() && cfg.coarseDetection) { if (!pupilDetectionMethod->hasCoarseLocation() && cfg.coarseDetection) {
coarseROI = PupilDetectionMethod::coarsePupilDetection( downscaled, 0.5f ); coarseROI = PupilDetectionMethod::coarsePupilDetection( downscaled, 0.5f, 60, 40);
data.coarseROI = Rect( data.coarseROI = Rect(
userROI.tl() + coarseROI.tl() / scalingFactor, userROI.tl() + coarseROI.tl() / scalingFactor,
userROI.tl() + coarseROI.br() / scalingFactor userROI.tl() + coarseROI.br() / scalingFactor
); );
} else } else
data.coarseROI = Rect(); data.coarseROI = Rect();
if (cfg.tracking && pupilTrackingMethod) { if (cfg.tracking && pupilTrackingMethod) {
pupilTrackingMethod->run(timestamp, downscaled, coarseROI, data.pupil, *pupilDetectionMethod); pupilTrackingMethod->run(timestamp, downscaled, coarseROI, data.pupil, *pupilDetectionMethod);
} else { } else {
pupilDetectionMethod->run( downscaled, coarseROI, data.pupil ); pupilDetectionMethod->run( downscaled, coarseROI, data.pupil );
// TODO: expose this to the user // TODO: expose this to the user
if ( ! pupilDetectionMethod->hasConfidence() ) if ( ! pupilDetectionMethod->hasConfidence() )
data.pupil.confidence = PupilDetectionMethod::outlineContrastConfidence(downscaled, data.pupil); data.pupil.confidence = PupilDetectionMethod::outlineContrastConfidence(downscaled, data.pupil);
} }
if (data.pupil.center.x > 0 && data.pupil.center.y > 0) { if (data.pupil.center.x > 0 && data.pupil.center.y > 0) {
// Upscale // Upscale
...@@ -128,7 +128,7 @@ void EyeImageProcessor::process(Timestamp timestamp, const Mat &frame) ...@@ -128,7 +128,7 @@ void EyeImageProcessor::process(Timestamp timestamp, const Mat &frame)
} }
data.processingTimestamp = gTimer.elapsed() - data.timestamp; data.processingTimestamp = gTimer.elapsed() - data.timestamp;
emit newData(data); emit newData(data);
} }
......
...@@ -6,7 +6,7 @@ using namespace cv; ...@@ -6,7 +6,7 @@ using namespace cv;
//#define DBG_COARSE_PUPIL_DETECTION //#define DBG_COARSE_PUPIL_DETECTION
//#define DBG_OUTLINE_CONTRAST //#define DBG_OUTLINE_CONTRAST
#include <QElapsedTimer>
Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &minCoverage, const int &workingWidth, const int &workingHeight) Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &minCoverage, const int &workingWidth, const int &workingHeight)
{ {
// We can afford to work on a very small input for haar features, but retain the aspect ratio // We can afford to work on a very small input for haar features, but retain the aspect ratio
...@@ -15,7 +15,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -15,7 +15,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
float r = max( xr, yr ); float r = max( xr, yr );
Mat downscaled; Mat downscaled;
resize(frame, downscaled, Size(), 1/r, 1/r, CV_INTER_LINEAR); resize(frame, downscaled, Size(), 1/r, 1/r, CV_INTER_LINEAR);
int ystep = (int) max<float>( 0.01f*downscaled.rows, 1.0f); int ystep = (int) max<float>( 0.01f*downscaled.rows, 1.0f);
int xstep = (int) max<float>( 0.01f*downscaled.cols, 1.0f); int xstep = (int) max<float>( 0.01f*downscaled.cols, 1.0f);
...@@ -25,8 +25,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -25,8 +25,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
// Pupil radii is based on PuRe assumptions // Pupil radii is based on PuRe assumptions
int min_r = (int) (0.5 * 0.07 * d); int min_r = (int) (0.5 * 0.07 * d);
int max_r = (int) (0.5 * 0.29 * d); int max_r = (int) (0.5 * 0.29 * d);
int r_step = (int) max<float>( 0.1f*(max_r + min_r), 1.0f); int r_step = (int) max<float>( 0.2f*(max_r + min_r), 1.0f);
// TODO: padding so we consider the borders as well! // TODO: padding so we consider the borders as well!
/* Haar-like feature suggested by Swirski. For details, see /* Haar-like feature suggested by Swirski. For details, see
...@@ -38,9 +37,9 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -38,9 +37,9 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
*/ */
Mat itg; Mat itg;
integral(downscaled, itg, CV_32S); integral(downscaled, itg, CV_32S);
Mat res = Mat::zeros( downscaled.rows, downscaled.cols, CV_32F); Mat res = Mat::zeros( downscaled.rows, downscaled.cols, CV_32F);
float best_response = std::numeric_limits<float>::min(); float best_response = std::numeric_limits<float>::min();
deque< pair<Rect, float> > candidates; deque< pair<Rect, float> > candidates;
for (int r = min_r; r<=max_r; r+=r_step) { for (int r = min_r; r<=max_r; r+=r_step) {
int step = 3*r; int step = 3*r;
...@@ -62,7 +61,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -62,7 +61,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
ib.y = y - r; ib.y = y - r;
ic.y = y + r; ic.y = y + r;
id.y = y + r; id.y = y + r;
for (int x = step; x<downscaled.cols-step; x+=xstep) { for (int x = step; x<downscaled.cols-step; x+=xstep) {
oa.x = x - step; oa.x = x - step;
ob.x = x + step; ob.x = x + step;
oc.x = x + step; oc.x = x + step;
...@@ -78,7 +77,10 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -78,7 +77,10 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
float inner_mean = inner_norm*inner; float inner_mean = inner_norm*inner;
float outer_mean = outer_norm*outer; float outer_mean = outer_norm*outer;
float response = (outer_mean - inner_mean); float response = (outer_mean - inner_mean);
if ( response < 0.5*best_response)
continue;
if (response > best_response) if (response > best_response)
best_response = response; best_response = response;
...@@ -93,14 +95,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -93,14 +95,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
} }
} }
// Eliminate low response candidates then sort and combine auto compare = [] (const pair<Rect, float> &a, const pair<Rect,float> &b) {
for ( auto c = candidates.begin(); c != candidates.end();) {
if ( c->second < 0.5 * best_response)
c = candidates.erase(c);
else
c++;
}
auto compare = [] (const pair<Rect, float> &a, const pair<Rect,float> &b) {
return (a.second > b.second); return (a.second > b.second);
}; };
sort( candidates.begin(), candidates.end(), compare); sort( candidates.begin(), candidates.end(), compare);
...@@ -125,7 +120,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m ...@@ -125,7 +120,7 @@ Rect PupilDetectionMethod::coarsePupilDetection(const Mat &frame, const float &m
#endif #endif
if (coarse.width > minWidth && coarse.height > minHeight) if (coarse.width > minWidth && coarse.height > minHeight)
break; break;
} }
#ifdef DBG_COARSE_PUPIL_DETECTION #ifdef DBG_COARSE_PUPIL_DETECTION
rectangle(dbg, coarse, Scalar(0,255,0)); rectangle(dbg, coarse, Scalar(0,255,0));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment