#include "SmileTest.h" #include #include // for cout #include // for setprecision( int p ) #include // For auto_ptr #include #include // For system independent path support namespace bf = boost::filesystem; #include "FilePairLineIterator.h" using namespace std; CPPUNIT_TEST_SUITE_REGISTRATION( SmileTest ); SmileTest::SmileTest() : smiledetector(0, MPSmile::featuerDetectorWeights), rotator( SMD_FACE_SIZE ) { std::string defaultFD( "./featuredetector/frozenData/" ); loadFeatureDetector( defaultFD ); smiledetector.setPixelMax( 1.0 ); } void SmileTest::loadFeatureDetector( const std::string &dir ) { bf::path dirPath( dir ); bf::path fdtxml; bf::path gpriorxml; featureDetector.setUseSequence( false ); fdtxml = dirPath / "left_eye_CERT3.fdtxml"; gpriorxml = dirPath / "left_eye_CERT3.gpriorxml"; featureDetector.loadFeatureFromFiles( fdtxml.native_file_string().c_str(), gpriorxml.native_file_string().c_str() ); fdtxml = dirPath / "right_eye_CERT3.fdtxml"; gpriorxml = dirPath / "right_eye_CERT3.gpriorxml"; featureDetector.loadFeatureFromFiles( fdtxml.native_file_string().c_str(), gpriorxml.native_file_string().c_str() ); fdtxml = dirPath / "nose_CERT3.fdtxml"; gpriorxml = dirPath / "nose_CERT3.gpriorxml"; featureDetector.loadFeatureFromFiles( fdtxml.native_file_string().c_str(), gpriorxml.native_file_string().c_str() ); fdtxml = dirPath / "mouth_CERT3_1.fdtxml"; gpriorxml = dirPath / "mouth_CERT3_1.gpriorxml"; featureDetector.loadFeatureFromFiles( fdtxml.native_file_string().c_str(), gpriorxml.native_file_string().c_str() ); featureDetector.setCERT3_3_FaceBox(); } /** */ void SmileTest::setUp() { } /** */ void SmileTest::tearDown() { } /** Rotate an RImage and compare. * Rotate the input RImage and compare with one we know is properly rotated. */ void SmileTest::testDataFile() { static const bf::path imageDir( "/Users/testbot/Images" ); float count = 0; float correct = 0; float errors = 0; FilePairLineIterator iter( "unit_test_data.txt" ); // std::cout << "CERT v" << CERT_CLASS::getVersion() << " (build " << CERT_CLASS::getBuildString() << ")" << std::endl; while( !iter.eof() ) { std::string filename1; std::string filename2; if( iter.nextDataLine( filename1, filename2 ) ) { bf::path path1( imageDir / filename1 ); bf::path path2( imageDir / filename2 ); float smile1, smile2; if( smileForImage( path1.native_file_string(), smile1 ) && smileForImage( path2.native_file_string(), smile2 ) ) { if( smile1 > smile2 ) ++correct; } else { ++errors; } ++count; } else { // error message? Assert? } } CPPUNIT_ASSERT( count > 0.0 ); float auc = correct / (count - errors); std::stringstream errorStream; errorStream << "SmileTest correct/total/missed-faces: " << correct << "/" << count << "/" << errors << ". AUC (correct/(total-missed)) = " << auc; std::string errorString = errorStream.str() + "\n"; CPPUNIT_ASSERT_MESSAGE( errorString, (auc > 0.96) ); std::cout << ": " << errorStream.str(); } bool SmileTest::smileForImage( const std::string &filename, float &smile ) { RImage pixels; // std::cout << "Image: " << filename << std::endl; if( !loader.loadRImage( pixels, filename ) ) return false; EyeFaceList faceList; featureDetector.findEyes( pixels, faceList ); ObjectWithFeatures *face = featureDetector.getLargestFace(); if( face ) { FeatureAlignment::alignment_method method = FeatureAlignment::procrustes; RIntegral *pfIntegral = static_cast*>(featureDetector.getIntegralPtr().get()); RImage patch; bool didRotate; MP_RotateFace::OWFList faces; faces.push_back( *face ); try { didRotate = rotator.rotateImageUsingFeatures( &featureDetector, &pixels, faces, patch, method, pfIntegral ); } catch(...) { return false; } FaceObject tempFace; mp_FDEyes::FaceFromObject( tempFace, *face ); smiledetector.findSmilesFromFace( patch, tempFace, 1.0f ); smile = tempFace.activation; return true; } return false; }