/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of the copyright holders may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ #include "test_precomp.hpp" #include <string> #ifdef HAVE_CVCONFIG_H #include "cvconfig.h" #endif #ifdef HAVE_TBB #include "tbb/task_scheduler_init.h" #endif using namespace cv; const float score_thr = 0.05f; class LatentSVMDetectorCascadeTest : public cvtest::BaseTest { protected: void run(int); }; static void writeDetections( FileStorage& fs, const std::string& nodeName, const std::vector<lsvm::LSVMDetector::ObjectDetection>& detections ) { fs << nodeName << "["; for( size_t i = 0; i < detections.size(); i++ ) //FIXME operator << { lsvm::LSVMDetector::ObjectDetection const &d = detections[i]; fs << d.rect.x << d.rect.y << d.rect.width << d.rect.height << d.score << d.classID; } fs << "]"; } static void readDetections( FileStorage fs, const std::string& nodeName, std::vector<lsvm::LSVMDetector::ObjectDetection>& detections ) { detections.clear(); FileNode fn = fs.root()[nodeName]; FileNodeIterator fni = fn.begin(); while( fni != fn.end() ) { lsvm::LSVMDetector::ObjectDetection d; fni >> d.rect.x >> d.rect.y >> d.rect.width >> d.rect.height >> d.score >> d.classID; detections.push_back( d ); } } static inline bool isEqualCaskad( const lsvm::LSVMDetector::ObjectDetection& d1, const lsvm::LSVMDetector::ObjectDetection& d2, int eps, float threshold) { return ( std::abs(d1.rect.x - d2.rect.x) <= eps && std::abs(d1.rect.y - d2.rect.y) <= eps && std::abs(d1.rect.width - d2.rect.width) <= eps && std::abs(d1.rect.height - d2.rect.height) <= eps && (d1.classID == d2.classID) && std::abs(d1.score - d2.score) <= threshold ); } bool compareResults( const std::vector<lsvm::LSVMDetector::ObjectDetection>& calc, const std::vector<lsvm::LSVMDetector::ObjectDetection>& valid, int eps, float threshold) { if( calc.size() != valid.size() ) return false; for( size_t i = 0; i < calc.size(); i++ ) { lsvm::LSVMDetector::ObjectDetection const &c = calc[i]; lsvm::LSVMDetector::ObjectDetection const &v = valid[i]; if( !isEqualCaskad(c, v, eps, threshold) ) { std::cerr << "Expected: " << v.rect << " class=" << v.classID << " score=" << v.score << std::endl; std::cerr << "Actual: " << c.rect << " class=" << c.classID << " score=" << c.score << std::endl; return false; } } return true; } void LatentSVMDetectorCascadeTest::run( int /* start_from */) { std::string test_data_path = ts->get_data_path() + "latentsvmdetector/"; std::string img_path_cat = test_data_path + "cat.png"; std::string img_path_cars = test_data_path + "cars.png"; std::string model_path_cat = test_data_path + "models_VOC2007_cascade/cat.xml"; std::string model_path_car = test_data_path + "models_VOC2007_cascade/car.xml"; std::string true_res_path = test_data_path + "results_cascade.xml"; #ifdef HAVE_TBB int numThreads = 2; #endif Mat image_cat = imread( img_path_cat ); Mat image_cars = imread( img_path_cars ); if( image_cat.empty() || image_cars.empty() ) { ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); return; } // We will test 2 cases: // detector1 - to test case of one class 'cat' // detector12 - to test case of two (several) classes 'cat' and car // Load detectors cv::Ptr<lsvm::LSVMDetector> detector1 = lsvm::LSVMDetector::create(std::vector<std::string>(1,model_path_cat)); std::vector<std::string> models_pathes(2); models_pathes[0] = model_path_cat; models_pathes[1] = model_path_car; cv::Ptr<lsvm::LSVMDetector> detector12 = lsvm::LSVMDetector::create(models_pathes); if( detector1->isEmpty() || detector12->isEmpty() || detector12->getClassCount() != 2 ) { ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA ); return; } // 1. Test method detect // Run detectors std::vector<lsvm::LSVMDetector::ObjectDetection> detections1_cat, detections12_cat, detections12_cars; detector1->detect( image_cat, detections1_cat, 0.5); detector12->detect( image_cat, detections12_cat, 0.5); detector12->detect( image_cars, detections12_cars, 0.5); // Load true results FileStorage fs( true_res_path, FileStorage::READ ); if( fs.isOpened() ) { std::vector<lsvm::LSVMDetector::ObjectDetection> true_detections1_cat, true_detections12_cat, true_detections12_cars; readDetections( fs, "detections1_cat", true_detections1_cat ); readDetections( fs, "detections12_cat", true_detections12_cat ); readDetections( fs, "detections12_cars", true_detections12_cars ); if( !compareResults(detections1_cat, true_detections1_cat, 1, score_thr) ) { std::cerr << "Results of detector1 are invalid on image cat.png" << std::endl; ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); } if( !compareResults(detections12_cat, true_detections12_cat, 1, score_thr) ) { std::cerr << "Results of detector12 are invalid on image cat.png" << std::endl; ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); } if( !compareResults(detections12_cars, true_detections12_cars, 1, score_thr) ) { std::cerr << "Results of detector12 are invalid on image cars.png" << std::endl; ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH ); } } else { fs.open( true_res_path, FileStorage::WRITE ); if( fs.isOpened() ) { writeDetections( fs, "detections1_cat", detections1_cat ); writeDetections( fs, "detections12_cat", detections12_cat ); writeDetections( fs, "detections12_cars", detections12_cars ); } else std::cerr << "File " << true_res_path << " cann't be opened to save test results" << std::endl; } ts->set_failed_test_info( cvtest::TS::OK); } TEST(Objdetect_LatentSVMDetectorCascade_cpp, regression) { LatentSVMDetectorCascadeTest test; test.safe_run(); }