merged 2.4 into trunk
This commit is contained in:
@@ -586,16 +586,13 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
struct CV_EXPORTS DataMatrixCode {
|
||||
char msg[4]; //TODO std::string
|
||||
Mat original;
|
||||
Point corners[4]; //TODO vector
|
||||
};
|
||||
|
||||
CV_EXPORTS void findDataMatrix(const Mat& image, std::vector<DataMatrixCode>& codes);
|
||||
CV_EXPORTS void drawDataMatrixCodes(const std::vector<DataMatrixCode>& codes, Mat& drawImage);
|
||||
CV_EXPORTS_W void findDataMatrix(InputArray image,
|
||||
CV_OUT vector<string>& codes,
|
||||
OutputArray corners=noArray(),
|
||||
OutputArrayOfArrays dmtx=noArray());
|
||||
CV_EXPORTS_W void drawDataMatrixCodes(InputOutputArray image,
|
||||
const vector<string>& codes,
|
||||
InputArray corners);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
|
@@ -496,60 +496,80 @@ endo: ; // end search for this o
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace
|
||||
|
||||
void findDataMatrix(InputArray _image,
|
||||
vector<string>& codes,
|
||||
OutputArray _corners,
|
||||
OutputArrayOfArrays _dmtx)
|
||||
{
|
||||
struct CvDM2DM_transform
|
||||
{
|
||||
DataMatrixCode operator()(CvDataMatrixCode& cvdm)
|
||||
Mat image = _image.getMat();
|
||||
CvMat m(image);
|
||||
deque <CvDataMatrixCode> rc = cvFindDataMatrix(&m);
|
||||
int i, n = (int)rc.size();
|
||||
Mat corners;
|
||||
|
||||
if( _corners.needed() )
|
||||
{
|
||||
DataMatrixCode dm;
|
||||
memcpy(dm.msg,cvdm.msg,sizeof(cvdm.msg));
|
||||
dm.original = cv::Mat(cvdm.original,true);
|
||||
cvReleaseMat(&cvdm.original);
|
||||
cv::Mat c(cvdm.corners,true);
|
||||
dm.corners[0] = c.at<Point>(0,0);
|
||||
dm.corners[1] = c.at<Point>(1,0);
|
||||
dm.corners[2] = c.at<Point>(2,0);
|
||||
dm.corners[3] = c.at<Point>(3,0);
|
||||
cvReleaseMat(&cvdm.corners);
|
||||
return dm;
|
||||
_corners.create(n, 4, CV_32SC2);
|
||||
corners = _corners.getMat();
|
||||
}
|
||||
};
|
||||
|
||||
struct DrawDataMatrixCode
|
||||
{
|
||||
DrawDataMatrixCode(cv::Mat& image):image(image){}
|
||||
void operator()(const DataMatrixCode& code)
|
||||
|
||||
if( _dmtx.needed() )
|
||||
_dmtx.create(n, 1, CV_8U);
|
||||
|
||||
codes.resize(n);
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Scalar c(0, 255, 0);
|
||||
Scalar c2(255, 0,0);
|
||||
line(image, code.corners[0], code.corners[1], c);
|
||||
line(image, code.corners[1], code.corners[2], c);
|
||||
line(image, code.corners[2], code.corners[3], c);
|
||||
line(image, code.corners[3], code.corners[0], c);
|
||||
string code_text(code.msg,4);
|
||||
//int baseline = 0;
|
||||
//Size sz = getTextSize(code_text, CV_FONT_HERSHEY_SIMPLEX, 1, 1, &baseline);
|
||||
putText(image, code_text, code.corners[0], CV_FONT_HERSHEY_SIMPLEX, 0.8, c2, 1, CV_AA, false);
|
||||
CvDataMatrixCode& rc_i = rc[i];
|
||||
codes[i] = string(rc_i.msg);
|
||||
|
||||
if( corners.data )
|
||||
{
|
||||
const Point* srcpt = (Point*)rc_i.corners->data.ptr;
|
||||
Point* dstpt = (Point*)corners.ptr(i);
|
||||
for( int k = 0; k < 4; k++ )
|
||||
dstpt[k] = srcpt[k];
|
||||
}
|
||||
cvReleaseMat(&rc_i.corners);
|
||||
|
||||
if( _dmtx.needed() )
|
||||
{
|
||||
_dmtx.create(rc_i.original->rows, rc_i.original->cols, rc_i.original->type, i);
|
||||
Mat dst = _dmtx.getMat(i);
|
||||
Mat(rc_i.original).copyTo(dst);
|
||||
}
|
||||
cvReleaseMat(&rc_i.original);
|
||||
}
|
||||
cv::Mat& image;
|
||||
|
||||
DrawDataMatrixCode& operator=(const DrawDataMatrixCode&);
|
||||
};
|
||||
}
|
||||
|
||||
void findDataMatrix(const cv::Mat& image, std::vector<DataMatrixCode>& codes)
|
||||
void drawDataMatrixCodes(InputOutputArray _image,
|
||||
const vector<string>& codes,
|
||||
InputArray _corners)
|
||||
{
|
||||
CvMat m(image);
|
||||
deque <CvDataMatrixCode> rc = cvFindDataMatrix(&m);
|
||||
codes.clear();
|
||||
codes.resize(rc.size());
|
||||
std::transform(rc.begin(),rc.end(),codes.begin(),CvDM2DM_transform());
|
||||
Mat image = _image.getMat();
|
||||
Mat corners = _corners.getMat();
|
||||
int i, n = corners.rows;
|
||||
|
||||
if( n > 0 )
|
||||
{
|
||||
CV_Assert( corners.depth() == CV_32S &&
|
||||
corners.cols*corners.channels() == 8 &&
|
||||
n == (int)codes.size() );
|
||||
}
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
Scalar c(0, 255, 0);
|
||||
Scalar c2(255, 0,0);
|
||||
const Point* pt = (const Point*)corners.ptr(i);
|
||||
|
||||
for( int k = 0; k < 4; k++ )
|
||||
line(image, pt[k], pt[(k+1)%4], c);
|
||||
//int baseline = 0;
|
||||
//Size sz = getTextSize(code_text, CV_FONT_HERSHEY_SIMPLEX, 1, 1, &baseline);
|
||||
putText(image, codes[i], pt[0], CV_FONT_HERSHEY_SIMPLEX, 0.8, c2, 1, CV_AA, false);
|
||||
}
|
||||
}
|
||||
|
||||
void drawDataMatrixCodes(const std::vector<DataMatrixCode>& codes, Mat& drawImage)
|
||||
{
|
||||
std::for_each(codes.begin(),codes.end(),DrawDataMatrixCode(drawImage));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
43
modules/objdetect/src/objdetect_init.cpp
Normal file
43
modules/objdetect/src/objdetect_init.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/*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 "precomp.hpp"
|
@@ -61,23 +61,17 @@ const CvRect true_bounding_boxes[3] = {cvRect(0, 45, 362, 452), cvRect(304, 0, 6
|
||||
|
||||
class CV_LatentSVMDetectorTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_LatentSVMDetectorTest();
|
||||
~CV_LatentSVMDetectorTest();
|
||||
protected:
|
||||
void run(int);
|
||||
bool isEqual(CvRect r1, CvRect r2);
|
||||
bool isEqual(CvRect r1, CvRect r2, int eps);
|
||||
};
|
||||
|
||||
CV_LatentSVMDetectorTest::CV_LatentSVMDetectorTest()
|
||||
bool CV_LatentSVMDetectorTest::isEqual(CvRect r1, CvRect r2, int eps)
|
||||
{
|
||||
}
|
||||
|
||||
CV_LatentSVMDetectorTest::~CV_LatentSVMDetectorTest() {}
|
||||
|
||||
bool CV_LatentSVMDetectorTest::isEqual(CvRect r1, CvRect r2)
|
||||
{
|
||||
return ((r1.x == r2.x) && (r1.y == r2.y) && (r1.width == r2.width) && (r1.height == r2.height));
|
||||
return (std::abs(r1.x - r2.x) <= eps
|
||||
&& std::abs(r1.y - r2.y) <= eps
|
||||
&& std::abs(r1.width - r2.width) <= eps
|
||||
&& std::abs(r1.height - r2.height) <= eps);
|
||||
}
|
||||
|
||||
void CV_LatentSVMDetectorTest::run( int /* start_from */)
|
||||
@@ -85,53 +79,55 @@ void CV_LatentSVMDetectorTest::run( int /* start_from */)
|
||||
string img_path = string(ts->get_data_path()) + "latentsvmdetector/cat.jpg";
|
||||
string model_path = string(ts->get_data_path()) + "latentsvmdetector/models_VOC2007/cat.xml";
|
||||
int numThreads = -1;
|
||||
|
||||
#ifdef HAVE_TBB
|
||||
numThreads = 2;
|
||||
tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred);
|
||||
init.initialize(numThreads);
|
||||
init.initialize(numThreads);
|
||||
#endif
|
||||
IplImage* image = cvLoadImage(img_path.c_str());
|
||||
if (!image)
|
||||
|
||||
IplImage* image = cvLoadImage(img_path.c_str());
|
||||
if (!image)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
return;
|
||||
}
|
||||
|
||||
CvLatentSvmDetector* detector = cvLoadLatentSvmDetector(model_path.c_str());
|
||||
if (!detector)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
cvReleaseImage(&image);
|
||||
return;
|
||||
}
|
||||
CvLatentSvmDetector* detector = cvLoadLatentSvmDetector(model_path.c_str());
|
||||
if (!detector)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
|
||||
cvReleaseImage(&image);
|
||||
return;
|
||||
}
|
||||
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* detections = 0;
|
||||
detections = cvLatentSvmDetectObjects(image, detector, storage, 0.5f, numThreads);
|
||||
if (detections->total != num_detections)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
}
|
||||
else
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
for (int i = 0; i < detections->total; i++)
|
||||
{
|
||||
CvObjectDetection detection = *(CvObjectDetection*)cvGetSeqElem( detections, i );
|
||||
CvRect bounding_box = detection.rect;
|
||||
float score = detection.score;
|
||||
if ((!isEqual(bounding_box, true_bounding_boxes[i])) || (fabs(score - true_scores[i]) > score_thr))
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (detections->total != num_detections)
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
}
|
||||
else
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
for (int i = 0; i < detections->total; i++)
|
||||
{
|
||||
CvObjectDetection detection = *(CvObjectDetection*)cvGetSeqElem( detections, i );
|
||||
CvRect bounding_box = detection.rect;
|
||||
float score = detection.score;
|
||||
if ((!isEqual(bounding_box, true_bounding_boxes[i], 1)) || (fabs(score - true_scores[i]) > score_thr))
|
||||
{
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_TBB
|
||||
init.terminate();
|
||||
#endif
|
||||
cvReleaseMemStorage( &storage );
|
||||
cvReleaseLatentSvmDetector( &detector );
|
||||
cvReleaseMemStorage( &storage );
|
||||
cvReleaseLatentSvmDetector( &detector );
|
||||
cvReleaseImage( &image );
|
||||
}
|
||||
|
||||
@@ -139,16 +135,10 @@ void CV_LatentSVMDetectorTest::run( int /* start_from */)
|
||||
|
||||
class LatentSVMDetectorTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
LatentSVMDetectorTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
LatentSVMDetectorTest::LatentSVMDetectorTest()
|
||||
{
|
||||
}
|
||||
|
||||
static void writeDetections( FileStorage& fs, const string& nodeName, const vector<LatentSvmDetector::ObjectDetection>& detections )
|
||||
{
|
||||
fs << nodeName << "[";
|
||||
@@ -176,14 +166,24 @@ static void readDetections( FileStorage fs, const string& nodeName, vector<Laten
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool isEqual( const LatentSvmDetector::ObjectDetection& d1, const LatentSvmDetector::ObjectDetection& d2)
|
||||
static inline bool isEqual( const LatentSvmDetector::ObjectDetection& d1, const LatentSvmDetector::ObjectDetection& d2, int eps, float threshold)
|
||||
{
|
||||
return ((d1.rect.x == d2.rect.x) && (d1.rect.y == d2.rect.y) && (d1.rect.width == d2.rect.width) && (d1.rect.height == d2.rect.height) &&
|
||||
(d1.classID == d2.classID) &&
|
||||
std::abs(d1.score-d2.score) < score_thr );
|
||||
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 vector<LatentSvmDetector::ObjectDetection>& calc, const vector<LatentSvmDetector::ObjectDetection>& valid )
|
||||
std::ostream& operator << (std::ostream& os, const CvRect& r)
|
||||
{
|
||||
return (os << "[x=" << r.x << ", y=" << r.y << ", w=" << r.width << ", h=" << r.height << "]");
|
||||
}
|
||||
|
||||
bool compareResults( const vector<LatentSvmDetector::ObjectDetection>& calc, const vector<LatentSvmDetector::ObjectDetection>& valid, int eps, float threshold)
|
||||
{
|
||||
if( calc.size() != valid.size() )
|
||||
return false;
|
||||
@@ -192,8 +192,12 @@ bool compareResults( const vector<LatentSvmDetector::ObjectDetection>& calc, con
|
||||
{
|
||||
const LatentSvmDetector::ObjectDetection& c = calc[i];
|
||||
const LatentSvmDetector::ObjectDetection& v = valid[i];
|
||||
if( !isEqual(c,v) )
|
||||
if( !isEqual(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;
|
||||
}
|
||||
@@ -209,9 +213,11 @@ void LatentSVMDetectorTest::run( int /* start_from */)
|
||||
string true_res_path = string(ts->get_data_path()) + "latentsvmdetector/results.xml";
|
||||
|
||||
int numThreads = 1;
|
||||
|
||||
#ifdef HAVE_TBB
|
||||
numThreads = 2;
|
||||
#endif
|
||||
|
||||
Mat image_cat = imread( img_path_cat );
|
||||
Mat image_cars = imread( img_path_cars );
|
||||
if( image_cat.empty() || image_cars.empty() )
|
||||
@@ -255,17 +261,17 @@ void LatentSVMDetectorTest::run( int /* start_from */)
|
||||
readDetections( fs, "detections12_cars", true_detections12_cars );
|
||||
|
||||
|
||||
if( !compareResults(detections1_cat, true_detections1_cat) )
|
||||
if( !compareResults(detections1_cat, true_detections1_cat, 1, score_thr) )
|
||||
{
|
||||
std::cerr << "Results of detector1 are invalid on image cat.jpg" << std::endl;
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
}
|
||||
if( !compareResults(detections12_cat, true_detections12_cat) )
|
||||
if( !compareResults(detections12_cat, true_detections12_cat, 1, score_thr) )
|
||||
{
|
||||
std::cerr << "Results of detector12 are invalid on image cat.jpg" << std::endl;
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
}
|
||||
if( !compareResults(detections12_cars, true_detections12_cars) )
|
||||
if( !compareResults(detections12_cars, true_detections12_cars, 1, score_thr) )
|
||||
{
|
||||
std::cerr << "Results of detector12 are invalid on image cars.jpg" << std::endl;
|
||||
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
|
||||
|
Reference in New Issue
Block a user