Commit 02fb3f0a authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

it finally works!!!

parent ef509ace
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "cascadedetect.hpp" #include "cascadedetect.hpp"
#include "opencv2/objdetect/objdetect_c.h" #include "opencv2/objdetect/objdetect_c.h"
#include "opencl_kernels.hpp"
#if defined (LOG_CASCADE_STATISTIC) #if defined (LOG_CASCADE_STATISTIC)
struct Logger struct Logger
...@@ -491,7 +492,7 @@ bool HaarEvaluator::read(const FileNode& node) ...@@ -491,7 +492,7 @@ bool HaarEvaluator::read(const FileNode& node)
features->resize(n); features->resize(n);
FileNodeIterator it = node.begin(); FileNodeIterator it = node.begin();
hasTiltedFeatures = false; hasTiltedFeatures = false;
std::vector<Feature> ff = *features; std::vector<Feature>& ff = *features;
sumSize0 = Size(); sumSize0 = Size();
ufbuf.release(); ufbuf.release();
...@@ -552,30 +553,37 @@ bool HaarEvaluator::setImage( InputArray _image, Size _origWinSize, Size _sumSiz ...@@ -552,30 +553,37 @@ bool HaarEvaluator::setImage( InputArray _image, Size _origWinSize, Size _sumSiz
tofs = (int)((utilted.offset - usum.offset)/sizeof(int)); tofs = (int)((utilted.offset - usum.offset)/sizeof(int));
} }
else else
{
integral(_image, usum, noArray(), noArray(), CV_32S); integral(_image, usum, noArray(), noArray(), CV_32S);
}
sqrBoxFilter(_image, usqsum, CV_32S, sqrBoxFilter(_image, usqsum, CV_32S,
Size(normrect.width, normrect.height), Size(normrect.width, normrect.height),
Point(0, 0), false); Point(0, 0), false);
/*sqrBoxFilter(_image.getMat(), sqsum, CV_32S,
Size(normrect.width, normrect.height),
Point(0, 0), false);
sqsum.copyTo(usqsum);*/
sumStep = (int)(usum.step/usum.elemSize()); sumStep = (int)(usum.step/usum.elemSize());
} }
else else
{ {
sum0.create(rn*rn_scale, cn, CV_32S); sum0.create(rn*rn_scale, cn, CV_32S);
sqsum0.create(rn, cn, CV_64F); sqsum0.create(rn, cn, CV_32S);
sum = sum0(Rect(0, 0, cols+1, rows+1)); sum = sum0(Rect(0, 0, cols+1, rows+1));
sqsum = sqsum0(Rect(0, 0, cols+1, rows+1)); sqsum = sqsum0(Rect(0, 0, cols, rows));
if( hasTiltedFeatures ) if( hasTiltedFeatures )
{ {
Mat tilted = sum0(Rect(0, _sumSize.height, cols+1, rows+1)); Mat tilted = sum0(Rect(0, _sumSize.height, cols+1, rows+1));
integral(_image, sum, sqsum, tilted, CV_32S); integral(_image, sum, noArray(), tilted, CV_32S);
tofs = (int)((tilted.data - sum.data)/sizeof(int)); tofs = (int)((tilted.data - sum.data)/sizeof(int));
} }
else else
integral(_image, sum, sqsum, noArray(), CV_32S); integral(_image, sum, noArray(), noArray(), CV_32S);
/*sqrBoxFilter(_image, sqsum, CV_32S, sqrBoxFilter(_image, sqsum, CV_32S,
Size(normrect.width, normrect.height), Size(normrect.width, normrect.height),
Point(0, 0), false);*/ Point(0, 0), false);
sumStep = (int)(sum.step/sum.elemSize()); sumStep = (int)(sum.step/sum.elemSize());
} }
...@@ -592,7 +600,7 @@ bool HaarEvaluator::setImage( InputArray _image, Size _origWinSize, Size _sumSiz ...@@ -592,7 +600,7 @@ bool HaarEvaluator::setImage( InputArray _image, Size _origWinSize, Size _sumSiz
optfeaturesPtr[fi].setOffsets( ff[fi], sumStep, tofs ); optfeaturesPtr[fi].setOffsets( ff[fi], sumStep, tofs );
} }
if( _image.isUMat() && (sumSize0 != _sumSize || ufbuf.empty()) ) if( _image.isUMat() && (sumSize0 != _sumSize || ufbuf.empty()) )
copyVectorToUMat(ff, ufbuf); copyVectorToUMat(*optfeatures, ufbuf);
sumSize0 = _sumSize; sumSize0 = _sumSize;
return true; return true;
...@@ -608,13 +616,7 @@ bool HaarEvaluator::setWindow( Point pt ) ...@@ -608,13 +616,7 @@ bool HaarEvaluator::setWindow( Point pt )
const int* p = &sum.at<int>(pt); const int* p = &sum.at<int>(pt);
int valsum = CALC_SUM_OFS(nofs, p); int valsum = CALC_SUM_OFS(nofs, p);
double valsqsum = sqsum.at<int>(pt.y + normrect.y, pt.x + normrect.x);
int nqofs[4];
CV_SUM_OFS( nqofs[0], nqofs[1], nqofs[2], nqofs[3], 0, normrect, (int)(sqsum.step/sizeof(double)) );
const double* pq = &sqsum.at<double>(pt);
double valsqsum = CALC_SUM_OFS(nqofs, pq);
//double valsqsum = sqsum.at<int>(pt.y + normrect.y, pt.x + normrect.x);
double nf = (double)normrect.area() * valsqsum - (double)valsum * valsum; double nf = (double)normrect.area() * valsqsum - (double)valsum * valsum;
if( nf > 0. ) if( nf > 0. )
...@@ -1131,8 +1133,6 @@ bool CascadeClassifierImpl::detectSingleScale( InputArray _image, Size processin ...@@ -1131,8 +1133,6 @@ bool CascadeClassifierImpl::detectSingleScale( InputArray _image, Size processin
bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size processingRectSize, bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size processingRectSize,
int yStep, double factor, Size sumSize0 ) int yStep, double factor, Size sumSize0 )
{ {
const int MAX_FACES = 10000;
Ptr<HaarEvaluator> haar = featureEvaluator.dynamicCast<HaarEvaluator>(); Ptr<HaarEvaluator> haar = featureEvaluator.dynamicCast<HaarEvaluator>();
if( haar.empty() ) if( haar.empty() )
return false; return false;
...@@ -1141,7 +1141,8 @@ bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size proce ...@@ -1141,7 +1141,8 @@ bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size proce
if( cascadeKernel.empty() ) if( cascadeKernel.empty() )
{ {
//cascadeKernel.create(") cascadeKernel.create("runHaarClassifierStump", ocl::objdetect::haarobjectdetect_oclsrc,
format("-D MAX_FACES=%d", MAX_FACES));
if( cascadeKernel.empty() ) if( cascadeKernel.empty() )
return false; return false;
} }
...@@ -1152,30 +1153,35 @@ bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size proce ...@@ -1152,30 +1153,35 @@ bool CascadeClassifierImpl::ocl_detectSingleScale( InputArray _image, Size proce
copyVectorToUMat(data.classifiers, uclassifiers); copyVectorToUMat(data.classifiers, uclassifiers);
copyVectorToUMat(data.nodes, unodes); copyVectorToUMat(data.nodes, unodes);
copyVectorToUMat(data.leaves, uleaves); copyVectorToUMat(data.leaves, uleaves);
ufacepos.create(1, MAX_FACES*4 + 1, CV_32S);
} }
std::vector<UMat> bufs; std::vector<UMat> bufs;
haar->getUMats(bufs); haar->getUMats(bufs);
CV_Assert(bufs.size() == 3); CV_Assert(bufs.size() == 3);
Rect normrect = haar->getNormRect();
//processingRectSize = Size(yStep, yStep);
size_t globalsize[] = { processingRectSize.width/yStep, processingRectSize.height/yStep }; size_t globalsize[] = { processingRectSize.width/yStep, processingRectSize.height/yStep };
return cascadeKernel.args(ocl::KernelArg::ReadOnly(bufs[0]), // sum cascadeKernel.args(ocl::KernelArg::ReadOnlyNoSize(bufs[0]), // sum
ocl::KernelArg::ReadOnly(bufs[1]), // sqsum ocl::KernelArg::ReadOnlyNoSize(bufs[1]), // sqsum
ocl::KernelArg::PtrReadOnly(bufs[2]), // optfeatures ocl::KernelArg::PtrReadOnly(bufs[2]), // optfeatures
// cascade classifier // cascade classifier
(int)data.stages.size(),
ocl::KernelArg::PtrReadOnly(ustages), ocl::KernelArg::PtrReadOnly(ustages),
ocl::KernelArg::PtrReadOnly(uclassifiers), ocl::KernelArg::PtrReadOnly(uclassifiers),
ocl::KernelArg::PtrReadOnly(unodes), ocl::KernelArg::PtrReadOnly(unodes),
ocl::KernelArg::PtrReadOnly(uleaves), ocl::KernelArg::PtrReadOnly(uleaves),
ocl::KernelArg::WriteOnly(ufacepos), // positions ocl::KernelArg::PtrWriteOnly(ufacepos), // positions
ocl::KernelArg::PtrReadOnly(uparams), processingRectSize,
processingRectSize.width, yStep, (float)factor,
processingRectSize.height, normrect, data.origWinSize);
yStep, (float)factor, MAX_FACES).run(2, globalsize, 0, false); bool ok = cascadeKernel.run(2, globalsize, 0, true);
//CV_Assert(ok);
return ok;
} }
bool CascadeClassifierImpl::isOldFormatCascade() const bool CascadeClassifierImpl::isOldFormatCascade() const
...@@ -1234,12 +1240,13 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std:: ...@@ -1234,12 +1240,13 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
if( maxObjectSize.height == 0 || maxObjectSize.width == 0 ) if( maxObjectSize.height == 0 || maxObjectSize.width == 0 )
maxObjectSize = imgsz; maxObjectSize = imgsz;
bool use_ocl = false;/*ocl::useOpenCL() && bool use_ocl = ocl::useOpenCL() &&
getFeatureType() == FeatureEvaluator::HAAR && getFeatureType() == FeatureEvaluator::HAAR &&
!isOldFormatCascade() && !isOldFormatCascade() &&
data.isStumpBased &&
maskGenerator.empty() && maskGenerator.empty() &&
!outputRejectLevels && !outputRejectLevels &&
tryOpenCL;*/ tryOpenCL;
if( !use_ocl ) if( !use_ocl )
{ {
...@@ -1268,13 +1275,20 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std:: ...@@ -1268,13 +1275,20 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
} }
Size sumSize0((imgsz.width + SUM_ALIGN) & -SUM_ALIGN, imgsz.height+1); Size sumSize0((imgsz.width + SUM_ALIGN) & -SUM_ALIGN, imgsz.height+1);
if( use_ocl )
{
ufacepos.create(1, MAX_FACES*4 + 1, CV_32S);
UMat ufacecount(ufacepos, Rect(0,0,1,1));
ufacecount.setTo(Scalar::all(0));
}
for( double factor = 1; ; factor *= scaleFactor ) for( double factor = 1; ; factor *= scaleFactor )
{ {
Size originalWindowSize = getOriginalWindowSize(); Size originalWindowSize = getOriginalWindowSize();
Size windowSize( cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) ); Size windowSize( cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) );
Size scaledImageSize( cvRound( grayImage.cols/factor ), cvRound( grayImage.rows/factor ) ); Size scaledImageSize( cvRound( imgsz.width/factor ), cvRound( imgsz.height/factor ) );
Size processingRectSize( scaledImageSize.width - originalWindowSize.width, Size processingRectSize( scaledImageSize.width - originalWindowSize.width,
scaledImageSize.height - originalWindowSize.height ); scaledImageSize.height - originalWindowSize.height );
...@@ -1331,6 +1345,7 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std:: ...@@ -1331,6 +1345,7 @@ void CascadeClassifierImpl::detectMultiScaleNoGrouping( InputArray _image, std::
Mat facepos = ufacepos.getMat(ACCESS_READ); Mat facepos = ufacepos.getMat(ACCESS_READ);
const int* fptr = facepos.ptr<int>(); const int* fptr = facepos.ptr<int>();
int i, nfaces = fptr[0]; int i, nfaces = fptr[0];
printf("nfaces = %d\n", nfaces);
for( i = 0; i < nfaces; i++ ) for( i = 0; i < nfaces; i++ )
{ {
candidates.push_back(Rect(fptr[i*4+1], fptr[i*4+2], fptr[i*4+3], fptr[i*4+4])); candidates.push_back(Rect(fptr[i*4+1], fptr[i*4+2], fptr[i*4+3], fptr[i*4+4]));
...@@ -1439,8 +1454,6 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) ...@@ -1439,8 +1454,6 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
origWinSize.height = (int)root[CC_HEIGHT]; origWinSize.height = (int)root[CC_HEIGHT];
CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 ); CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 );
isStumpBased = (int)(root[CC_STAGE_PARAMS][CC_MAX_DEPTH]) == 1 ? true : false;
// load feature params // load feature params
FileNode fn = root[CC_FEATURE_PARAMS]; FileNode fn = root[CC_FEATURE_PARAMS];
if( fn.empty() ) if( fn.empty() )
...@@ -1460,6 +1473,7 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) ...@@ -1460,6 +1473,7 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
nodes.clear(); nodes.clear();
FileNodeIterator it = fn.begin(), it_end = fn.end(); FileNodeIterator it = fn.begin(), it_end = fn.end();
isStumpBased = true;
for( int si = 0; it != it_end; si++, ++it ) for( int si = 0; it != it_end; si++, ++it )
{ {
...@@ -1485,6 +1499,9 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) ...@@ -1485,6 +1499,9 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
DTree tree; DTree tree;
tree.nodeCount = (int)internalNodes.size()/nodeStep; tree.nodeCount = (int)internalNodes.size()/nodeStep;
if( tree.nodeCount > 1 )
isStumpBased = false;
classifiers.push_back(tree); classifiers.push_back(tree);
nodes.reserve(nodes.size() + tree.nodeCount); nodes.reserve(nodes.size() + tree.nodeCount);
......
...@@ -63,8 +63,8 @@ protected: ...@@ -63,8 +63,8 @@ protected:
double scaleFactor, Size minObjectSize, Size maxObjectSize, double scaleFactor, Size minObjectSize, Size maxObjectSize,
bool outputRejectLevels = false ); bool outputRejectLevels = false );
enum { BOOST = 0 enum { MAX_FACES = 10000 };
}; enum { BOOST = 0 };
enum { DO_CANNY_PRUNING = CASCADE_DO_CANNY_PRUNING, enum { DO_CANNY_PRUNING = CASCADE_DO_CANNY_PRUNING,
SCALE_IMAGE = CASCADE_SCALE_IMAGE, SCALE_IMAGE = CASCADE_SCALE_IMAGE,
FIND_BIGGEST_OBJECT = CASCADE_FIND_BIGGEST_OBJECT, FIND_BIGGEST_OBJECT = CASCADE_FIND_BIGGEST_OBJECT,
...@@ -132,7 +132,7 @@ protected: ...@@ -132,7 +132,7 @@ protected:
Ptr<MaskGenerator> maskGenerator; Ptr<MaskGenerator> maskGenerator;
UMat ugrayImage, uimageBuffer; UMat ugrayImage, uimageBuffer;
UMat ufacepos, ustages, uclassifiers, unodes, uleaves, usubsets, uparams; UMat ufacepos, ustages, uclassifiers, unodes, uleaves, usubsets;
ocl::Kernel cascadeKernel; ocl::Kernel cascadeKernel;
bool tryOpenCL; bool tryOpenCL;
...@@ -327,19 +327,19 @@ inline void HaarEvaluator::OptFeature :: setOffsets( const Feature& _f, int step ...@@ -327,19 +327,19 @@ inline void HaarEvaluator::OptFeature :: setOffsets( const Feature& _f, int step
weight[0] = _f.rect[0].weight; weight[0] = _f.rect[0].weight;
weight[1] = _f.rect[1].weight; weight[1] = _f.rect[1].weight;
weight[2] = _f.rect[2].weight; weight[2] = _f.rect[2].weight;
Rect r2 = weight[2] > 0 ? _f.rect[2].r : Rect(0,0,0,0);
if (_f.tilted) if (_f.tilted)
{ {
CV_TILTED_OFS( ofs[0][0], ofs[0][1], ofs[0][2], ofs[0][3], tofs, _f.rect[0].r, step ); CV_TILTED_OFS( ofs[0][0], ofs[0][1], ofs[0][2], ofs[0][3], tofs, _f.rect[0].r, step );
CV_TILTED_OFS( ofs[1][0], ofs[1][1], ofs[1][2], ofs[1][3], tofs, _f.rect[1].r, step ); CV_TILTED_OFS( ofs[1][0], ofs[1][1], ofs[1][2], ofs[1][3], tofs, _f.rect[1].r, step );
if (weight[2]) CV_TILTED_PTRS( ofs[2][0], ofs[2][1], ofs[2][2], ofs[2][3], tofs, r2, step );
CV_TILTED_PTRS( ofs[2][0], ofs[2][1], ofs[2][2], ofs[2][3], tofs, _f.rect[2].r, step );
} }
else else
{ {
CV_SUM_OFS( ofs[0][0], ofs[0][1], ofs[0][2], ofs[0][3], 0, _f.rect[0].r, step ); CV_SUM_OFS( ofs[0][0], ofs[0][1], ofs[0][2], ofs[0][3], 0, _f.rect[0].r, step );
CV_SUM_OFS( ofs[1][0], ofs[1][1], ofs[1][2], ofs[1][3], 0, _f.rect[1].r, step ); CV_SUM_OFS( ofs[1][0], ofs[1][1], ofs[1][2], ofs[1][3], 0, _f.rect[1].r, step );
if (weight[2]) CV_SUM_OFS( ofs[2][0], ofs[2][1], ofs[2][2], ofs[2][3], 0, r2, step );
CV_SUM_OFS( ofs[2][0], ofs[2][1], ofs[2][2], ofs[2][3], 0, _f.rect[2].r, step );
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment