diff --git a/modules/gpu/include/opencv2/gpu/gpu.hpp b/modules/gpu/include/opencv2/gpu/gpu.hpp index f8a16ee2a..4c3af5956 100644 --- a/modules/gpu/include/opencv2/gpu/gpu.hpp +++ b/modules/gpu/include/opencv2/gpu/gpu.hpp @@ -1428,7 +1428,7 @@ class CV_EXPORTS CascadeClassifier_GPU_LBP public: enum stage { BOOST = 0 }; enum feature { LBP = 0 }; - CascadeClassifier_GPU_LBP(); + CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize = cv::Size()); ~CascadeClassifier_GPU_LBP(); bool empty() const; @@ -1441,6 +1441,7 @@ public: Size getClassifierSize() const; private: bool read(const FileNode &root); + void initializeBuffers(cv::Size frame); static const stage stageType = BOOST; static const feature featureType = LBP; @@ -1459,8 +1460,9 @@ private: GpuMat subsets_mat; GpuMat features_mat; - // current integral image GpuMat integral; + GpuMat integralBuffer; + GpuMat resuzeBuffer; }; ////////////////////////////////// SURF ////////////////////////////////////////// diff --git a/modules/gpu/perf/perf_objdetect.cpp b/modules/gpu/perf/perf_objdetect.cpp index 5fd2297bd..e1990488a 100644 --- a/modules/gpu/perf/perf_objdetect.cpp +++ b/modules/gpu/perf/perf_objdetect.cpp @@ -66,12 +66,12 @@ GPU_PERF_TEST_1(LBPClassifier, cv::gpu::DeviceInfo) cv::Mat img_host = readImage("gpu/haarcascade/group_1_640x480_VGA.pgm", cv::IMREAD_GRAYSCALE); ASSERT_FALSE(img_host.empty()); - cv::gpu::CascadeClassifier_GPU_LBP cascade; - ASSERT_TRUE(cascade.load(perf::TestBase::getDataPath("gpu/lbpcascade/lbpcascade_frontalface.xml"))); cv::gpu::GpuMat img(img_host); cv::gpu::GpuMat gpu_rects, buffer; + cv::gpu::CascadeClassifier_GPU_LBP cascade(img.size()); + ASSERT_TRUE(cascade.load(perf::TestBase::getDataPath("gpu/lbpcascade/lbpcascade_frontalface.xml"))); // cascade.detectMultiScale(img, objects_buffer); cascade.detectMultiScale(img, buffer, gpu_rects); diff --git a/modules/gpu/src/cascadeclassifier.cpp b/modules/gpu/src/cascadeclassifier.cpp index da0bfe5ef..e8522568e 100644 --- a/modules/gpu/src/cascadeclassifier.cpp +++ b/modules/gpu/src/cascadeclassifier.cpp @@ -61,20 +61,46 @@ Size cv::gpu::CascadeClassifier_GPU::getClassifierSize() const { throw_nogpu(); int cv::gpu::CascadeClassifier_GPU::detectMultiScale( const GpuMat& , GpuMat& , double , int , Size) { throw_nogpu(); return 0; } // ============ LBP cascade ==============================================// -cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP() { throw_nogpu(); } -cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP() { throw_nogpu(); } +cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size /*frameSize*/){ throw_nogpu(); } +cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP() { throw_nogpu(); } bool cv::gpu::CascadeClassifier_GPU_LBP::empty() const { throw_nogpu(); return true; } bool cv::gpu::CascadeClassifier_GPU_LBP::load(const string&) { throw_nogpu(); return true; } Size cv::gpu::CascadeClassifier_GPU_LBP::getClassifierSize() const { throw_nogpu(); return Size(); } void cv::gpu::CascadeClassifier_GPU_LBP::preallocateIntegralBuffer(cv::Size /*desired*/) { throw_nogpu();} +void cv::gpu::CascadeClassifier_GPU_LBP::initializeBuffers(cv::Size /*frame*/) { throw_nogpu();} int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const cv::gpu::GpuMat& /*image*/, cv::gpu::GpuMat& /*scaledImageBuffer*/, cv::gpu::GpuMat& /*objectsBuf*/, double /*scaleFactor*/, int /*minNeighbors*/, cv::Size /*maxObjectSize*/){ throw_nogpu(); return 0;} #else -cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(){} +cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize) +{ + if (detectionFrameSize != cv::Size()) + initializeBuffers(detectionFrameSize); +} + +void cv::gpu::CascadeClassifier_GPU_LBP::initializeBuffers(cv::Size frame) +{ + if (resuzeBuffer.empty() || frame.width > resuzeBuffer.cols || frame.height > resuzeBuffer.rows) + { + resuzeBuffer.create(frame, CV_8UC1); + + integral.create(frame.height + 1, frame.width + 1, CV_32SC1); + NcvSize32u roiSize; + roiSize.width = frame.width; + roiSize.height = frame.height; + + cudaDeviceProp prop; + cudaSafeCall( cudaGetDeviceProperties(&prop, cv::gpu::getDevice()) ); + + Ncv32u bufSize; + ncvSafeCall( nppiStIntegralGetSize_8u32u(roiSize, &bufSize, prop) ); + // printf("HERE!!!!!!!%d\n", bufSize); + integralBuffer.create(1, bufSize, CV_8UC1); + } +} cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP(){} @@ -309,10 +335,12 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp objects.create(1 , defaultObjSearchNum, CV_32SC4); GpuMat candidates(1 , defaultObjSearchNum, CV_32SC4); + // GpuMat candidates(objects); if (maxObjectSize == cv::Size()) maxObjectSize = image.size(); - scaledImageBuffer.create(image.rows + 1, image.cols + 1, CV_8U); + initializeBuffers(image.size()); + unsigned int* classified = new unsigned int[1]; *classified = 0; unsigned int* dclassified; @@ -335,13 +363,17 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp // if( windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height ) // continue; - cv::gpu::resize(image, scaledImageBuffer, scaledImageSize, 0, 0, CV_INTER_LINEAR); - cv::gpu::integral(scaledImageBuffer, integral); + GpuMat scaledImg(resuzeBuffer, cv::Rect(0, 0, scaledImageSize.width, scaledImageSize.height)); + GpuMat scaledIntegral(integral, cv::Rect(0, 0, scaledImageSize.width + 1, scaledImageSize.height + 1)); + GpuMat currBuff = integralBuffer;//(integralBuffer, cv::Rect(0, 0, integralBuffer.width, integralBuffer.height)); + + cv::gpu::resize(image, scaledImg, scaledImageSize, 0, 0, CV_INTER_LINEAR); + cv::gpu::integralBuffered(scaledImg, scaledIntegral, currBuff); step = (factor <= 2.) + 1; cv::gpu::device::lbp::classifyStump(stage_mat, stage_mat.cols / sizeof(Stage), nodes_mat, leaves_mat, subsets_mat, features_mat, - integral, processingRectSize.width, processingRectSize.height, windowSize.width, windowSize.height, factor, step, subsetSize, candidates, dclassified); + scaledIntegral, processingRectSize.width, processingRectSize.height, windowSize.width, windowSize.height, factor, step, subsetSize, candidates, dclassified); } if (groupThreshold <= 0 || objects.empty()) return 0;