This commit is contained in:
commit
3fcdbbe734
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ OpenCV4Tegra/
|
||||
.sw[a-z]
|
||||
.*.swp
|
||||
tags
|
||||
build/
|
||||
|
@ -85,7 +85,7 @@ The output of the function can be used for robust edge or corner detection.
|
||||
|
||||
cornerHarris
|
||||
------------
|
||||
Harris edge detector.
|
||||
Harris corner detector.
|
||||
|
||||
.. ocv:function:: void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT )
|
||||
|
||||
@ -105,7 +105,7 @@ Harris edge detector.
|
||||
|
||||
:param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` .
|
||||
|
||||
The function runs the Harris edge detector on the image. Similarly to
|
||||
The function runs the Harris corner detector on the image. Similarly to
|
||||
:ocv:func:`cornerMinEigenVal` and
|
||||
:ocv:func:`cornerEigenValsAndVecs` , for each pixel
|
||||
:math:`(x, y)` it calculates a
|
||||
|
@ -863,7 +863,7 @@ public:
|
||||
* * 1 corresponds to 0.1 mean false alarms
|
||||
* This vector will be calculated _only_ when the objects type is REFINE_ADV
|
||||
*/
|
||||
virtual void detect(const InputArray _image, OutputArray _lines,
|
||||
virtual void detect(InputArray _image, OutputArray _lines,
|
||||
OutputArray width = noArray(), OutputArray prec = noArray(),
|
||||
OutputArray nfa = noArray()) = 0;
|
||||
|
||||
@ -874,7 +874,7 @@ public:
|
||||
* Should have the size of the image, where the lines were found
|
||||
* @param lines The lines that need to be drawn
|
||||
*/
|
||||
virtual void drawSegments(InputOutputArray image, const InputArray lines) = 0;
|
||||
virtual void drawSegments(InputOutputArray image, InputArray lines) = 0;
|
||||
|
||||
/**
|
||||
* Draw both vectors on the image canvas. Uses blue for lines 1 and red for lines 2.
|
||||
@ -885,7 +885,7 @@ public:
|
||||
* @param lines2 The second lines that need to be drawn. Color - Red.
|
||||
* @return The number of mismatching pixels between lines1 and lines2.
|
||||
*/
|
||||
virtual int compareSegments(const Size& size, const InputArray lines1, const InputArray lines2, Mat* image = 0) = 0;
|
||||
virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, Mat* image = 0) = 0;
|
||||
|
||||
virtual ~LineSegmentDetector() {};
|
||||
};
|
||||
|
@ -205,7 +205,7 @@ public:
|
||||
* * 1 corresponds to 0.1 mean false alarms
|
||||
* This vector will be calculated _only_ when the objects type is REFINE_ADV
|
||||
*/
|
||||
void detect(const InputArray _image, OutputArray _lines,
|
||||
void detect(InputArray _image, OutputArray _lines,
|
||||
OutputArray width = noArray(), OutputArray prec = noArray(),
|
||||
OutputArray nfa = noArray());
|
||||
|
||||
@ -216,7 +216,7 @@ public:
|
||||
* Should have the size of the image, where the lines were found
|
||||
* @param lines The lines that need to be drawn
|
||||
*/
|
||||
void drawSegments(InputOutputArray image, const InputArray lines);
|
||||
void drawSegments(InputOutputArray image, InputArray lines);
|
||||
|
||||
/**
|
||||
* Draw both vectors on the image canvas. Uses blue for lines 1 and red for lines 2.
|
||||
@ -227,7 +227,7 @@ public:
|
||||
* @param lines2 The second lines that need to be drawn. Color - Red.
|
||||
* @return The number of mismatching pixels between lines1 and lines2.
|
||||
*/
|
||||
int compareSegments(const Size& size, const InputArray lines1, const InputArray lines2, Mat* image = 0);
|
||||
int compareSegments(const Size& size, InputArray lines1, InputArray lines2, Mat* image = 0);
|
||||
|
||||
private:
|
||||
Mat image;
|
||||
|
@ -12,23 +12,20 @@ Cascade classifier class used for object detection. Supports HAAR cascade classi
|
||||
class CV_EXPORTS OclCascadeClassifier : public CascadeClassifier
|
||||
{
|
||||
public:
|
||||
OclCascadeClassifier() {};
|
||||
~OclCascadeClassifier() {};
|
||||
CvSeq *oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage,
|
||||
double scaleFactor,int minNeighbors,
|
||||
int flags, CvSize minSize = cvSize(0, 0),
|
||||
CvSize maxSize = cvSize(0, 0));
|
||||
void detectMultiScale(oclMat &image, CV_OUT std::vector<cv::Rect>& faces,
|
||||
double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0,
|
||||
Size minSize = Size(), Size maxSize = Size());
|
||||
};
|
||||
|
||||
ocl::OclCascadeClassifier::oclHaarDetectObjects
|
||||
------------------------------------------------------
|
||||
Returns the detected objects by a list of rectangles
|
||||
Detects objects of different sizes in the input image.
|
||||
|
||||
.. ocv:function:: CvSeq* ocl::OclCascadeClassifier::oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage, double scaleFactor,int minNeighbors, int flags, CvSize minSize = cvSize(0, 0), CvSize maxSize = cvSize(0, 0))
|
||||
.. ocv:function:: void ocl::OclCascadeClassifier::detectMultiScale(oclMat &image, std::vector<cv::Rect>& faces, double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size())
|
||||
|
||||
:param image: Matrix of type CV_8U containing an image where objects should be detected.
|
||||
|
||||
:param imageobjectsBuff: Buffer to store detected objects (rectangles). If it is empty, it is allocated with the defaultsize. If not empty, the function searches not more than N objects, where N = sizeof(objectsBufers data)/sizeof(cv::Rect).
|
||||
:param faces: Vector of rectangles where each rectangle contains the detected object.
|
||||
|
||||
:param scaleFactor: Parameter specifying how much the image size is reduced at each image scale.
|
||||
|
||||
@ -36,7 +33,9 @@ Returns the detected objects by a list of rectangles
|
||||
|
||||
:param minSize: Minimum possible object size. Objects smaller than that are ignored.
|
||||
|
||||
Detects objects of different sizes in the input image,only tested for face detection now. The function returns the number of detected objects.
|
||||
:param maxSize: Maximum possible object size. Objects larger than that are ignored.
|
||||
|
||||
The function provides a very similar interface with that in CascadeClassifier class, except using oclMat as input image.
|
||||
|
||||
ocl::MatchTemplateBuf
|
||||
---------------------
|
||||
|
@ -869,59 +869,13 @@ namespace cv
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////CascadeClassifier//////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
class CV_EXPORTS OclCascadeClassifier : public cv::CascadeClassifier
|
||||
{
|
||||
public:
|
||||
OclCascadeClassifier() {};
|
||||
~OclCascadeClassifier() {};
|
||||
|
||||
CvSeq* oclHaarDetectObjects(oclMat &gimg, CvMemStorage *storage, double scaleFactor,
|
||||
int minNeighbors, int flags, CvSize minSize = cvSize(0, 0), CvSize maxSize = cvSize(0, 0));
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
class CV_EXPORTS OclCascadeClassifierBuf : public cv::CascadeClassifier
|
||||
{
|
||||
public:
|
||||
OclCascadeClassifierBuf() :
|
||||
m_flags(0), initialized(false), m_scaleFactor(0), buffers(NULL) {}
|
||||
|
||||
~OclCascadeClassifierBuf() { release(); }
|
||||
|
||||
void detectMultiScale(oclMat &image, CV_OUT std::vector<cv::Rect>& faces,
|
||||
double scaleFactor = 1.1, int minNeighbors = 3, int flags = 0,
|
||||
Size minSize = Size(), Size maxSize = Size());
|
||||
void release();
|
||||
|
||||
private:
|
||||
void Init(const int rows, const int cols, double scaleFactor, int flags,
|
||||
const int outputsz, const size_t localThreads[],
|
||||
Size minSize, Size maxSize);
|
||||
void CreateBaseBufs(const int datasize, const int totalclassifier, const int flags, const int outputsz);
|
||||
void CreateFactorRelatedBufs(const int rows, const int cols, const int flags,
|
||||
const double scaleFactor, const size_t localThreads[],
|
||||
Size minSize, Size maxSize);
|
||||
void GenResult(CV_OUT std::vector<cv::Rect>& faces, const std::vector<cv::Rect> &rectList, const std::vector<int> &rweights);
|
||||
|
||||
int m_rows;
|
||||
int m_cols;
|
||||
int m_flags;
|
||||
int m_loopcount;
|
||||
int m_nodenum;
|
||||
bool findBiggestObject;
|
||||
bool initialized;
|
||||
double m_scaleFactor;
|
||||
Size m_minSize;
|
||||
Size m_maxSize;
|
||||
std::vector<Size> sizev;
|
||||
std::vector<float> scalev;
|
||||
oclMat gimg1, gsum, gsqsum;
|
||||
void * buffers;
|
||||
};
|
||||
#endif
|
||||
|
||||
/////////////////////////////// Pyramid /////////////////////////////////////
|
||||
CV_EXPORTS void pyrDown(const oclMat &src, oclMat &dst);
|
||||
|
@ -44,47 +44,8 @@
|
||||
//
|
||||
//M*/
|
||||
#include "precomp.hpp"
|
||||
|
||||
#if 0
|
||||
|
||||
///////////// Haar ////////////////////////
|
||||
namespace cv
|
||||
{
|
||||
namespace ocl
|
||||
{
|
||||
|
||||
struct getRect
|
||||
{
|
||||
Rect operator()(const CvAvgComp &e) const
|
||||
{
|
||||
return e.rect;
|
||||
}
|
||||
};
|
||||
|
||||
class CascadeClassifier_GPU : public OclCascadeClassifier
|
||||
{
|
||||
public:
|
||||
void detectMultiScale(oclMat &image,
|
||||
CV_OUT std::vector<cv::Rect>& faces,
|
||||
double scaleFactor = 1.1,
|
||||
int minNeighbors = 3, int flags = 0,
|
||||
Size minSize = Size(),
|
||||
Size maxSize = Size())
|
||||
{
|
||||
(void)maxSize;
|
||||
MemStorage storage(cvCreateMemStorage(0));
|
||||
//CvMat img=image;
|
||||
CvSeq *objs = oclHaarDetectObjects(image, storage, scaleFactor, minNeighbors, flags, minSize);
|
||||
vector<CvAvgComp> vecAvgComp;
|
||||
Seq<CvAvgComp>(objs).copyTo(vecAvgComp);
|
||||
faces.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), faces.begin(), getRect());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
PERFTEST(Haar)
|
||||
{
|
||||
Mat img = imread(abspath("basketball1.png"), IMREAD_GRAYSCALE);
|
||||
@ -106,12 +67,12 @@ PERFTEST(Haar)
|
||||
SUBTEST << img.cols << "x" << img.rows << "; scale image";
|
||||
CPU_ON;
|
||||
faceCascadeCPU.detectMultiScale(img, faces,
|
||||
1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
|
||||
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
|
||||
CPU_OFF;
|
||||
|
||||
|
||||
vector<Rect> oclfaces;
|
||||
ocl::CascadeClassifier_GPU faceCascade;
|
||||
ocl::OclCascadeClassifier faceCascade;
|
||||
|
||||
if (!faceCascade.load(abspath("haarcascade_frontalface_alt.xml")))
|
||||
{
|
||||
@ -122,7 +83,7 @@ PERFTEST(Haar)
|
||||
|
||||
WARMUP_ON;
|
||||
faceCascade.detectMultiScale(d_img, oclfaces,
|
||||
1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
|
||||
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
|
||||
WARMUP_OFF;
|
||||
|
||||
if(faces.size() == oclfaces.size())
|
||||
@ -134,14 +95,12 @@ PERFTEST(Haar)
|
||||
|
||||
GPU_ON;
|
||||
faceCascade.detectMultiScale(d_img, oclfaces,
|
||||
1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
|
||||
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
|
||||
GPU_OFF;
|
||||
|
||||
GPU_FULL_ON;
|
||||
d_img.upload(img);
|
||||
faceCascade.detectMultiScale(d_img, oclfaces,
|
||||
1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
|
||||
1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
|
||||
GPU_FULL_OFF;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
@ -20,7 +20,6 @@
|
||||
// Jia Haipeng, jiahaipeng95@gmail.com
|
||||
// Wu Xinglong, wxl370@126.com
|
||||
// Wang Yao, bitwangyaoyao@gmail.com
|
||||
// Sen Liu, swjtuls1987@126.com
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
@ -54,8 +53,6 @@
|
||||
using namespace cv;
|
||||
using namespace cv::ocl;
|
||||
|
||||
#if 0
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace ocl
|
||||
@ -68,9 +65,9 @@ extern const char *haarobjectdetect_scaled2;
|
||||
}
|
||||
|
||||
/* these settings affect the quality of detection: change with care */
|
||||
#define CV_ADJUST_FEATURES 1
|
||||
#define CV_ADJUST_WEIGHTS 0
|
||||
|
||||
#define CV_ADJUST_FEATURES 1
|
||||
#define CV_ADJUST_WEIGHTS 0
|
||||
#define CV_HAAR_FEATURE_MAX 3
|
||||
typedef int sumtype;
|
||||
typedef double sqsumtype;
|
||||
|
||||
@ -679,14 +676,15 @@ static void gpuSetHaarClassifierCascade( CvHaarClassifierCascade *_cascade)
|
||||
} /* j */
|
||||
}
|
||||
}
|
||||
|
||||
CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemStorage *storage, double scaleFactor,
|
||||
int minNeighbors, int flags, CvSize minSize, CvSize maxSize)
|
||||
void OclCascadeClassifier::detectMultiScale(oclMat &gimg, CV_OUT std::vector<cv::Rect>& faces,
|
||||
double scaleFactor, int minNeighbors, int flags,
|
||||
Size minSize, Size maxSize)
|
||||
//CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemStorage *storage, double scaleFactor,
|
||||
// int minNeighbors, int flags, CvSize minSize, CvSize maxSize)
|
||||
{
|
||||
CvHaarClassifierCascade *cascade = oldCascade;
|
||||
|
||||
const double GROUP_EPS = 0.2;
|
||||
CvSeq *result_seq = 0;
|
||||
|
||||
cv::ConcurrentRectVector allCandidates;
|
||||
std::vector<cv::Rect> rectList;
|
||||
@ -714,8 +712,8 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
if( !CV_IS_HAAR_CLASSIFIER(cascade) )
|
||||
CV_Error( !cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier cascade" );
|
||||
|
||||
if( !storage )
|
||||
CV_Error( CV_StsNullPtr, "Null storage pointer" );
|
||||
//if( !storage )
|
||||
// CV_Error( CV_StsNullPtr, "Null storage pointer" );
|
||||
|
||||
if( CV_MAT_DEPTH(gimg.type()) != CV_8U )
|
||||
CV_Error( CV_StsUnsupportedFormat, "Only 8-bit images are supported" );
|
||||
@ -729,7 +727,7 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
if( !cascade->hid_cascade )
|
||||
gpuCreateHidHaarClassifierCascade(cascade, &datasize, &totalclassifier);
|
||||
|
||||
result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), storage );
|
||||
//result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), storage );
|
||||
|
||||
if( CV_MAT_CN(gimg.type()) > 1 )
|
||||
{
|
||||
@ -1028,7 +1026,7 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
args.push_back ( std::make_pair(sizeof(cl_mem) , (void *)&pbuffer ));
|
||||
args.push_back ( std::make_pair(sizeof(cl_mem) , (void *)&correctionbuffer ));
|
||||
args.push_back ( std::make_pair(sizeof(cl_int) , (void *)&nodenum ));
|
||||
|
||||
const char * build_options = gcascade->is_stump_based ? "-D STUMP_BASED=1" : "-D STUMP_BASED=0";
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect_scaled2, "gpuRunHaarClassifierCascade_scaled2", globalThreads, localThreads, args, -1, -1, build_options);
|
||||
|
||||
candidate = (int *)clEnqueueMapBuffer(qu, candidatebuffer, 1, CL_MAP_READ, 0, 4 * sizeof(int) * outputsz, 0, 0, 0, &status);
|
||||
@ -1062,623 +1060,22 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
else
|
||||
rweights.resize(rectList.size(), 0);
|
||||
|
||||
faces.clear();
|
||||
if( findBiggestObject && rectList.size() )
|
||||
{
|
||||
CvAvgComp result_comp = {{0, 0, 0, 0}, 0};
|
||||
|
||||
Rect result_comp(0, 0, 0, 0);
|
||||
for( size_t i = 0; i < rectList.size(); i++ )
|
||||
{
|
||||
cv::Rect r = rectList[i];
|
||||
if( r.area() > cv::Rect(result_comp.rect).area() )
|
||||
if( r.area() > result_comp.area() )
|
||||
{
|
||||
result_comp.rect = r;
|
||||
result_comp.neighbors = rweights[i];
|
||||
result_comp = r;
|
||||
}
|
||||
}
|
||||
cvSeqPush( result_seq, &result_comp );
|
||||
faces.push_back(result_comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
for( size_t i = 0; i < rectList.size(); i++ )
|
||||
{
|
||||
CvAvgComp c;
|
||||
c.rect = rectList[i];
|
||||
c.neighbors = rweights[i];
|
||||
cvSeqPush( result_seq, &c );
|
||||
}
|
||||
}
|
||||
|
||||
return result_seq;
|
||||
}
|
||||
|
||||
struct OclBuffers
|
||||
{
|
||||
cl_mem stagebuffer;
|
||||
cl_mem nodebuffer;
|
||||
cl_mem candidatebuffer;
|
||||
cl_mem scaleinfobuffer;
|
||||
cl_mem pbuffer;
|
||||
cl_mem correctionbuffer;
|
||||
cl_mem newnodebuffer;
|
||||
};
|
||||
|
||||
struct getRect
|
||||
{
|
||||
Rect operator()(const CvAvgComp &e) const
|
||||
{
|
||||
return e.rect;
|
||||
}
|
||||
};
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::detectMultiScale(oclMat &gimg, CV_OUT std::vector<cv::Rect>& faces,
|
||||
double scaleFactor, int minNeighbors, int flags,
|
||||
Size minSize, Size maxSize)
|
||||
{
|
||||
int blocksize = 8;
|
||||
int grp_per_CU = 12;
|
||||
size_t localThreads[3] = { blocksize, blocksize, 1 };
|
||||
size_t globalThreads[3] = { grp_per_CU * cv::ocl::Context::getContext()->computeUnits() *localThreads[0],
|
||||
localThreads[1],
|
||||
1 };
|
||||
int outputsz = 256 * globalThreads[0] / localThreads[0];
|
||||
|
||||
Init(gimg.rows, gimg.cols, scaleFactor, flags, outputsz, localThreads, minSize, maxSize);
|
||||
|
||||
const double GROUP_EPS = 0.2;
|
||||
|
||||
cv::ConcurrentRectVector allCandidates;
|
||||
std::vector<cv::Rect> rectList;
|
||||
std::vector<int> rweights;
|
||||
|
||||
CvHaarClassifierCascade *cascade = oldCascade;
|
||||
GpuHidHaarClassifierCascade *gcascade;
|
||||
GpuHidHaarStageClassifier *stage;
|
||||
|
||||
if( CV_MAT_DEPTH(gimg.type()) != CV_8U )
|
||||
CV_Error( CV_StsUnsupportedFormat, "Only 8-bit images are supported" );
|
||||
|
||||
if( CV_MAT_CN(gimg.type()) > 1 )
|
||||
{
|
||||
oclMat gtemp;
|
||||
cvtColor( gimg, gtemp, CV_BGR2GRAY );
|
||||
gimg = gtemp;
|
||||
}
|
||||
|
||||
int *candidate;
|
||||
cl_command_queue qu = reinterpret_cast<cl_command_queue>(Context::getContext()->oclCommandQueue());
|
||||
if( (flags & CV_HAAR_SCALE_IMAGE) )
|
||||
{
|
||||
int indexy = 0;
|
||||
CvSize sz;
|
||||
|
||||
cv::Rect roi, roi2;
|
||||
cv::Mat imgroi, imgroisq;
|
||||
cv::ocl::oclMat resizeroi, gimgroi, gimgroisq;
|
||||
|
||||
for( int i = 0; i < m_loopcount; i++ )
|
||||
{
|
||||
sz = sizev[i];
|
||||
roi = Rect(0, indexy, sz.width, sz.height);
|
||||
roi2 = Rect(0, 0, sz.width - 1, sz.height - 1);
|
||||
resizeroi = gimg1(roi2);
|
||||
gimgroi = gsum(roi);
|
||||
gimgroisq = gsqsum(roi);
|
||||
|
||||
cv::ocl::resize(gimg, resizeroi, Size(sz.width - 1, sz.height - 1), 0, 0, INTER_LINEAR);
|
||||
cv::ocl::integral(resizeroi, gimgroi, gimgroisq);
|
||||
indexy += sz.height;
|
||||
}
|
||||
|
||||
gcascade = (GpuHidHaarClassifierCascade *)(cascade->hid_cascade);
|
||||
stage = (GpuHidHaarStageClassifier *)(gcascade + 1);
|
||||
|
||||
int startstage = 0;
|
||||
int endstage = gcascade->count;
|
||||
int startnode = 0;
|
||||
int pixelstep = gsum.step / 4;
|
||||
int splitstage = 3;
|
||||
int splitnode = stage[0].count + stage[1].count + stage[2].count;
|
||||
cl_int4 p, pq;
|
||||
p.s[0] = gcascade->p0;
|
||||
p.s[1] = gcascade->p1;
|
||||
p.s[2] = gcascade->p2;
|
||||
p.s[3] = gcascade->p3;
|
||||
pq.s[0] = gcascade->pq0;
|
||||
pq.s[1] = gcascade->pq1;
|
||||
pq.s[2] = gcascade->pq2;
|
||||
pq.s[3] = gcascade->pq3;
|
||||
float correction = gcascade->inv_window_area;
|
||||
|
||||
vector<pair<size_t, const void *> > args;
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->stagebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->scaleinfobuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->nodebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&gsum.data ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&gsqsum.data ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->candidatebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&pixelstep ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&m_loopcount ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&startstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&splitstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&endstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&startnode ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&splitnode ));
|
||||
args.push_back ( make_pair(sizeof(cl_int4) , (void *)&p ));
|
||||
args.push_back ( make_pair(sizeof(cl_int4) , (void *)&pq ));
|
||||
args.push_back ( make_pair(sizeof(cl_float) , (void *)&correction ));
|
||||
|
||||
const char * build_options = gcascade->is_stump_based ? "-D STUMP_BASED=1" : "-D STUMP_BASED=0";
|
||||
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect, "gpuRunHaarClassifierCascade", globalThreads, localThreads, args, -1, -1, build_options);
|
||||
|
||||
candidate = (int *)malloc(4 * sizeof(int) * outputsz);
|
||||
memset(candidate, 0, 4 * sizeof(int) * outputsz);
|
||||
|
||||
openCLReadBuffer( gsum.clCxt, ((OclBuffers *)buffers)->candidatebuffer, candidate, 4 * sizeof(int)*outputsz );
|
||||
|
||||
for(int i = 0; i < outputsz; i++)
|
||||
{
|
||||
if(candidate[4 * i + 2] != 0)
|
||||
{
|
||||
allCandidates.push_back(Rect(candidate[4 * i], candidate[4 * i + 1],
|
||||
candidate[4 * i + 2], candidate[4 * i + 3]));
|
||||
}
|
||||
}
|
||||
free((void *)candidate);
|
||||
candidate = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::ocl::integral(gimg, gsum, gsqsum);
|
||||
|
||||
gcascade = (GpuHidHaarClassifierCascade *)cascade->hid_cascade;
|
||||
|
||||
int step = gsum.step / 4;
|
||||
int startnode = 0;
|
||||
int splitstage = 3;
|
||||
|
||||
int startstage = 0;
|
||||
int endstage = gcascade->count;
|
||||
|
||||
vector<pair<size_t, const void *> > args;
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->stagebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->scaleinfobuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->newnodebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&gsum.data ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&gsqsum.data ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->candidatebuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&gsum.rows ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&gsum.cols ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&step ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&m_loopcount ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&startstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&splitstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&endstage ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&startnode ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->pbuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->correctionbuffer ));
|
||||
args.push_back ( make_pair(sizeof(cl_int) , (void *)&m_nodenum ));
|
||||
|
||||
const char * build_options = gcascade->is_stump_based ? "-D STUMP_BASED=1" : "-D STUMP_BASED=0";
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect_scaled2, "gpuRunHaarClassifierCascade_scaled2", globalThreads, localThreads, args, -1, -1, build_options);
|
||||
|
||||
candidate = (int *)clEnqueueMapBuffer(qu, ((OclBuffers *)buffers)->candidatebuffer, 1, CL_MAP_READ, 0, 4 * sizeof(int) * outputsz, 0, 0, 0, NULL);
|
||||
|
||||
for(int i = 0; i < outputsz; i++)
|
||||
{
|
||||
if(candidate[4 * i + 2] != 0)
|
||||
allCandidates.push_back(Rect(candidate[4 * i], candidate[4 * i + 1],
|
||||
candidate[4 * i + 2], candidate[4 * i + 3]));
|
||||
}
|
||||
clEnqueueUnmapMemObject(qu, ((OclBuffers *)buffers)->candidatebuffer, candidate, 0, 0, 0);
|
||||
}
|
||||
rectList.resize(allCandidates.size());
|
||||
if(!allCandidates.empty())
|
||||
std::copy(allCandidates.begin(), allCandidates.end(), rectList.begin());
|
||||
|
||||
if( minNeighbors != 0 || findBiggestObject )
|
||||
groupRectangles(rectList, rweights, std::max(minNeighbors, 1), GROUP_EPS);
|
||||
else
|
||||
rweights.resize(rectList.size(), 0);
|
||||
|
||||
GenResult(faces, rectList, rweights);
|
||||
}
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::Init(const int rows, const int cols,
|
||||
double scaleFactor, int flags,
|
||||
const int outputsz, const size_t localThreads[],
|
||||
CvSize minSize, CvSize maxSize)
|
||||
{
|
||||
if(initialized)
|
||||
{
|
||||
return; // we only allow one time initialization
|
||||
}
|
||||
CvHaarClassifierCascade *cascade = oldCascade;
|
||||
|
||||
if( !CV_IS_HAAR_CLASSIFIER(cascade) )
|
||||
CV_Error( !cascade ? CV_StsNullPtr : CV_StsBadArg, "Invalid classifier cascade" );
|
||||
|
||||
if( scaleFactor <= 1 )
|
||||
CV_Error( CV_StsOutOfRange, "scale factor must be > 1" );
|
||||
|
||||
if( cols < minSize.width || rows < minSize.height )
|
||||
CV_Error(CV_StsError, "Image too small");
|
||||
|
||||
int datasize=0;
|
||||
int totalclassifier=0;
|
||||
|
||||
if( !cascade->hid_cascade )
|
||||
{
|
||||
gpuCreateHidHaarClassifierCascade(cascade, &datasize, &totalclassifier);
|
||||
}
|
||||
|
||||
if( maxSize.height == 0 || maxSize.width == 0 )
|
||||
{
|
||||
maxSize.height = rows;
|
||||
maxSize.width = cols;
|
||||
}
|
||||
|
||||
findBiggestObject = (flags & CV_HAAR_FIND_BIGGEST_OBJECT) != 0;
|
||||
if( findBiggestObject )
|
||||
flags &= ~(CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING);
|
||||
|
||||
CreateBaseBufs(datasize, totalclassifier, flags, outputsz);
|
||||
CreateFactorRelatedBufs(rows, cols, flags, scaleFactor, localThreads, minSize, maxSize);
|
||||
|
||||
m_scaleFactor = scaleFactor;
|
||||
m_rows = rows;
|
||||
m_cols = cols;
|
||||
m_flags = flags;
|
||||
m_minSize = minSize;
|
||||
m_maxSize = maxSize;
|
||||
|
||||
// initialize nodes
|
||||
GpuHidHaarClassifierCascade *gcascade;
|
||||
GpuHidHaarStageClassifier *stage;
|
||||
GpuHidHaarClassifier *classifier;
|
||||
GpuHidHaarTreeNode *node;
|
||||
cl_command_queue qu = reinterpret_cast<cl_command_queue>(Context::getContext()->oclCommandQueue());
|
||||
if( (flags & CV_HAAR_SCALE_IMAGE) )
|
||||
{
|
||||
gcascade = (GpuHidHaarClassifierCascade *)(cascade->hid_cascade);
|
||||
stage = (GpuHidHaarStageClassifier *)(gcascade + 1);
|
||||
classifier = (GpuHidHaarClassifier *)(stage + gcascade->count);
|
||||
node = (GpuHidHaarTreeNode *)(classifier->node);
|
||||
|
||||
gpuSetImagesForHaarClassifierCascade( cascade, 1., gsum.step / 4 );
|
||||
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->stagebuffer, 1, 0,
|
||||
sizeof(GpuHidHaarStageClassifier) * gcascade->count,
|
||||
stage, 0, NULL, NULL));
|
||||
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->nodebuffer, 1, 0,
|
||||
m_nodenum * sizeof(GpuHidHaarTreeNode),
|
||||
node, 0, NULL, NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
gpuSetHaarClassifierCascade(cascade);
|
||||
|
||||
gcascade = (GpuHidHaarClassifierCascade *)cascade->hid_cascade;
|
||||
stage = (GpuHidHaarStageClassifier *)(gcascade + 1);
|
||||
classifier = (GpuHidHaarClassifier *)(stage + gcascade->count);
|
||||
node = (GpuHidHaarTreeNode *)(classifier->node);
|
||||
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->nodebuffer, 1, 0,
|
||||
m_nodenum * sizeof(GpuHidHaarTreeNode),
|
||||
node, 0, NULL, NULL));
|
||||
|
||||
cl_int4 *p = (cl_int4 *)malloc(sizeof(cl_int4) * m_loopcount);
|
||||
float *correction = (float *)malloc(sizeof(float) * m_loopcount);
|
||||
double factor;
|
||||
for(int i = 0; i < m_loopcount; i++)
|
||||
{
|
||||
factor = scalev[i];
|
||||
int equRect_x = (int)(factor * gcascade->p0 + 0.5);
|
||||
int equRect_y = (int)(factor * gcascade->p1 + 0.5);
|
||||
int equRect_w = (int)(factor * gcascade->p3 + 0.5);
|
||||
int equRect_h = (int)(factor * gcascade->p2 + 0.5);
|
||||
p[i].s[0] = equRect_x;
|
||||
p[i].s[1] = equRect_y;
|
||||
p[i].s[2] = equRect_x + equRect_w;
|
||||
p[i].s[3] = equRect_y + equRect_h;
|
||||
correction[i] = 1. / (equRect_w * equRect_h);
|
||||
int startnodenum = m_nodenum * i;
|
||||
float factor2 = (float)factor;
|
||||
|
||||
vector<pair<size_t, const void *> > args1;
|
||||
args1.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->nodebuffer ));
|
||||
args1.push_back ( make_pair(sizeof(cl_mem) , (void *)&((OclBuffers *)buffers)->newnodebuffer ));
|
||||
args1.push_back ( make_pair(sizeof(cl_float) , (void *)&factor2 ));
|
||||
args1.push_back ( make_pair(sizeof(cl_float) , (void *)&correction[i] ));
|
||||
args1.push_back ( make_pair(sizeof(cl_int) , (void *)&startnodenum ));
|
||||
|
||||
size_t globalThreads2[3] = {m_nodenum, 1, 1};
|
||||
|
||||
openCLExecuteKernel(Context::getContext(), &haarobjectdetect_scaled2, "gpuscaleclassifier", globalThreads2, NULL/*localThreads2*/, args1, -1, -1);
|
||||
}
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->stagebuffer, 1, 0, sizeof(GpuHidHaarStageClassifier)*gcascade->count, stage, 0, NULL, NULL));
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->pbuffer, 1, 0, sizeof(cl_int4)*m_loopcount, p, 0, NULL, NULL));
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->correctionbuffer, 1, 0, sizeof(cl_float)*m_loopcount, correction, 0, NULL, NULL));
|
||||
|
||||
free(p);
|
||||
free(correction);
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::CreateBaseBufs(const int datasize, const int totalclassifier,
|
||||
const int flags, const int outputsz)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
buffers = malloc(sizeof(OclBuffers));
|
||||
|
||||
size_t tempSize =
|
||||
sizeof(GpuHidHaarStageClassifier) * ((GpuHidHaarClassifierCascade *)oldCascade->hid_cascade)->count;
|
||||
m_nodenum = (datasize - sizeof(GpuHidHaarClassifierCascade) - tempSize - sizeof(GpuHidHaarClassifier) * totalclassifier)
|
||||
/ sizeof(GpuHidHaarTreeNode);
|
||||
|
||||
((OclBuffers *)buffers)->stagebuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY, tempSize);
|
||||
((OclBuffers *)buffers)->nodebuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY, m_nodenum * sizeof(GpuHidHaarTreeNode));
|
||||
}
|
||||
|
||||
if (initialized
|
||||
&& ((m_flags & CV_HAAR_SCALE_IMAGE) ^ (flags & CV_HAAR_SCALE_IMAGE)))
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->candidatebuffer));
|
||||
}
|
||||
|
||||
if (flags & CV_HAAR_SCALE_IMAGE)
|
||||
{
|
||||
((OclBuffers *)buffers)->candidatebuffer = openCLCreateBuffer(cv::ocl::Context::getContext(),
|
||||
CL_MEM_WRITE_ONLY,
|
||||
4 * sizeof(int) * outputsz);
|
||||
}
|
||||
else
|
||||
{
|
||||
((OclBuffers *)buffers)->candidatebuffer = openCLCreateBuffer(cv::ocl::Context::getContext(),
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
4 * sizeof(int) * outputsz);
|
||||
faces = rectList;
|
||||
}
|
||||
}
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::CreateFactorRelatedBufs(
|
||||
const int rows, const int cols, const int flags,
|
||||
const double scaleFactor, const size_t localThreads[],
|
||||
CvSize minSize, CvSize maxSize)
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
if ((m_flags & CV_HAAR_SCALE_IMAGE) && !(flags & CV_HAAR_SCALE_IMAGE))
|
||||
{
|
||||
gimg1.release();
|
||||
gsum.release();
|
||||
gsqsum.release();
|
||||
}
|
||||
else if (!(m_flags & CV_HAAR_SCALE_IMAGE) && (flags & CV_HAAR_SCALE_IMAGE))
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->newnodebuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->correctionbuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->pbuffer));
|
||||
}
|
||||
else if ((m_flags & CV_HAAR_SCALE_IMAGE) && (flags & CV_HAAR_SCALE_IMAGE))
|
||||
{
|
||||
if (fabs(m_scaleFactor - scaleFactor) < 1e-6
|
||||
&& (rows == m_rows && cols == m_cols)
|
||||
&& (minSize.width == m_minSize.width)
|
||||
&& (minSize.height == m_minSize.height)
|
||||
&& (maxSize.width == m_maxSize.width)
|
||||
&& (maxSize.height == m_maxSize.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fabs(m_scaleFactor - scaleFactor) < 1e-6
|
||||
&& (rows == m_rows && cols == m_cols)
|
||||
&& (minSize.width == m_minSize.width)
|
||||
&& (minSize.height == m_minSize.height)
|
||||
&& (maxSize.width == m_maxSize.width)
|
||||
&& (maxSize.height == m_maxSize.height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->newnodebuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->correctionbuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->pbuffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int loopcount;
|
||||
int indexy = 0;
|
||||
int totalheight = 0;
|
||||
double factor;
|
||||
Rect roi;
|
||||
CvSize sz;
|
||||
CvSize winSize0 = oldCascade->orig_window_size;
|
||||
detect_piramid_info *scaleinfo;
|
||||
cl_command_queue qu = reinterpret_cast<cl_command_queue>(Context::getContext()->oclCommandQueue());
|
||||
if (flags & CV_HAAR_SCALE_IMAGE)
|
||||
{
|
||||
for(factor = 1.f;; factor *= scaleFactor)
|
||||
{
|
||||
CvSize winSize = { cvRound(winSize0.width * factor), cvRound(winSize0.height * factor) };
|
||||
sz.width = cvRound( cols / factor ) + 1;
|
||||
sz.height = cvRound( rows / factor ) + 1;
|
||||
CvSize sz1 = { sz.width - winSize0.width - 1, sz.height - winSize0.height - 1 };
|
||||
|
||||
if( sz1.width <= 0 || sz1.height <= 0 )
|
||||
break;
|
||||
if( winSize.width > maxSize.width || winSize.height > maxSize.height )
|
||||
break;
|
||||
if( winSize.width < minSize.width || winSize.height < minSize.height )
|
||||
continue;
|
||||
|
||||
totalheight += sz.height;
|
||||
sizev.push_back(sz);
|
||||
scalev.push_back(static_cast<float>(factor));
|
||||
}
|
||||
|
||||
loopcount = sizev.size();
|
||||
gimg1.create(rows, cols, CV_8UC1);
|
||||
gsum.create(totalheight + 4, cols + 1, CV_32SC1);
|
||||
gsqsum.create(totalheight + 4, cols + 1, CV_32FC1);
|
||||
|
||||
scaleinfo = (detect_piramid_info *)malloc(sizeof(detect_piramid_info) * loopcount);
|
||||
for( int i = 0; i < loopcount; i++ )
|
||||
{
|
||||
sz = sizev[i];
|
||||
roi = Rect(0, indexy, sz.width, sz.height);
|
||||
int width = sz.width - 1 - oldCascade->orig_window_size.width;
|
||||
int height = sz.height - 1 - oldCascade->orig_window_size.height;
|
||||
int grpnumperline = (width + localThreads[0] - 1) / localThreads[0];
|
||||
int totalgrp = ((height + localThreads[1] - 1) / localThreads[1]) * grpnumperline;
|
||||
|
||||
((detect_piramid_info *)scaleinfo)[i].width_height = (width << 16) | height;
|
||||
((detect_piramid_info *)scaleinfo)[i].grpnumperline_totalgrp = (grpnumperline << 16) | totalgrp;
|
||||
((detect_piramid_info *)scaleinfo)[i].imgoff = gsum(roi).offset >> 2;
|
||||
((detect_piramid_info *)scaleinfo)[i].factor = scalev[i];
|
||||
|
||||
indexy += sz.height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(factor = 1;
|
||||
cvRound(factor * winSize0.width) < cols - 10 && cvRound(factor * winSize0.height) < rows - 10;
|
||||
factor *= scaleFactor)
|
||||
{
|
||||
CvSize winSize = { cvRound( winSize0.width * factor ), cvRound( winSize0.height * factor ) };
|
||||
if( winSize.width < minSize.width || winSize.height < minSize.height )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sizev.push_back(winSize);
|
||||
scalev.push_back(factor);
|
||||
}
|
||||
|
||||
loopcount = scalev.size();
|
||||
if(loopcount == 0)
|
||||
{
|
||||
loopcount = 1;
|
||||
sizev.push_back(minSize);
|
||||
scalev.push_back( min(cvRound(minSize.width / winSize0.width), cvRound(minSize.height / winSize0.height)) );
|
||||
}
|
||||
|
||||
((OclBuffers *)buffers)->pbuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY,
|
||||
sizeof(cl_int4) * loopcount);
|
||||
((OclBuffers *)buffers)->correctionbuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY,
|
||||
sizeof(cl_float) * loopcount);
|
||||
((OclBuffers *)buffers)->newnodebuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_WRITE,
|
||||
loopcount * m_nodenum * sizeof(GpuHidHaarTreeNode));
|
||||
|
||||
scaleinfo = (detect_piramid_info *)malloc(sizeof(detect_piramid_info) * loopcount);
|
||||
for( int i = 0; i < loopcount; i++ )
|
||||
{
|
||||
sz = sizev[i];
|
||||
factor = scalev[i];
|
||||
int ystep = cvRound(std::max(2., factor));
|
||||
int width = (cols - 1 - sz.width + ystep - 1) / ystep;
|
||||
int height = (rows - 1 - sz.height + ystep - 1) / ystep;
|
||||
int grpnumperline = (width + localThreads[0] - 1) / localThreads[0];
|
||||
int totalgrp = ((height + localThreads[1] - 1) / localThreads[1]) * grpnumperline;
|
||||
|
||||
((detect_piramid_info *)scaleinfo)[i].width_height = (width << 16) | height;
|
||||
((detect_piramid_info *)scaleinfo)[i].grpnumperline_totalgrp = (grpnumperline << 16) | totalgrp;
|
||||
((detect_piramid_info *)scaleinfo)[i].imgoff = 0;
|
||||
((detect_piramid_info *)scaleinfo)[i].factor = factor;
|
||||
}
|
||||
}
|
||||
|
||||
if (loopcount != m_loopcount)
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->scaleinfobuffer));
|
||||
}
|
||||
((OclBuffers *)buffers)->scaleinfobuffer = openCLCreateBuffer(cv::ocl::Context::getContext(), CL_MEM_READ_ONLY, sizeof(detect_piramid_info) * loopcount);
|
||||
}
|
||||
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, ((OclBuffers *)buffers)->scaleinfobuffer, 1, 0,
|
||||
sizeof(detect_piramid_info)*loopcount,
|
||||
scaleinfo, 0, NULL, NULL));
|
||||
free(scaleinfo);
|
||||
|
||||
m_loopcount = loopcount;
|
||||
}
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::GenResult(CV_OUT std::vector<cv::Rect>& faces,
|
||||
const std::vector<cv::Rect> &rectList,
|
||||
const std::vector<int> &rweights)
|
||||
{
|
||||
MemStorage tempStorage(cvCreateMemStorage(0));
|
||||
CvSeq *result_seq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvAvgComp), tempStorage );
|
||||
|
||||
if( findBiggestObject && rectList.size() )
|
||||
{
|
||||
CvAvgComp result_comp = {CvRect(), 0};
|
||||
|
||||
for( size_t i = 0; i < rectList.size(); i++ )
|
||||
{
|
||||
cv::Rect r = rectList[i];
|
||||
if( r.area() > cv::Rect(result_comp.rect).area() )
|
||||
{
|
||||
result_comp.rect = r;
|
||||
result_comp.neighbors = rweights[i];
|
||||
}
|
||||
}
|
||||
cvSeqPush( result_seq, &result_comp );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( size_t i = 0; i < rectList.size(); i++ )
|
||||
{
|
||||
CvAvgComp c;
|
||||
c.rect = rectList[i];
|
||||
c.neighbors = rweights[i];
|
||||
cvSeqPush( result_seq, &c );
|
||||
}
|
||||
}
|
||||
|
||||
vector<CvAvgComp> vecAvgComp;
|
||||
Seq<CvAvgComp>(result_seq).copyTo(vecAvgComp);
|
||||
faces.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), faces.begin(), getRect());
|
||||
}
|
||||
|
||||
void cv::ocl::OclCascadeClassifierBuf::release()
|
||||
{
|
||||
if(initialized)
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->stagebuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->scaleinfobuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->nodebuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->candidatebuffer));
|
||||
|
||||
if( (m_flags & CV_HAAR_SCALE_IMAGE) )
|
||||
{
|
||||
cvFree(&oldCascade->hid_cascade);
|
||||
}
|
||||
else
|
||||
{
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->newnodebuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->correctionbuffer));
|
||||
openCLSafeCall(clReleaseMemObject(((OclBuffers *)buffers)->pbuffer));
|
||||
}
|
||||
|
||||
free(buffers);
|
||||
buffers = NULL;
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH 1024
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -64,7 +64,7 @@
|
||||
#undef OPENCV_NOSTL
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/objdetect.hpp"
|
||||
#include "opencv2/objdetect/objdetect_c.h"
|
||||
#include "opencv2/ocl.hpp"
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
|
@ -44,9 +44,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include "opencv2/objdetect.hpp"
|
||||
#include "opencv2/objdetect/objdetect_c.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
@ -185,18 +183,11 @@ INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, HOG, testing::Combine(
|
||||
testing::Values(Size(64, 128), Size(48, 96)),
|
||||
testing::Values(MatType(CV_8UC1), MatType(CV_8UC4))));
|
||||
|
||||
#if 0
|
||||
|
||||
///////////////////////////// Haar //////////////////////////////
|
||||
IMPLEMENT_PARAM_CLASS(CascadeName, std::string);
|
||||
CascadeName cascade_frontalface_alt(std::string("haarcascade_frontalface_alt.xml"));
|
||||
CascadeName cascade_frontalface_alt2(std::string("haarcascade_frontalface_alt2.xml"));
|
||||
struct getRect
|
||||
{
|
||||
Rect operator ()(const CvAvgComp &e) const
|
||||
{
|
||||
return e.rect;
|
||||
}
|
||||
};
|
||||
|
||||
PARAM_TEST_CASE(Haar, int, CascadeName)
|
||||
{
|
||||
@ -224,49 +215,18 @@ PARAM_TEST_CASE(Haar, int, CascadeName)
|
||||
|
||||
TEST_P(Haar, FaceDetect)
|
||||
{
|
||||
MemStorage storage(cvCreateMemStorage(0));
|
||||
CvSeq *_objects;
|
||||
_objects = cascade.oclHaarDetectObjects(d_img, storage, 1.1, 3,
|
||||
flags, Size(30, 30), Size(0, 0));
|
||||
vector<CvAvgComp> vecAvgComp;
|
||||
Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);
|
||||
oclfaces.resize(vecAvgComp.size());
|
||||
std::transform(vecAvgComp.begin(), vecAvgComp.end(), oclfaces.begin(), getRect());
|
||||
cascade.detectMultiScale(d_img, oclfaces, 1.1, 3,
|
||||
flags, Size(30, 30));
|
||||
|
||||
cpucascade.detectMultiScale(img, faces, 1.1, 3,
|
||||
flags,
|
||||
Size(30, 30), Size(0, 0));
|
||||
|
||||
EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0);
|
||||
}
|
||||
|
||||
TEST_P(Haar, FaceDetectUseBuf)
|
||||
{
|
||||
ocl::OclCascadeClassifierBuf cascadebuf;
|
||||
if(!cascadebuf.load(cascadeName))
|
||||
{
|
||||
std::cout << "ERROR: Could not load classifier cascade for FaceDetectUseBuf!" << std::endl;
|
||||
return;
|
||||
}
|
||||
cascadebuf.detectMultiScale(d_img, oclfaces, 1.1, 3,
|
||||
flags,
|
||||
Size(30, 30), Size(0, 0));
|
||||
cpucascade.detectMultiScale(img, faces, 1.1, 3,
|
||||
flags,
|
||||
Size(30, 30), Size(0, 0));
|
||||
|
||||
// intentionally run ocl facedetect again and check if it still works after the first run
|
||||
cascadebuf.detectMultiScale(d_img, oclfaces, 1.1, 3,
|
||||
flags,
|
||||
Size(30, 30));
|
||||
cascadebuf.release();
|
||||
cpucascade.detectMultiScale(img, faces, 1.1, 3,
|
||||
flags, Size(30, 30));
|
||||
|
||||
EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, Haar,
|
||||
Combine(Values(CV_HAAR_SCALE_IMAGE, 0),
|
||||
Values(cascade_frontalface_alt/*, cascade_frontalface_alt2*/)));
|
||||
#endif
|
||||
Combine(Values((int)CASCADE_SCALE_IMAGE, 0),
|
||||
Values(cascade_frontalface_alt, cascade_frontalface_alt2)));
|
||||
|
||||
|
||||
#endif //HAVE_OPENCL
|
||||
|
2
modules/optim/CMakeLists.txt
Normal file
2
modules/optim/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
set(the_description "Generic optimization")
|
||||
ocv_define_module(optim opencv_core)
|
48
modules/optim/doc/linear_programming.rst
Normal file
48
modules/optim/doc/linear_programming.rst
Normal file
@ -0,0 +1,48 @@
|
||||
Linear Programming
|
||||
==================
|
||||
|
||||
.. highlight:: cpp
|
||||
|
||||
optim::solveLP
|
||||
--------------------
|
||||
Solve given (non-integer) linear programming problem using the Simplex Algorithm (Simplex Method).
|
||||
What we mean here by "linear programming problem" (or LP problem, for short) can be
|
||||
formulated as:
|
||||
|
||||
.. math::
|
||||
\mbox{Maximize } c\cdot x\\
|
||||
\mbox{Subject to:}\\
|
||||
Ax\leq b\\
|
||||
x\geq 0
|
||||
|
||||
Where :math:`c` is fixed *1*-by-*n* row-vector, :math:`A` is fixed *m*-by-*n* matrix, :math:`b` is fixed *m*-by-*1* column vector and
|
||||
:math:`x` is an arbitrary *n*-by-*1* column vector, which satisfies the constraints.
|
||||
|
||||
Simplex algorithm is one of many algorithms that are designed to handle this sort of problems efficiently. Although it is not optimal in theoretical
|
||||
sense (there exist algorithms that can solve any problem written as above in polynomial type, while simplex method degenerates to exponential time
|
||||
for some special cases), it is well-studied, easy to implement and is shown to work well for real-life purposes.
|
||||
|
||||
The particular implementation is taken almost verbatim from **Introduction to Algorithms, third edition**
|
||||
by T. H. Cormen, C. E. Leiserson, R. L. Rivest and Clifford Stein. In particular, the Bland's rule
|
||||
(`http://en.wikipedia.org/wiki/Bland%27s\_rule <http://en.wikipedia.org/wiki/Bland%27s_rule>`_) is used to prevent cycling.
|
||||
|
||||
.. ocv:function:: int optim::solveLP(const Mat& Func, const Mat& Constr, Mat& z)
|
||||
|
||||
:param Func: This row-vector corresponds to :math:`c` in the LP problem formulation (see above). It should contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted, in the latter case it is understood to correspond to :math:`c^T`.
|
||||
|
||||
:param Constr: *m*-by-*n\+1* matrix, whose rightmost column corresponds to :math:`b` in formulation above and the remaining to :math:`A`. It should containt 32- or 64-bit floating point numbers.
|
||||
|
||||
:param z: The solution will be returned here as a column-vector - it corresponds to :math:`c` in the formulation above. It will contain 64-bit floating point numbers.
|
||||
|
||||
:return: One of the return codes:
|
||||
|
||||
::
|
||||
|
||||
//!the return codes for solveLP() function
|
||||
enum
|
||||
{
|
||||
SOLVELP_UNBOUNDED = -2, //problem is unbounded (target function can achieve arbitrary high values)
|
||||
SOLVELP_UNFEASIBLE = -1, //problem is unfeasible (there are no points that satisfy all the constraints imposed)
|
||||
SOLVELP_SINGLE = 0, //there is only one maximum for target function
|
||||
SOLVELP_MULTI = 1 //there are multiple maxima for target function - the arbitrary one is returned
|
||||
};
|
10
modules/optim/doc/optim.rst
Normal file
10
modules/optim/doc/optim.rst
Normal file
@ -0,0 +1,10 @@
|
||||
**************************************
|
||||
optim. Generic numerical optimization
|
||||
**************************************
|
||||
|
||||
.. highlight:: cpp
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
linear_programming
|
62
modules/optim/include/opencv2/optim.hpp
Normal file
62
modules/optim/include/opencv2/optim.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*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) 2008-2012, 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*/
|
||||
|
||||
#ifndef __OPENCV_OPTIM_HPP__
|
||||
#define __OPENCV_OPTIM_HPP__
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
namespace cv{namespace optim
|
||||
{
|
||||
//!the return codes for solveLP() function
|
||||
enum
|
||||
{
|
||||
SOLVELP_UNBOUNDED = -2, //problem is unbounded (target function can achieve arbitrary high values)
|
||||
SOLVELP_UNFEASIBLE = -1, //problem is unfeasible (there are no points that satisfy all the constraints imposed)
|
||||
SOLVELP_SINGLE = 0, //there is only one maximum for target function
|
||||
SOLVELP_MULTI = 1 //there are multiple maxima for target function - the arbitrary one is returned
|
||||
};
|
||||
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
|
||||
}}// cv
|
||||
|
||||
#endif
|
48
modules/optim/include/opencv2/optim/optim.hpp
Normal file
48
modules/optim/include/opencv2/optim/optim.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*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.
|
||||
// Copyright (C) 2013, OpenCV Foundation, 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*/
|
||||
|
||||
#ifdef __OPENCV_BUILD
|
||||
#error this is a compatibility header which should not be used inside the OpenCV library
|
||||
#endif
|
||||
|
||||
#include "opencv2/optim.hpp"
|
322
modules/optim/src/lpsolver.cpp
Normal file
322
modules/optim/src/lpsolver.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
#include "precomp.hpp"
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace cv{namespace optim{
|
||||
using std::vector;
|
||||
|
||||
#ifdef ALEX_DEBUG
|
||||
#define dprintf(x) printf x
|
||||
static void print_matrix(const Mat& x){
|
||||
print(x);
|
||||
printf("\n");
|
||||
}
|
||||
static void print_simplex_state(const Mat& c,const Mat& b,double v,const std::vector<int> N,const std::vector<int> B){
|
||||
printf("\tprint simplex state\n");
|
||||
|
||||
printf("v=%g\n",v);
|
||||
|
||||
printf("here c goes\n");
|
||||
print_matrix(c);
|
||||
|
||||
printf("non-basic: ");
|
||||
print(Mat(N));
|
||||
printf("\n");
|
||||
|
||||
printf("here b goes\n");
|
||||
print_matrix(b);
|
||||
printf("basic: ");
|
||||
|
||||
print(Mat(B));
|
||||
printf("\n");
|
||||
}
|
||||
#else
|
||||
#define dprintf(x)
|
||||
#define print_matrix(x)
|
||||
#define print_simplex_state(c,b,v,N,B)
|
||||
#endif
|
||||
|
||||
/**Due to technical considerations, the format of input b and c is somewhat special:
|
||||
*both b and c should be one column bigger than corresponding b and c of linear problem and the leftmost column will be used internally
|
||||
by this procedure - it should not be cleaned before the call to procedure and may contain mess after
|
||||
it also initializes N and B and does not make any assumptions about their init values
|
||||
* @return SOLVELP_UNFEASIBLE if problem is unfeasible, 0 if feasible.
|
||||
*/
|
||||
static int initialize_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,vector<unsigned int>& indexToRow);
|
||||
static inline void pivot(Mat_<double>& c,Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,int leaving_index,
|
||||
int entering_index,vector<unsigned int>& indexToRow);
|
||||
/**@return SOLVELP_UNBOUNDED means the problem is unbdd, SOLVELP_MULTI means multiple solutions, SOLVELP_SINGLE means one solution.
|
||||
*/
|
||||
static int inner_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,vector<unsigned int>& indexToRow);
|
||||
static void swap_columns(Mat_<double>& A,int col1,int col2);
|
||||
#define SWAP(type,a,b) {type tmp=(a);(a)=(b);(b)=tmp;}
|
||||
|
||||
//return codes:-2 (no_sol - unbdd),-1(no_sol - unfsbl), 0(single_sol), 1(multiple_sol=>least_l2_norm)
|
||||
int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
dprintf(("call to solveLP\n"));
|
||||
|
||||
//sanity check (size, type, no. of channels)
|
||||
CV_Assert(Func.type()==CV_64FC1 || Func.type()==CV_32FC1);
|
||||
CV_Assert(Constr.type()==CV_64FC1 || Constr.type()==CV_32FC1);
|
||||
CV_Assert((Func.rows==1 && (Constr.cols-Func.cols==1))||
|
||||
(Func.cols==1 && (Constr.cols-Func.rows==1)));
|
||||
|
||||
//copy arguments for we will shall modify them
|
||||
Mat_<double> bigC=Mat_<double>(1,(Func.rows==1?Func.cols:Func.rows)+1),
|
||||
bigB=Mat_<double>(Constr.rows,Constr.cols+1);
|
||||
if(Func.rows==1){
|
||||
Func.convertTo(bigC.colRange(1,bigC.cols),CV_64FC1);
|
||||
}else{
|
||||
Mat FuncT=Func.t();
|
||||
FuncT.convertTo(bigC.colRange(1,bigC.cols),CV_64FC1);
|
||||
}
|
||||
Constr.convertTo(bigB.colRange(1,bigB.cols),CV_64FC1);
|
||||
double v=0;
|
||||
vector<int> N,B;
|
||||
vector<unsigned int> indexToRow;
|
||||
|
||||
if(initialize_simplex(bigC,bigB,v,N,B,indexToRow)==SOLVELP_UNFEASIBLE){
|
||||
return SOLVELP_UNFEASIBLE;
|
||||
}
|
||||
Mat_<double> c=bigC.colRange(1,bigC.cols),
|
||||
b=bigB.colRange(1,bigB.cols);
|
||||
|
||||
int res=0;
|
||||
if((res=inner_simplex(c,b,v,N,B,indexToRow))==SOLVELP_UNBOUNDED){
|
||||
return SOLVELP_UNBOUNDED;
|
||||
}
|
||||
|
||||
//return the optimal solution
|
||||
z.create(c.cols,1,CV_64FC1);
|
||||
MatIterator_<double> it=z.begin<double>();
|
||||
for(int i=1;i<=c.cols;i++,it++){
|
||||
if(indexToRow[i]<N.size()){
|
||||
*it=0;
|
||||
}else{
|
||||
*it=b.at<double>(indexToRow[i]-N.size(),b.cols-1);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int initialize_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,vector<unsigned int>& indexToRow){
|
||||
N.resize(c.cols);
|
||||
N[0]=0;
|
||||
for (std::vector<int>::iterator it = N.begin()+1 ; it != N.end(); ++it){
|
||||
*it=it[-1]+1;
|
||||
}
|
||||
B.resize(b.rows);
|
||||
B[0]=N.size();
|
||||
for (std::vector<int>::iterator it = B.begin()+1 ; it != B.end(); ++it){
|
||||
*it=it[-1]+1;
|
||||
}
|
||||
indexToRow.resize(c.cols+b.rows);
|
||||
indexToRow[0]=0;
|
||||
for (std::vector<unsigned int>::iterator it = indexToRow.begin()+1 ; it != indexToRow.end(); ++it){
|
||||
*it=it[-1]+1;
|
||||
}
|
||||
v=0;
|
||||
|
||||
int k=0;
|
||||
{
|
||||
double min=DBL_MAX;
|
||||
for(int i=0;i<b.rows;i++){
|
||||
if(b(i,b.cols-1)<min){
|
||||
min=b(i,b.cols-1);
|
||||
k=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(b(k,b.cols-1)>=0){
|
||||
N.erase(N.begin());
|
||||
for (std::vector<unsigned int>::iterator it = indexToRow.begin()+1 ; it != indexToRow.end(); ++it){
|
||||
--(*it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Mat_<double> old_c=c.clone();
|
||||
c=0;
|
||||
c(0,0)=-1;
|
||||
for(int i=0;i<b.rows;i++){
|
||||
b(i,0)=-1;
|
||||
}
|
||||
|
||||
print_simplex_state(c,b,v,N,B);
|
||||
|
||||
dprintf(("\tWE MAKE PIVOT\n"));
|
||||
pivot(c,b,v,N,B,k,0,indexToRow);
|
||||
|
||||
print_simplex_state(c,b,v,N,B);
|
||||
|
||||
inner_simplex(c,b,v,N,B,indexToRow);
|
||||
|
||||
dprintf(("\tAFTER INNER_SIMPLEX\n"));
|
||||
print_simplex_state(c,b,v,N,B);
|
||||
|
||||
if(indexToRow[0]>=N.size()){
|
||||
int iterator_offset=indexToRow[0]-N.size();
|
||||
if(b(iterator_offset,b.cols-1)>0){
|
||||
return SOLVELP_UNFEASIBLE;
|
||||
}
|
||||
pivot(c,b,v,N,B,iterator_offset,0,indexToRow);
|
||||
}
|
||||
|
||||
vector<int>::iterator iterator;
|
||||
{
|
||||
int iterator_offset=indexToRow[0];
|
||||
iterator=N.begin()+iterator_offset;
|
||||
std::iter_swap(iterator,N.begin());
|
||||
SWAP(int,indexToRow[*iterator],indexToRow[0]);
|
||||
swap_columns(c,iterator_offset,0);
|
||||
swap_columns(b,iterator_offset,0);
|
||||
}
|
||||
|
||||
dprintf(("after swaps\n"));
|
||||
print_simplex_state(c,b,v,N,B);
|
||||
|
||||
//start from 1, because we ignore x_0
|
||||
c=0;
|
||||
v=0;
|
||||
for(int I=1;I<old_c.cols;I++){
|
||||
if(indexToRow[I]<N.size()){
|
||||
dprintf(("I=%d from nonbasic\n",I));
|
||||
int iterator_offset=indexToRow[I];
|
||||
c(0,iterator_offset)+=old_c(0,I);
|
||||
print_matrix(c);
|
||||
}else{
|
||||
dprintf(("I=%d from basic\n",I));
|
||||
int iterator_offset=indexToRow[I]-N.size();
|
||||
c-=old_c(0,I)*b.row(iterator_offset).colRange(0,b.cols-1);
|
||||
v+=old_c(0,I)*b(iterator_offset,b.cols-1);
|
||||
print_matrix(c);
|
||||
}
|
||||
}
|
||||
|
||||
dprintf(("after restore\n"));
|
||||
print_simplex_state(c,b,v,N,B);
|
||||
|
||||
N.erase(N.begin());
|
||||
for (std::vector<unsigned int>::iterator it = indexToRow.begin()+1 ; it != indexToRow.end(); ++it){
|
||||
--(*it);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inner_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,vector<unsigned int>& indexToRow){
|
||||
int count=0;
|
||||
for(;;){
|
||||
dprintf(("iteration #%d\n",count));
|
||||
count++;
|
||||
|
||||
static MatIterator_<double> pos_ptr;
|
||||
int e=-1,pos_ctr=0,min_var=INT_MAX;
|
||||
bool all_nonzero=true;
|
||||
for(pos_ptr=c.begin();pos_ptr!=c.end();pos_ptr++,pos_ctr++){
|
||||
if(*pos_ptr==0){
|
||||
all_nonzero=false;
|
||||
}
|
||||
if(*pos_ptr>0){
|
||||
if(N[pos_ctr]<min_var){
|
||||
e=pos_ctr;
|
||||
min_var=N[pos_ctr];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(e==-1){
|
||||
dprintf(("hello from e==-1\n"));
|
||||
print_matrix(c);
|
||||
if(all_nonzero==true){
|
||||
return SOLVELP_SINGLE;
|
||||
}else{
|
||||
return SOLVELP_MULTI;
|
||||
}
|
||||
}
|
||||
|
||||
int l=-1;
|
||||
min_var=INT_MAX;
|
||||
double min=DBL_MAX;
|
||||
int row_it=0;
|
||||
MatIterator_<double> min_row_ptr=b.begin();
|
||||
for(MatIterator_<double> it=b.begin();it!=b.end();it+=b.cols,row_it++){
|
||||
double myite=0;
|
||||
//check constraints, select the tightest one, reinforcing Bland's rule
|
||||
if((myite=it[e])>0){
|
||||
double val=it[b.cols-1]/myite;
|
||||
if(val<min || (val==min && B[row_it]<min_var)){
|
||||
min_var=B[row_it];
|
||||
min_row_ptr=it;
|
||||
min=val;
|
||||
l=row_it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(l==-1){
|
||||
return SOLVELP_UNBOUNDED;
|
||||
}
|
||||
dprintf(("the tightest constraint is in row %d with %g\n",l,min));
|
||||
|
||||
pivot(c,b,v,N,B,l,e,indexToRow);
|
||||
|
||||
dprintf(("objective, v=%g\n",v));
|
||||
print_matrix(c);
|
||||
dprintf(("constraints\n"));
|
||||
print_matrix(b);
|
||||
dprintf(("non-basic: "));
|
||||
print_matrix(Mat(N));
|
||||
dprintf(("basic: "));
|
||||
print_matrix(Mat(B));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void pivot(Mat_<double>& c,Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,
|
||||
int leaving_index,int entering_index,vector<unsigned int>& indexToRow){
|
||||
double Coef=b(leaving_index,entering_index);
|
||||
for(int i=0;i<b.cols;i++){
|
||||
if(i==entering_index){
|
||||
b(leaving_index,i)=1/Coef;
|
||||
}else{
|
||||
b(leaving_index,i)/=Coef;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<b.rows;i++){
|
||||
if(i!=leaving_index){
|
||||
double coef=b(i,entering_index);
|
||||
for(int j=0;j<b.cols;j++){
|
||||
if(j==entering_index){
|
||||
b(i,j)=-coef*b(leaving_index,j);
|
||||
}else{
|
||||
b(i,j)-=(coef*b(leaving_index,j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//objective function
|
||||
Coef=c(0,entering_index);
|
||||
for(int i=0;i<(b.cols-1);i++){
|
||||
if(i==entering_index){
|
||||
c(0,i)=-Coef*b(leaving_index,i);
|
||||
}else{
|
||||
c(0,i)-=Coef*b(leaving_index,i);
|
||||
}
|
||||
}
|
||||
dprintf(("v was %g\n",v));
|
||||
v+=Coef*b(leaving_index,b.cols-1);
|
||||
|
||||
SWAP(int,N[entering_index],B[leaving_index]);
|
||||
SWAP(int,indexToRow[N[entering_index]],indexToRow[B[leaving_index]]);
|
||||
}
|
||||
|
||||
static inline void swap_columns(Mat_<double>& A,int col1,int col2){
|
||||
for(int i=0;i<A.rows;i++){
|
||||
double tmp=A(i,col1);
|
||||
A(i,col1)=A(i,col2);
|
||||
A(i,col2)=tmp;
|
||||
}
|
||||
}
|
||||
}}
|
44
modules/optim/src/precomp.cpp
Normal file
44
modules/optim/src/precomp.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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"
|
||||
|
||||
/* End of file. */
|
48
modules/optim/src/precomp.hpp
Normal file
48
modules/optim/src/precomp.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*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*/
|
||||
|
||||
#ifndef __OPENCV_PRECOMP_H__
|
||||
#define __OPENCV_PRECOMP_H__
|
||||
|
||||
#include "opencv2/optim.hpp"
|
||||
|
||||
#endif
|
101
modules/optim/test/test_lpsolver.cpp
Normal file
101
modules/optim/test/test_lpsolver.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "test_precomp.hpp"
|
||||
#include <iostream>
|
||||
|
||||
TEST(Optim_LpSolver, regression_basic){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//cormen's example #1
|
||||
A=(cv::Mat_<double>(3,1)<<3,1,2);
|
||||
B=(cv::Mat_<double>(3,4)<<1,1,3,30,2,2,5,24,4,1,2,36);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::optim::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(3,1)<<8,4,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
//cormen's example #2
|
||||
A=(cv::Mat_<double>(1,2)<<18,12.5);
|
||||
B=(cv::Mat_<double>(3,3)<<1,1,20,1,0,20,0,1,16);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::optim::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(2,1)<<20,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
//cormen's example #3
|
||||
A=(cv::Mat_<double>(1,2)<<5,-3);
|
||||
B=(cv::Mat_<double>(2,3)<<1,-1,1,2,1,2);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::optim::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(2,1)<<1,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_init_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//cormen's example #4 - unfeasible
|
||||
A=(cv::Mat_<double>(1,3)<<-1,-1,-1);
|
||||
B=(cv::Mat_<double>(2,4)<<-2,-7.5,-3,-10000,-20,-5,-10,-30000);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
cv::optim::solveLP(A,B,z);
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
etalon_z=(cv::Mat_<double>(3,1)<<1250,1000,0);
|
||||
ASSERT_EQ(cv::countNonZero(z!=etalon_z),0);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_absolutely_unfeasible){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//trivial absolutely unfeasible example
|
||||
A=(cv::Mat_<double>(1,1)<<1);
|
||||
B=(cv::Mat_<double>(2,2)<<1,-1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
ASSERT_EQ(res,-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_multiple_solutions){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//trivial example with multiple solutions
|
||||
A=(cv::Mat_<double>(2,1)<<1,1);
|
||||
B=(cv::Mat_<double>(1,3)<<1,1,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(res,1);
|
||||
ASSERT_EQ(z.dot(A),1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Optim_LpSolver, regression_cycling){
|
||||
cv::Mat A,B,z,etalon_z;
|
||||
|
||||
#if 1
|
||||
//example with cycling from http://people.orie.cornell.edu/miketodd/or630/SimplexCyclingExample.pdf
|
||||
A=(cv::Mat_<double>(4,1)<<10,-57,-9,-24);
|
||||
B=(cv::Mat_<double>(3,5)<<0.5,-5.5,-2.5,9,0,0.5,-1.5,-0.5,1,0,1,0,0,0,1);
|
||||
std::cout<<"here A goes\n"<<A<<"\n";
|
||||
int res=cv::optim::solveLP(A,B,z);
|
||||
printf("res=%d\n",res);
|
||||
printf("scalar %g\n",z.dot(A));
|
||||
std::cout<<"here z goes\n"<<z<<"\n";
|
||||
ASSERT_EQ(z.dot(A),1);
|
||||
//ASSERT_EQ(res,1);
|
||||
#endif
|
||||
}
|
3
modules/optim/test/test_main.cpp
Normal file
3
modules/optim/test/test_main.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
CV_TEST_MAIN("cv")
|
1
modules/optim/test/test_precomp.cpp
Normal file
1
modules/optim/test/test_precomp.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "test_precomp.hpp"
|
15
modules/optim/test/test_precomp.hpp
Normal file
15
modules/optim/test/test_precomp.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||
# if defined __clang__ || defined __APPLE__
|
||||
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
# pragma GCC diagnostic ignored "-Wextra"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef __OPENCV_TEST_PRECOMP_HPP__
|
||||
#define __OPENCV_TEST_PRECOMP_HPP__
|
||||
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/optim.hpp"
|
||||
|
||||
#endif
|
@ -81,6 +81,10 @@ if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_module} PROPERTIES FOLDER "bindings")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-DCVAPI_EXPORTS)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
|
||||
endif()
|
||||
|
@ -510,13 +510,6 @@ PyObject* pyopencv_from(const cvflann_flann_distance_t& value)
|
||||
return PyInt_FromLong(int(value));
|
||||
}
|
||||
|
||||
template<>
|
||||
bool pyopencv_to(PyObject*, cv::flann::SearchParams &, const char *)
|
||||
{
|
||||
CV_Assert(!"not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool pyopencv_to(PyObject* obj, int& value, const char* name)
|
||||
{
|
||||
@ -1055,6 +1048,12 @@ bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
|
||||
return ok;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool pyopencv_to(PyObject* obj, cv::flann::SearchParams & value, const char * name)
|
||||
{
|
||||
return pyopencv_to<cv::flann::IndexParams>(obj, value, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool pyopencv_to(PyObject *o, Ptr<T>& p, const char *name)
|
||||
{
|
||||
|
@ -8,9 +8,6 @@
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
int main( int, const char** ) { return 0; }
|
||||
|
||||
#if 0
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
@ -46,7 +43,7 @@ static double getTime()
|
||||
}
|
||||
|
||||
void detect( Mat& img, vector<Rect>& faces,
|
||||
ocl::OclCascadeClassifierBuf& cascade,
|
||||
ocl::OclCascadeClassifier& cascade,
|
||||
double scale, bool calTime);
|
||||
|
||||
|
||||
@ -66,20 +63,19 @@ double checkRectSimilarity(Size sz, vector<Rect>& cpu_rst, vector<Rect>& gpu_rst
|
||||
int main( int argc, const char** argv )
|
||||
{
|
||||
const char* keys =
|
||||
"{ h | help | false | print help message }"
|
||||
"{ i | input | | specify input image }"
|
||||
"{ t | template | haarcascade_frontalface_alt.xml |"
|
||||
"{ h help | false | print help message }"
|
||||
"{ i input | | specify input image }"
|
||||
"{ t template | haarcascade_frontalface_alt.xml |"
|
||||
" specify template file path }"
|
||||
"{ c | scale | 1.0 | scale image }"
|
||||
"{ s | use_cpu | false | use cpu or gpu to process the image }"
|
||||
"{ o | output | facedetect_output.jpg |"
|
||||
"{ c scale | 1.0 | scale image }"
|
||||
"{ s use_cpu | false | use cpu or gpu to process the image }"
|
||||
"{ o output | facedetect_output.jpg |"
|
||||
" specify output image save path(only works when input is images) }";
|
||||
|
||||
CommandLineParser cmd(argc, argv, keys);
|
||||
if (cmd.get<bool>("help"))
|
||||
{
|
||||
cout << "Avaible options:" << endl;
|
||||
cmd.printParams();
|
||||
return 0;
|
||||
}
|
||||
CvCapture* capture = 0;
|
||||
@ -90,7 +86,7 @@ int main( int argc, const char** argv )
|
||||
outputName = cmd.get<string>("o");
|
||||
string cascadeName = cmd.get<string>("t");
|
||||
double scale = cmd.get<double>("c");
|
||||
ocl::OclCascadeClassifierBuf cascade;
|
||||
ocl::OclCascadeClassifier cascade;
|
||||
CascadeClassifier cpu_cascade;
|
||||
|
||||
if( !cascade.load( cascadeName ) || !cpu_cascade.load(cascadeName) )
|
||||
@ -211,7 +207,7 @@ _cleanup_:
|
||||
}
|
||||
|
||||
void detect( Mat& img, vector<Rect>& faces,
|
||||
ocl::OclCascadeClassifierBuf& cascade,
|
||||
ocl::OclCascadeClassifier& cascade,
|
||||
double scale, bool calTime)
|
||||
{
|
||||
ocl::oclMat image(img);
|
||||
@ -223,7 +219,7 @@ void detect( Mat& img, vector<Rect>& faces,
|
||||
|
||||
cascade.detectMultiScale( smallImg, faces, 1.1,
|
||||
3, 0
|
||||
|CV_HAAR_SCALE_IMAGE
|
||||
|CASCADE_SCALE_IMAGE
|
||||
, Size(30,30), Size(0, 0) );
|
||||
if(calTime) workEnd();
|
||||
}
|
||||
@ -234,11 +230,11 @@ void detectCPU( Mat& img, vector<Rect>& faces,
|
||||
{
|
||||
if(calTime) workBegin();
|
||||
Mat cpu_gray, cpu_smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
|
||||
cvtColor(img, cpu_gray, CV_BGR2GRAY);
|
||||
cvtColor(img, cpu_gray, COLOR_BGR2GRAY);
|
||||
resize(cpu_gray, cpu_smallImg, cpu_smallImg.size(), 0, 0, INTER_LINEAR);
|
||||
equalizeHist(cpu_smallImg, cpu_smallImg);
|
||||
cascade.detectMultiScale(cpu_smallImg, faces, 1.1,
|
||||
3, 0 | CV_HAAR_SCALE_IMAGE,
|
||||
3, 0 | CASCADE_SCALE_IMAGE,
|
||||
Size(30, 30), Size(0, 0));
|
||||
if(calTime) workEnd();
|
||||
}
|
||||
@ -311,5 +307,4 @@ double checkRectSimilarity(Size sz, vector<Rect>& ob1, vector<Rect>& ob2)
|
||||
final_test_result = -1;
|
||||
}
|
||||
return final_test_result;
|
||||
}
|
||||
#endif
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user