Commit b179e2dd authored by Andrey Kamaev's avatar Andrey Kamaev Committed by OpenCV Buildbot

Merge pull request #396 from vpisarev:facedetect_fixes

parents 992d47e9 638c0d1b
...@@ -45,20 +45,20 @@ ...@@ -45,20 +45,20 @@
#include <stdio.h> #include <stdio.h>
#include "opencv2/core/internal.hpp" #include "opencv2/core/internal.hpp"
#if CV_SSE2 || CV_SSE3 #if CV_SSE2
# if !CV_SSE4_1 && !CV_SSE4_2 # if 1 /*!CV_SSE4_1 && !CV_SSE4_2*/
# define _mm_blendv_pd(a, b, m) _mm_xor_pd(a, _mm_and_pd(_mm_xor_pd(b, a), m)) # define _mm_blendv_pd(a, b, m) _mm_xor_pd(a, _mm_and_pd(_mm_xor_pd(b, a), m))
# define _mm_blendv_ps(a, b, m) _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(b, a), m)) # define _mm_blendv_ps(a, b, m) _mm_xor_ps(a, _mm_and_ps(_mm_xor_ps(b, a), m))
# endif # endif
#endif #endif
#if CV_AVX #if 0 /*CV_AVX*/
# define CV_HAAR_USE_AVX 1 # define CV_HAAR_USE_AVX 1
# if defined _MSC_VER # if defined _MSC_VER
# pragma warning( disable : 4752 ) # pragma warning( disable : 4752 )
# endif # endif
#else #else
# if CV_SSE2 || CV_SSE3 # if CV_SSE2
# define CV_HAAR_USE_SSE 1 # define CV_HAAR_USE_SSE 1
# endif # endif
#endif #endif
......
...@@ -87,11 +87,15 @@ protected: ...@@ -87,11 +87,15 @@ protected:
vector<string> imageFilenames; vector<string> imageFilenames;
vector<Mat> images; vector<Mat> images;
string validationFilename; string validationFilename;
string configFilename;
FileStorage validationFS; FileStorage validationFS;
bool write_results;
}; };
CV_DetectorTest::CV_DetectorTest() CV_DetectorTest::CV_DetectorTest()
{ {
configFilename = "dummy";
write_results = false;
} }
string& CV_DetectorTest::getValidationFilename() string& CV_DetectorTest::getValidationFilename()
...@@ -146,86 +150,99 @@ int CV_DetectorTest::prepareData( FileStorage& _fs ) ...@@ -146,86 +150,99 @@ int CV_DetectorTest::prepareData( FileStorage& _fs )
void CV_DetectorTest::run( int ) void CV_DetectorTest::run( int )
{ {
string dataPath = ts->get_data_path(); string dataPath = ts->get_data_path();
validationFS.open( dataPath + getValidationFilename(), FileStorage::READ ); string vs_filename = dataPath + getValidationFilename();
int code = prepareData( validationFS );
write_results = !validationFS.open( vs_filename, FileStorage::READ );
int code;
if( !write_results )
{
code = prepareData( validationFS );
}
else
{
FileStorage fs0(dataPath + configFilename, FileStorage::READ );
code = prepareData(fs0);
}
if( code < 0 ) if( code < 0 )
{ {
ts->set_failed_test_info( code ); ts->set_failed_test_info( code );
return; return;
} }
#ifdef GET_STAT if( write_results )
validationFS.release();
string filename = ts->get_data_path();
filename += getValidationFilename();
validationFS.open( filename, FileStorage::WRITE );
validationFS << FileStorage::getDefaultObjectName(validationFilename) << "{";
validationFS << DIST_E << eps.dist;
validationFS << S_E << eps.s;
validationFS << NO_PAIR_E << eps.noPair;
// validationFS << TOTAL_NO_PAIR_E << eps.totalNoPair;
// write detector names
validationFS << DETECTOR_NAMES << "[";
vector<string>::const_iterator nit = detectorNames.begin();
for( ; nit != detectorNames.end(); ++nit )
{ {
validationFS << *nit; validationFS.release();
} validationFS.open( vs_filename, FileStorage::WRITE );
validationFS << "]"; // DETECTOR_NAMES validationFS << FileStorage::getDefaultObjectName(validationFilename) << "{";
validationFS << DIST_E << eps.dist;
validationFS << S_E << eps.s;
validationFS << NO_PAIR_E << eps.noPair;
// validationFS << TOTAL_NO_PAIR_E << eps.totalNoPair;
// write detector names
validationFS << DETECTOR_NAMES << "[";
vector<string>::const_iterator nit = detectorNames.begin();
for( ; nit != detectorNames.end(); ++nit )
{
validationFS << *nit;
}
validationFS << "]"; // DETECTOR_NAMES
// write detectors // write detectors
validationFS << DETECTORS << "{"; validationFS << DETECTORS << "{";
assert( detectorNames.size() == detectorFilenames.size() ); assert( detectorNames.size() == detectorFilenames.size() );
nit = detectorNames.begin(); nit = detectorNames.begin();
for( int di = 0; di < detectorNames.size(), nit != detectorNames.end(); ++nit, di++ ) for( int di = 0; nit != detectorNames.end(); ++nit, di++ )
{ {
validationFS << *nit << "{"; validationFS << *nit << "{";
writeDetector( validationFS, di ); writeDetector( validationFS, di );
validationFS << "}";
}
validationFS << "}"; validationFS << "}";
}
validationFS << "}";
// write image filenames // write image filenames
validationFS << IMAGE_FILENAMES << "["; validationFS << IMAGE_FILENAMES << "[";
vector<string>::const_iterator it = imageFilenames.begin(); vector<string>::const_iterator it = imageFilenames.begin();
for( int ii = 0; it != imageFilenames.end(); ++it, ii++ ) for( int ii = 0; it != imageFilenames.end(); ++it, ii++ )
{ {
char buf[10]; char buf[10];
sprintf( buf, "%s%d", "img_", ii ); sprintf( buf, "%s%d", "img_", ii );
cvWriteComment( validationFS.fs, buf, 0 ); cvWriteComment( validationFS.fs, buf, 0 );
validationFS << *it; validationFS << *it;
} }
validationFS << "]"; // IMAGE_FILENAMES validationFS << "]"; // IMAGE_FILENAMES
validationFS << VALIDATION << "{"; validationFS << VALIDATION << "{";
#endif }
int progress = 0; int progress = 0;
for( int di = 0; di < test_case_count; di++ ) for( int di = 0; di < test_case_count; di++ )
{ {
progress = update_progress( progress, di, test_case_count, 0 ); progress = update_progress( progress, di, test_case_count, 0 );
#ifdef GET_STAT if( write_results )
validationFS << detectorNames[di] << "{"; validationFS << detectorNames[di] << "{";
#endif
vector<vector<Rect> > objects; vector<vector<Rect> > objects;
int temp_code = runTestCase( di, objects ); int temp_code = runTestCase( di, objects );
#ifndef GET_STAT
if (temp_code == cvtest::TS::OK) if (!write_results && temp_code == cvtest::TS::OK)
temp_code = validate( di, objects ); temp_code = validate( di, objects );
#endif
if (temp_code != cvtest::TS::OK) if (temp_code != cvtest::TS::OK)
code = temp_code; code = temp_code;
#ifdef GET_STAT
validationFS << "}"; // detectorNames[di] if( write_results )
#endif validationFS << "}"; // detectorNames[di]
}
if( write_results )
{
validationFS << "}"; // VALIDATION
validationFS << "}"; // getDefaultObjectName
} }
#ifdef GET_STAT
validationFS << "}"; // VALIDATION
validationFS << "}"; // getDefaultObjectName
#endif
if ( test_case_count <= 0 || imageFilenames.size() <= 0 ) if ( test_case_count <= 0 || imageFilenames.size() <= 0 )
{ {
ts->printf( cvtest::TS::LOG, "validation file is not determined or not correct" ); ts->printf( cvtest::TS::LOG, "validation file is not determined or not correct" );
...@@ -257,18 +274,19 @@ int CV_DetectorTest::runTestCase( int detectorIdx, vector<vector<Rect> >& object ...@@ -257,18 +274,19 @@ int CV_DetectorTest::runTestCase( int detectorIdx, vector<vector<Rect> >& object
objects.push_back( imgObjects ); objects.push_back( imgObjects );
#ifdef GET_STAT if( write_results )
char buf[10];
sprintf( buf, "%s%d", "img_", ii );
string imageIdxStr = buf;
validationFS << imageIdxStr << "[:";
for( vector<Rect>::const_iterator it = imgObjects.begin();
it != imgObjects.end(); ++it )
{ {
validationFS << it->x << it->y << it->width << it->height; char buf[10];
sprintf( buf, "%s%d", "img_", ii );
string imageIdxStr = buf;
validationFS << imageIdxStr << "[:";
for( vector<Rect>::const_iterator it = imgObjects.begin();
it != imgObjects.end(); ++it )
{
validationFS << it->x << it->y << it->width << it->height;
}
validationFS << "]"; // imageIdxStr
} }
validationFS << "]"; // imageIdxStr
#endif
} }
return cvtest::TS::OK; return cvtest::TS::OK;
} }
...@@ -374,12 +392,14 @@ protected: ...@@ -374,12 +392,14 @@ protected:
virtual void readDetector( const FileNode& fn ); virtual void readDetector( const FileNode& fn );
virtual void writeDetector( FileStorage& fs, int di ); virtual void writeDetector( FileStorage& fs, int di );
virtual int detectMultiScale( int di, const Mat& img, vector<Rect>& objects ); virtual int detectMultiScale( int di, const Mat& img, vector<Rect>& objects );
virtual int detectMultiScale_C( const string& filename, int di, const Mat& img, vector<Rect>& objects );
vector<int> flags; vector<int> flags;
}; };
CV_CascadeDetectorTest::CV_CascadeDetectorTest() CV_CascadeDetectorTest::CV_CascadeDetectorTest()
{ {
validationFilename = "cascadeandhog/cascade.xml"; validationFilename = "cascadeandhog/cascade.xml";
configFilename = "cascadeandhog/_cascade.xml";
} }
void CV_CascadeDetectorTest::readDetector( const FileNode& fn ) void CV_CascadeDetectorTest::readDetector( const FileNode& fn )
...@@ -402,11 +422,48 @@ void CV_CascadeDetectorTest::writeDetector( FileStorage& fs, int di ) ...@@ -402,11 +422,48 @@ void CV_CascadeDetectorTest::writeDetector( FileStorage& fs, int di )
fs << C_SCALE_CASCADE << sc; fs << C_SCALE_CASCADE << sc;
} }
int CV_CascadeDetectorTest::detectMultiScale_C( const string& filename,
int di, const Mat& img,
vector<Rect>& objects )
{
Ptr<CvHaarClassifierCascade> c_cascade = cvLoadHaarClassifierCascade(filename.c_str(), cvSize(0,0));
Ptr<CvMemStorage> storage = cvCreateMemStorage();
if( c_cascade.empty() )
{
ts->printf( cvtest::TS::LOG, "cascade %s can not be opened");
return cvtest::TS::FAIL_INVALID_TEST_DATA;
}
Mat grayImg;
cvtColor( img, grayImg, CV_BGR2GRAY );
equalizeHist( grayImg, grayImg );
CvMat c_gray = grayImg;
CvSeq* rs = cvHaarDetectObjects(&c_gray, c_cascade, storage, 1.1, 3, flags[di] );
objects.clear();
for( int i = 0; i < rs->total; i++ )
{
Rect r = *(Rect*)cvGetSeqElem(rs, i);
objects.push_back(r);
}
return cvtest::TS::OK;
}
int CV_CascadeDetectorTest::detectMultiScale( int di, const Mat& img, int CV_CascadeDetectorTest::detectMultiScale( int di, const Mat& img,
vector<Rect>& objects) vector<Rect>& objects)
{ {
string dataPath = ts->get_data_path(), filename; string dataPath = ts->get_data_path(), filename;
filename = dataPath + detectorFilenames[di]; filename = dataPath + detectorFilenames[di];
const string pattern = "haarcascade_frontalface_default.xml";
if( filename.size() >= pattern.size() &&
strcmp(filename.c_str() + (filename.size() - pattern.size()),
pattern.c_str()) == 0 )
return detectMultiScale_C(filename, di, img, objects);
CascadeClassifier cascade( filename ); CascadeClassifier cascade( filename );
if( cascade.empty() ) if( cascade.empty() )
{ {
......
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