[~] Refactored, cleaned up, and consolidated the code of GPU examples (cascadeclassif...
authorAnton Obukhov <no@email>
Thu, 7 Apr 2011 12:59:01 +0000 (12:59 +0000)
committerAnton Obukhov <no@email>
Thu, 7 Apr 2011 12:59:01 +0000 (12:59 +0000)
modules/gpu/include/opencv2/gpu/gpu.hpp
modules/gpu/src/cascadeclassifier.cpp
samples/gpu/cascadeclassifier.cpp
samples/gpu/cascadeclassifier_nvidia_api.cpp

index f487ac6..6b324f8 100644 (file)
@@ -1520,7 +1520,7 @@ namespace cv
         // The cascade classifier class for object detection.\r
         class CV_EXPORTS CascadeClassifier_GPU\r
         {\r
-        public:            \r
+        public:\r
             CascadeClassifier_GPU();\r
             CascadeClassifier_GPU(const string& filename);\r
             ~CascadeClassifier_GPU();\r
@@ -1528,20 +1528,20 @@ namespace cv
             bool empty() const;\r
             bool load(const string& filename);\r
             void release();\r
-            \r
+\r
             /* returns number of detected objects */\r
             int detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor=1.2, int minNeighbors=4, Size minSize=Size());\r
-                                    \r
+\r
             bool findLargestObject;\r
             bool visualizeInPlace;\r
 \r
             Size getClassifierSize() const;\r
         private:\r
-            \r
-            struct CascadeClassifierImpl;                        \r
-            CascadeClassifierImpl* impl;            \r
+\r
+            struct CascadeClassifierImpl;\r
+            CascadeClassifierImpl* impl;\r
         };\r
-        \r
+\r
         ////////////////////////////////// SURF //////////////////////////////////////////\r
 \r
         class CV_EXPORTS SURF_GPU : public CvSURFParams\r
index 35653a0..0ffd10c 100644 (file)
@@ -62,16 +62,22 @@ int cv::gpu::CascadeClassifier_GPU::detectMultiScale( const GpuMat& , GpuMat& ,
 #else\r
 \r
 struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl\r
-{    \r
+{\r
     CascadeClassifierImpl(const string& filename) : lastAllocatedFrameSize(-1, -1)\r
     {\r
-        ncvSetDebugOutputHandler(NCVDebugOutputHandler);            \r
+        ncvSetDebugOutputHandler(NCVDebugOutputHandler);\r
         if (ncvStat != load(filename))\r
+        {\r
             CV_Error(CV_GpuApiCallError, "Error in GPU cacade load");\r
-    }    \r
-    NCVStatus process(const GpuMat& src, GpuMat& objects, float scaleStep, int minNeighbors, bool findLargestObject, bool visualizeInPlace, NcvSize32u ncvMinSize, /*out*/unsigned int& numDetections)\r
-    {   \r
-        calculateMemReqsAndAllocate(src.size());        \r
+        }\r
+    }\r
+\r
+\r
+    NCVStatus process(const GpuMat& src, GpuMat& objects, float scaleStep, int minNeighbors,\r
+                      bool findLargestObject, bool visualizeInPlace, NcvSize32u ncvMinSize,\r
+                      /*out*/unsigned int& numDetections)\r
+    {\r
+        calculateMemReqsAndAllocate(src.size());\r
 \r
         NCVMemPtr src_beg;\r
         src_beg.ptr = (void*)src.ptr<Ncv8u>();\r
@@ -81,14 +87,8 @@ struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
         src_seg.begin = src_beg;\r
         src_seg.size  = src.step * src.rows;\r
 \r
-        NCVMatrixReuse<Ncv8u> d_src(src_seg, devProp.textureAlignment, src.cols, src.rows, src.step, true);        \r
-               ncvAssertReturn(d_src.isMemReused(), NCV_ALLOCATOR_BAD_REUSE);\r
-        \r
-        //NCVMatrixAlloc<Ncv8u> d_src(*gpuAllocator, src.cols, src.rows);\r
-        //ncvAssertReturn(d_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);\r
-\r
-        //NCVMatrixAlloc<Ncv8u> h_src(*cpuAllocator, src.cols, src.rows);\r
-        //ncvAssertReturn(h_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);\r
+        NCVMatrixReuse<Ncv8u> d_src(src_seg, devProp.textureAlignment, src.cols, src.rows, src.step, true);\r
+        ncvAssertReturn(d_src.isMemReused(), NCV_ALLOCATOR_BAD_REUSE);\r
 \r
         CV_Assert(objects.rows == 1);\r
 \r
@@ -100,10 +100,8 @@ struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
         objects_seg.begin = objects_beg;\r
         objects_seg.size = objects.step * objects.rows;\r
         NCVVectorReuse<NcvRect32u> d_rects(objects_seg, objects.cols);\r
-               ncvAssertReturn(d_rects.isMemReused(), NCV_ALLOCATOR_BAD_REUSE);\r
-        //NCVVectorAlloc<NcvRect32u> d_rects(*gpuAllocator, 100);        \r
-        //ncvAssertReturn(d_rects.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);        \r
-            \r
+        ncvAssertReturn(d_rects.isMemReused(), NCV_ALLOCATOR_BAD_REUSE);\r
+\r
         NcvSize32u roi;\r
         roi.width = d_src.width();\r
         roi.height = d_src.height();\r
@@ -111,7 +109,7 @@ struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
         Ncv32u flags = 0;\r
         flags |= findLargestObject? NCVPipeObjDet_FindLargestObject : 0;\r
         flags |= visualizeInPlace ? NCVPipeObjDet_VisualizeInPlace  : 0;\r
-        \r
+\r
         ncvStat = ncvDetectObjectsMultiScale_device(\r
             d_src, roi, d_rects, numDetections, haar, *h_haarStages,\r
             *d_haarStages, *d_haarNodes, *d_haarFeatures,\r
@@ -122,24 +120,28 @@ struct cv::gpu::CascadeClassifier_GPU::CascadeClassifierImpl
             *gpuAllocator, *cpuAllocator, devProp, 0);\r
         ncvAssertReturnNcvStat(ncvStat);\r
         ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR);\r
-                       \r
+\r
         return NCV_SUCCESS;\r
     }\r
-    ////\r
-    \r
+\r
+\r
     NcvSize32u getClassifierSize() const  { return haar.ClassifierSize; }\r
     cv::Size getClassifierCvSize() const { return cv::Size(haar.ClassifierSize.width, haar.ClassifierSize.height); }\r
+\r
+\r
 private:\r
 \r
+\r
     static void NCVDebugOutputHandler(const char* msg) { CV_Error(CV_GpuApiCallError, msg); }\r
 \r
+\r
     NCVStatus load(const string& classifierFile)\r
-    {        \r
-        int devId = cv::gpu::getDevice();           \r
+    {\r
+        int devId = cv::gpu::getDevice();\r
         ncvAssertCUDAReturn(cudaGetDeviceProperties(&devProp, devId), NCV_CUDA_ERROR);\r
 \r
         // Load the classifier from file (assuming its size is about 1 mb) using a simple allocator\r
-        gpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeDevice, devProp.textureAlignment);        \r
+        gpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeDevice, devProp.textureAlignment);\r
         cpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeHostPinned, devProp.textureAlignment);\r
 \r
         ncvAssertPrintReturn(gpuCascadeAllocator->isInitialized(), "Error creating cascade GPU allocator", NCV_CUDA_ERROR);\r
@@ -149,12 +151,12 @@ private:
         ncvStat = ncvHaarGetClassifierSize(classifierFile, haarNumStages, haarNumNodes, haarNumFeatures);\r
         ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error reading classifier size (check the file)", NCV_FILE_ERROR);\r
 \r
-        h_haarStages   = new NCVVectorAlloc<HaarStage64>(*cpuCascadeAllocator, haarNumStages);        \r
+        h_haarStages   = new NCVVectorAlloc<HaarStage64>(*cpuCascadeAllocator, haarNumStages);\r
         h_haarNodes    = new NCVVectorAlloc<HaarClassifierNode128>(*cpuCascadeAllocator, haarNumNodes);\r
         h_haarFeatures = new NCVVectorAlloc<HaarFeature64>(*cpuCascadeAllocator, haarNumFeatures);\r
 \r
         ncvAssertPrintReturn(h_haarStages->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR);\r
-        ncvAssertPrintReturn(h_haarNodes->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR);        \r
+        ncvAssertPrintReturn(h_haarNodes->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR);\r
         ncvAssertPrintReturn(h_haarFeatures->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR);\r
 \r
         ncvStat = ncvHaarLoadFromFile_host(classifierFile, haar, *h_haarStages, *h_haarNodes, *h_haarFeatures);\r
@@ -165,7 +167,7 @@ private:
         d_haarFeatures = new NCVVectorAlloc<HaarFeature64>(*gpuCascadeAllocator, haarNumFeatures);\r
 \r
         ncvAssertPrintReturn(d_haarStages->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR);\r
-        ncvAssertPrintReturn(d_haarNodes->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR);                        \r
+        ncvAssertPrintReturn(d_haarNodes->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR);\r
         ncvAssertPrintReturn(d_haarFeatures->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR);\r
 \r
         ncvStat = h_haarStages->copySolid(*d_haarStages, 0);\r
@@ -173,31 +175,33 @@ private:
         ncvStat = h_haarNodes->copySolid(*d_haarNodes, 0);\r
         ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR);\r
         ncvStat = h_haarFeatures->copySolid(*d_haarFeatures, 0);\r
-        ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR);    \r
+        ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR);\r
 \r
         return NCV_SUCCESS;\r
     }\r
-    ////\r
+\r
 \r
     NCVStatus calculateMemReqsAndAllocate(const Size& frameSize)\r
-    {        \r
+    {\r
         if (lastAllocatedFrameSize == frameSize)\r
+        {\r
             return NCV_SUCCESS;\r
+        }\r
 \r
         // Calculate memory requirements and create real allocators\r
         NCVMemStackAllocator gpuCounter(devProp.textureAlignment);\r
         NCVMemStackAllocator cpuCounter(devProp.textureAlignment);\r
 \r
-        ncvAssertPrintReturn(gpuCounter.isInitialized(), "Error creating GPU memory counter", NCV_CUDA_ERROR);        \r
+        ncvAssertPrintReturn(gpuCounter.isInitialized(), "Error creating GPU memory counter", NCV_CUDA_ERROR);\r
         ncvAssertPrintReturn(cpuCounter.isInitialized(), "Error creating CPU memory counter", NCV_CUDA_ERROR);\r
-        \r
+\r
         NCVMatrixAlloc<Ncv8u> d_src(gpuCounter, frameSize.width, frameSize.height);\r
         NCVMatrixAlloc<Ncv8u> h_src(cpuCounter, frameSize.width, frameSize.height);\r
 \r
-        ncvAssertReturn(d_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);        \r
+        ncvAssertReturn(d_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);\r
         ncvAssertReturn(h_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);\r
 \r
-        NCVVectorAlloc<NcvRect32u> d_rects(gpuCounter, 100);        \r
+        NCVVectorAlloc<NcvRect32u> d_rects(gpuCounter, 100);\r
         ncvAssertReturn(d_rects.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC);\r
 \r
         NcvSize32u roi;\r
@@ -209,23 +213,23 @@ private:
 \r
         ncvAssertReturnNcvStat(ncvStat);\r
         ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR);\r
-                      \r
-        gpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeDevice, gpuCounter.maxSize(), devProp.textureAlignment);        \r
+\r
+        gpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeDevice, gpuCounter.maxSize(), devProp.textureAlignment);\r
         cpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeHostPinned, cpuCounter.maxSize(), devProp.textureAlignment);\r
 \r
         ncvAssertPrintReturn(gpuAllocator->isInitialized(), "Error creating GPU memory allocator", NCV_CUDA_ERROR);\r
-        ncvAssertPrintReturn(cpuAllocator->isInitialized(), "Error creating CPU memory allocator", NCV_CUDA_ERROR);        \r
+        ncvAssertPrintReturn(cpuAllocator->isInitialized(), "Error creating CPU memory allocator", NCV_CUDA_ERROR);\r
         return NCV_SUCCESS;\r
     }\r
-    //// \r
+\r
 \r
     cudaDeviceProp devProp;\r
     NCVStatus ncvStat;\r
 \r
-    Ptr<NCVMemNativeAllocator> gpuCascadeAllocator;        \r
+    Ptr<NCVMemNativeAllocator> gpuCascadeAllocator;\r
     Ptr<NCVMemNativeAllocator> cpuCascadeAllocator;\r
 \r
-    Ptr<NCVVectorAlloc<HaarStage64> >           h_haarStages;        \r
+    Ptr<NCVVectorAlloc<HaarStage64> >           h_haarStages;\r
     Ptr<NCVVectorAlloc<HaarClassifierNode128> > h_haarNodes;\r
     Ptr<NCVVectorAlloc<HaarFeature64> >         h_haarFeatures;\r
 \r
@@ -237,96 +241,103 @@ private:
 \r
     Size lastAllocatedFrameSize;\r
 \r
-    Ptr<NCVMemStackAllocator> gpuAllocator;        \r
+    Ptr<NCVMemStackAllocator> gpuAllocator;\r
     Ptr<NCVMemStackAllocator> cpuAllocator;\r
 };\r
 \r
 \r
-\r
 cv::gpu::CascadeClassifier_GPU::CascadeClassifier_GPU() : findLargestObject(false), visualizeInPlace(false), impl(0) {}\r
 cv::gpu::CascadeClassifier_GPU::CascadeClassifier_GPU(const string& filename) : findLargestObject(false), visualizeInPlace(false), impl(0) { load(filename); }\r
 cv::gpu::CascadeClassifier_GPU::~CascadeClassifier_GPU() { release(); }\r
 bool cv::gpu::CascadeClassifier_GPU::empty() const { return impl == 0; }\r
-\r
 void cv::gpu::CascadeClassifier_GPU::release() { if (impl) { delete impl; impl = 0; } }\r
 \r
+\r
 bool cv::gpu::CascadeClassifier_GPU::load(const string& filename)\r
-{         \r
+{\r
     release();\r
     impl = new CascadeClassifierImpl(filename);\r
-    return !this->empty();    \r
+    return !this->empty();\r
 }\r
 \r
+\r
 Size cv::gpu::CascadeClassifier_GPU::getClassifierSize() const\r
 {\r
     return this->empty() ? Size() : impl->getClassifierCvSize();\r
 }\r
-                            \r
+\r
+\r
 int cv::gpu::CascadeClassifier_GPU::detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor, int minNeighbors, Size minSize)\r
-{   \r
+{\r
     CV_Assert( scaleFactor > 1 && image.depth() == CV_8U);\r
     CV_Assert( !this->empty());\r
-        \r
+\r
     const int defaultObjSearchNum = 100;\r
     if (objectsBuf.empty())\r
+    {\r
         objectsBuf.create(1, defaultObjSearchNum, DataType<Rect>::type);\r
-    \r
+    }\r
+\r
     NcvSize32u ncvMinSize = impl->getClassifierSize();\r
 \r
     if (ncvMinSize.width < (unsigned)minSize.width && ncvMinSize.height < (unsigned)minSize.height)\r
     {\r
         ncvMinSize.width = minSize.width;\r
         ncvMinSize.height = minSize.height;\r
-    }    \r
-                \r
+    }\r
+\r
     unsigned int numDetections;\r
-    NCVStatus ncvStat = impl->process(image, objectsBuf, (float)scaleFactor, minNeighbors, findLargestObject, visualizeInPlace, ncvMinSize, numDetections);                 \r
+    NCVStatus ncvStat = impl->process(image, objectsBuf, (float)scaleFactor, minNeighbors, findLargestObject, visualizeInPlace, ncvMinSize, numDetections);\r
     if (ncvStat != NCV_SUCCESS)\r
+    {\r
         CV_Error(CV_GpuApiCallError, "Error in face detectioln");\r
+    }\r
 \r
     return numDetections;\r
 }\r
 \r
+\r
 struct RectConvert\r
 {\r
-       Rect operator()(const NcvRect32u& nr) const { return Rect(nr.x, nr.y, nr.width, nr.height); }\r
-       NcvRect32u operator()(const Rect& nr) const \r
-       { \r
-               NcvRect32u rect;\r
-               rect.x = nr.x;\r
-               rect.y = nr.y;\r
-               rect.width = nr.width;\r
-               rect.height = nr.height;\r
-               return rect; \r
-       }\r
+    Rect operator()(const NcvRect32u& nr) const { return Rect(nr.x, nr.y, nr.width, nr.height); }\r
+    NcvRect32u operator()(const Rect& nr) const\r
+    {\r
+        NcvRect32u rect;\r
+        rect.x = nr.x;\r
+        rect.y = nr.y;\r
+        rect.width = nr.width;\r
+        rect.height = nr.height;\r
+        return rect;\r
+    }\r
 };\r
 \r
+\r
 void groupRectangles(std::vector<NcvRect32u> &hypotheses, int groupThreshold, double eps, std::vector<Ncv32u> *weights)\r
 {\r
-       vector<Rect> rects(hypotheses.size());    \r
-       std::transform(hypotheses.begin(), hypotheses.end(), rects.begin(), RectConvert());\r
-    \r
-       if (weights) \r
-       {\r
-               vector<int> weights_int;\r
-               weights_int.assign(weights->begin(), weights->end());        \r
-               cv::groupRectangles(rects, weights_int, groupThreshold, eps);\r
-       }\r
-       else\r
-       {   \r
-               cv::groupRectangles(rects, groupThreshold, eps);\r
-       }\r
-       std::transform(rects.begin(), rects.end(), hypotheses.begin(), RectConvert());    \r
-       hypotheses.resize(rects.size());\r
+    vector<Rect> rects(hypotheses.size());\r
+    std::transform(hypotheses.begin(), hypotheses.end(), rects.begin(), RectConvert());\r
+\r
+    if (weights)\r
+    {\r
+        vector<int> weights_int;\r
+        weights_int.assign(weights->begin(), weights->end());\r
+        cv::groupRectangles(rects, weights_int, groupThreshold, eps);\r
+    }\r
+    else\r
+    {\r
+        cv::groupRectangles(rects, groupThreshold, eps);\r
+    }\r
+    std::transform(rects.begin(), rects.end(), hypotheses.begin(), RectConvert());\r
+    hypotheses.resize(rects.size());\r
 }\r
 \r
 \r
 #if 1 /* loadFromXML implementation switch */\r
 \r
-NCVStatus loadFromXML(const std::string &filename, \r
-                      HaarClassifierCascadeDescriptor &haar, \r
-                      std::vector<HaarStage64> &haarStages, \r
-                      std::vector<HaarClassifierNode128> &haarClassifierNodes, \r
+NCVStatus loadFromXML(const std::string &filename,\r
+                      HaarClassifierCascadeDescriptor &haar,\r
+                      std::vector<HaarStage64> &haarStages,\r
+                      std::vector<HaarClassifierNode128> &haarClassifierNodes,\r
                       std::vector<HaarFeature64> &haarFeatures)\r
 {\r
     NCVStatus ncvStat;\r
@@ -347,12 +358,12 @@ NCVStatus loadFromXML(const std::string &filename,
     haarStages.resize(0);\r
     haarClassifierNodes.resize(0);\r
     haarFeatures.resize(0);\r
-    \r
+\r
     Ptr<CvHaarClassifierCascade> oldCascade = (CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0);\r
     if (oldCascade.empty())\r
+    {\r
         return NCV_HAAR_XML_LOADING_EXCEPTION;\r
-\r
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
+    }\r
 \r
     haar.ClassifierSize.width = oldCascade->orig_window_size.width;\r
     haar.ClassifierSize.height = oldCascade->orig_window_size.height;\r
@@ -384,14 +395,14 @@ NCVStatus loadFromXML(const std::string &filename,
 \r
                 HaarClassifierNodeDescriptor32 nodeLeft;\r
                 if ( tree->left[n] <= 0 )\r
-                {   \r
+                {\r
                     Ncv32f leftVal = tree->alpha[-tree->left[n]];\r
                     ncvStat = nodeLeft.create(leftVal);\r
                     ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat);\r
                     bIsLeftNodeLeaf = true;\r
                 }\r
                 else\r
-                {   \r
+                {\r
                     Ncv32u leftNodeOffset = tree->left[n];\r
                     nodeLeft.create((Ncv32u)(h_TmpClassifierNotRootNodes.size() + leftNodeOffset - 1));\r
                     haar.bHasStumpsOnly = false;\r
@@ -419,8 +430,8 @@ NCVStatus loadFromXML(const std::string &filename,
 \r
                 Ncv32u featureId = 0;\r
                 for(int l = 0; l < CV_HAAR_FEATURE_MAX; ++l) //by rects\r
-                {                        \r
-                    Ncv32u rectX = feature->rect[l].r.x; \r
+                {\r
+                    Ncv32u rectX = feature->rect[l].r.x;\r
                     Ncv32u rectY = feature->rect[l].r.y;\r
                     Ncv32u rectWidth = feature->rect[l].r.width;\r
                     Ncv32u rectHeight = feature->rect[l].r.height;\r
@@ -441,7 +452,7 @@ NCVStatus loadFromXML(const std::string &filename,
 \r
                 HaarFeatureDescriptor32 tmpFeatureDesc;\r
                 ncvStat = tmpFeatureDesc.create(haar.bNeedsTiltedII, bIsLeftNodeLeaf, bIsRightNodeLeaf,\r
-                                                featureId, haarFeatures.size() - featureId);\r
+                    featureId, haarFeatures.size() - featureId);\r
                 ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat);\r
                 curNode.setFeatureDesc(tmpFeatureDesc);\r
 \r
@@ -466,8 +477,6 @@ NCVStatus loadFromXML(const std::string &filename,
         haarStages.push_back(curStage);\r
     }\r
 \r
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\r
-\r
     //fill in cascade stats\r
     haar.NumStages = haarStages.size();\r
     haar.NumClassifierRootNodes = haarClassifierNodes.size();\r
@@ -496,6 +505,7 @@ NCVStatus loadFromXML(const std::string &filename,
         }\r
         haarClassifierNodes[i].setRightNodeDesc(nodeRight);\r
     }\r
+\r
     for (Ncv32u i=0; i<h_TmpClassifierNotRootNodes.size(); i++)\r
     {\r
         HaarFeatureDescriptor32 featureDesc = h_TmpClassifierNotRootNodes[i].getFeatureDesc();\r
@@ -522,8 +532,6 @@ NCVStatus loadFromXML(const std::string &filename,
     return NCV_SUCCESS;\r
 }\r
 \r
-////\r
-\r
 #else /* loadFromXML implementation switch */\r
 \r
 #include "e:/devNPP-OpenCV/src/external/_rapidxml-1.13/rapidxml.hpp"\r
@@ -793,5 +801,3 @@ NCVStatus loadFromXML(const std::string &filename,
 #endif /* loadFromXML implementation switch */\r
 \r
 #endif /* HAVE_CUDA */\r
-\r
-\r
index 08ea80a..c9c806c 100644 (file)
@@ -1,19 +1,29 @@
 // WARNING: this sample is under construction! Use it on your own risk.\r
+#pragma warning(disable : 4100)\r
 \r
+#include "cvconfig.h"\r
+#include <iostream>\r
+#include <iomanip>\r
 #include <opencv2/contrib/contrib.hpp>\r
 #include <opencv2/objdetect/objdetect.hpp>\r
 #include <opencv2/highgui/highgui.hpp>\r
 #include <opencv2/imgproc/imgproc.hpp>\r
 #include <opencv2/gpu/gpu.hpp>\r
 \r
-#include <iostream>\r
-#include <iomanip>\r
-\r
 using namespace std;\r
 using namespace cv;\r
 using namespace cv::gpu;\r
 \r
 \r
+#if !defined(HAVE_CUDA)\r
+int main(int argc, const char **argv)\r
+{\r
+    cout << "Please compile the library with CUDA support" << endl;\r
+    return -1;\r
+}\r
+#else\r
+\r
+\r
 void help()\r
 {\r
     cout << "Usage: ./cascadeclassifier <cascade_file> <image_or_video_or_cameraid>\n"\r
@@ -21,14 +31,8 @@ void help()
 }\r
 \r
 \r
-void DetectAndDraw(Mat& img, CascadeClassifier_GPU& cascade);\r
-\r
-\r
-String cascadeName = "../../data/haarcascades/haarcascade_frontalface_alt.xml";\r
-String nestedCascadeName = "../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";\r
-\r
-\r
-template<class T> void convertAndResize(const T& src, T& gray, T& resized, double scale)\r
+template<class T>\r
+void convertAndResize(const T& src, T& gray, T& resized, double scale)\r
 {\r
     if (src.channels() == 3)\r
     {\r
@@ -54,15 +58,16 @@ template<class T> void convertAndResize(const T& src, T& gray, T& resized, doubl
 \r
 void matPrint(Mat &img, int lineOffsY, Scalar fontColor, const ostringstream &ss)\r
 {\r
-    int fontFace = FONT_HERSHEY_PLAIN;\r
-    double fontScale = 1.5;\r
+    int fontFace = FONT_HERSHEY_DUPLEX;\r
+    double fontScale = 0.8;\r
     int fontThickness = 2;\r
     Size fontSize = cv::getTextSize("T[]", fontFace, fontScale, fontThickness, 0);\r
 \r
     Point org;\r
     org.x = 1;\r
     org.y = 3 * fontSize.height * (lineOffsY + 1) / 2;\r
-    putText(img, ss.str(), org, fontFace, fontScale, fontColor, fontThickness);\r
+    putText(img, ss.str(), org, fontFace, fontScale, CV_RGB(0,0,0), 5*fontThickness/2, 16);\r
+    putText(img, ss.str(), org, fontFace, fontScale, fontColor, fontThickness, 16);\r
 }\r
 \r
 \r
@@ -72,25 +77,26 @@ void displayState(Mat &canvas, bool bHelp, bool bGpu, bool bLargestFace, bool bF
     Scalar fontColorNV  = CV_RGB(118,185,0);\r
 \r
     ostringstream ss;\r
+    ss << "FPS = " << setprecision(1) << fixed << fps;\r
+    matPrint(canvas, 0, fontColorRed, ss);\r
+    ss.str("");\r
     ss << "[" << canvas.cols << "x" << canvas.rows << "], " <<\r
         (bGpu ? "GPU, " : "CPU, ") <<\r
         (bLargestFace ? "OneFace, " : "MultiFace, ") <<\r
-        (bFilter ? "Filter:ON, " : "Filter:OFF, ") <<\r
-        "FPS = " << setprecision(1) << fixed << fps;\r
-\r
-    matPrint(canvas, 0, fontColorRed, ss);\r
+        (bFilter ? "Filter:ON" : "Filter:OFF");\r
+    matPrint(canvas, 1, fontColorRed, ss);\r
 \r
     if (bHelp)\r
     {\r
-        matPrint(canvas, 1, fontColorNV, ostringstream("Space - switch GPU / CPU"));\r
-        matPrint(canvas, 2, fontColorNV, ostringstream("M - switch OneFace / MultiFace"));\r
-        matPrint(canvas, 3, fontColorNV, ostringstream("F - toggle rectangles Filter (only in MultiFace)"));\r
-        matPrint(canvas, 4, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
-        matPrint(canvas, 5, fontColorNV, ostringstream("1/Q - increase/decrease scale"));\r
+        matPrint(canvas, 2, fontColorNV, ostringstream("Space - switch GPU / CPU"));\r
+        matPrint(canvas, 3, fontColorNV, ostringstream("M - switch OneFace / MultiFace"));\r
+        matPrint(canvas, 4, fontColorNV, ostringstream("F - toggle rectangles Filter"));\r
+        matPrint(canvas, 5, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
+        matPrint(canvas, 6, fontColorNV, ostringstream("1/Q - increase/decrease scale"));\r
     }\r
     else\r
     {\r
-        matPrint(canvas, 1, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
+        matPrint(canvas, 2, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
     }\r
 }\r
 \r
@@ -130,8 +136,10 @@ int main(int argc, const char *argv[])
     {\r
         if (!capture.open(inputName))\r
         {\r
-            int camid = 0;\r
-            sscanf(inputName.c_str(), "%d", &camid);\r
+            int camid = -1;\r
+            istringstream iss(inputName);\r
+            iss >> camid;\r
+\r
             if (!capture.open(camid))\r
             {\r
                 cout << "Can't open source" << endl;\r
@@ -180,24 +188,26 @@ int main(int argc, const char *argv[])
             cascade_gpu.visualizeInPlace = true;\r
             cascade_gpu.findLargestObject = findLargestObject;\r
 \r
-            detections_num = cascade_gpu.detectMultiScale(resized_gpu, facesBuf_gpu, 1.2, filterRects ? 4 : 0);\r
+            detections_num = cascade_gpu.detectMultiScale(resized_gpu, facesBuf_gpu, 1.2,\r
+                                                          (filterRects || findLargestObject) ? 4 : 0);\r
             facesBuf_gpu.colRange(0, detections_num).download(faces_downloaded);\r
         }\r
         else\r
         {\r
             Size minSize = cascade_gpu.getClassifierSize();\r
-            cascade_cpu.detectMultiScale(resized_cpu, facesBuf_cpu, 1.2, filterRects ? 4 : 0, (findLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0) | CV_HAAR_SCALE_IMAGE, minSize);\r
+            cascade_cpu.detectMultiScale(resized_cpu, facesBuf_cpu, 1.2,\r
+                                         (filterRects || findLargestObject) ? 4 : 0,\r
+                                         (findLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0)\r
+                                            | CV_HAAR_SCALE_IMAGE,\r
+                                         minSize);\r
             detections_num = (int)facesBuf_cpu.size();\r
         }\r
 \r
-        if (!useGPU)\r
+        if (!useGPU && detections_num)\r
         {\r
-            if (detections_num)\r
+            for (int i = 0; i < detections_num; ++i)\r
             {\r
-                for (int i = 0; i < detections_num; ++i)\r
-                {\r
-                    rectangle(resized_cpu, facesBuf_cpu[i], Scalar(255));\r
-                }\r
+                rectangle(resized_cpu, facesBuf_cpu[i], Scalar(255));\r
             }\r
         }\r
 \r
@@ -265,3 +275,5 @@ int main(int argc, const char *argv[])
 \r
     return 0;\r
 }\r
+\r
+#endif //!defined(HAVE_CUDA)\r
index ebdac1c..2dd3945 100644 (file)
@@ -1,50 +1,76 @@
 #pragma warning( disable : 4201 4408 4127 4100)\r
-#include <cstdio>\r
 \r
 #include "cvconfig.h"\r
-#if !defined(HAVE_CUDA)\r
-    int main( int argc, const char** argv ) { return printf("Please compile the library with CUDA support."), -1; }\r
-#else\r
-\r
-#include <cuda_runtime.h>\r
-#include "opencv2/opencv.hpp"\r
+#include <iostream>\r
+#include <iomanip>\r
+#include <opencv2/opencv.hpp>\r
+#include <opencv2/gpu/gpu.hpp>\r
 #include "NCVHaarObjectDetection.hpp"\r
 \r
+using namespace std;\r
 using namespace cv;\r
 \r
-const Size2i preferredVideoFrameSize(640, 480);\r
 \r
-std::string preferredClassifier = "haarcascade_frontalface_alt.xml";\r
-std::string wndTitle = "NVIDIA Computer Vision SDK :: Face Detection in Video Feed";\r
-\r
-\r
-void printSyntax(void)\r
+#if !defined(HAVE_CUDA)\r
+int main( int argc, const char** argv )\r
 {\r
-    printf("Syntax: FaceDetectionFeed.exe [-c cameranum | -v filename] classifier.xml\n");\r
+    cout << "Please compile the library with CUDA support" << endl;\r
+    return -1;\r
 }\r
+#else\r
 \r
-void imagePrintf(Mat& img, int lineOffsY, Scalar color, const char *format, ...)\r
-{    \r
-    int fontFace = CV_FONT_HERSHEY_PLAIN;\r
-    double fontScale = 1;       \r
-    \r
-    int baseline;\r
-    Size textSize = cv::getTextSize("T", fontFace, fontScale, 1, &baseline);\r
 \r
-    va_list arg_ptr;\r
-    va_start(arg_ptr, format);\r
+const Size2i preferredVideoFrameSize(640, 480);\r
+const string wndTitle = "NVIDIA Computer Vision :: Haar Classifiers Cascade";\r
 \r
-    char strBuf[4096];\r
-    vsprintf(&strBuf[0], format, arg_ptr);\r
 \r
-    Point org(1, 3 * textSize.height * (lineOffsY + 1) / 2);    \r
-    putText(img, &strBuf[0], org, fontFace, fontScale, color);\r
-    va_end(arg_ptr);    \r
+void matPrint(Mat &img, int lineOffsY, Scalar fontColor, const ostringstream &ss)\r
+{\r
+    int fontFace = FONT_HERSHEY_DUPLEX;\r
+    double fontScale = 0.8;\r
+    int fontThickness = 2;\r
+    Size fontSize = cv::getTextSize("T[]", fontFace, fontScale, fontThickness, 0);\r
+\r
+    Point org;\r
+    org.x = 1;\r
+    org.y = 3 * fontSize.height * (lineOffsY + 1) / 2;\r
+    putText(img, ss.str(), org, fontFace, fontScale, CV_RGB(0,0,0), 5*fontThickness/2, 16);\r
+    putText(img, ss.str(), org, fontFace, fontScale, fontColor, fontThickness, 16);\r
 }\r
 \r
+\r
+void displayState(Mat &canvas, bool bHelp, bool bGpu, bool bLargestFace, bool bFilter, double fps)\r
+{\r
+    Scalar fontColorRed = CV_RGB(255,0,0);\r
+    Scalar fontColorNV  = CV_RGB(118,185,0);\r
+\r
+    ostringstream ss;\r
+    ss << "FPS = " << setprecision(1) << fixed << fps;\r
+    matPrint(canvas, 0, fontColorRed, ss);\r
+    ss.str("");\r
+    ss << "[" << canvas.cols << "x" << canvas.rows << "], " <<\r
+        (bGpu ? "GPU, " : "CPU, ") <<\r
+        (bLargestFace ? "OneFace, " : "MultiFace, ") <<\r
+        (bFilter ? "Filter:ON" : "Filter:OFF");\r
+    matPrint(canvas, 1, fontColorRed, ss);\r
+\r
+    if (bHelp)\r
+    {\r
+        matPrint(canvas, 2, fontColorNV, ostringstream("Space - switch GPU / CPU"));\r
+        matPrint(canvas, 3, fontColorNV, ostringstream("M - switch OneFace / MultiFace"));\r
+        matPrint(canvas, 4, fontColorNV, ostringstream("F - toggle rectangles Filter"));\r
+        matPrint(canvas, 5, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
+    }\r
+    else\r
+    {\r
+        matPrint(canvas, 2, fontColorNV, ostringstream("H - toggle hotkeys help"));\r
+    }\r
+}\r
+\r
+\r
 NCVStatus process(Mat *srcdst,\r
                   Ncv32u width, Ncv32u height,\r
-                  NcvBool bShowAllHypotheses, NcvBool bLargestFace,\r
+                  NcvBool bFilterRects, NcvBool bLargestFace,\r
                   HaarClassifierCascadeDescriptor &haar,\r
                   NCVVector<HaarStage64> &d_haarStages, NCVVector<HaarClassifierNode128> &d_haarNodes,\r
                   NCVVector<HaarFeature64> &d_haarFeatures, NCVVector<HaarStage64> &h_haarStages,\r
@@ -87,7 +113,7 @@ NCVStatus process(Mat *srcdst,
         d_src, roi, d_rects, numDetections, haar, h_haarStages,\r
         d_haarStages, d_haarNodes, d_haarFeatures,\r
         haar.ClassifierSize,\r
-        bShowAllHypotheses ? 0 : 4,\r
+        (bFilterRects || bLargestFace) ? 4 : 0,\r
         1.2f, 1,\r
         (bLargestFace ? NCVPipeObjDet_FindLargestObject : 0)\r
         | NCVPipeObjDet_VisualizeInPlace,\r
@@ -111,80 +137,67 @@ NCVStatus process(Mat *srcdst,
     return NCV_SUCCESS;\r
 }\r
 \r
-int main( int argc, const char** argv )\r
+\r
+int main(int argc, const char** argv)\r
 {\r
-    NCVStatus ncvStat;\r
+    cout << "OpenCV / NVIDIA Computer Vision" << endl;\r
+    cout << "Face Detection in video and live feed" << endl;\r
+    cout << "Syntax: exename <cascade_file> <image_or_video_or_cameraid>" << endl;\r
+    cout << "=========================================" << endl;\r
 \r
-    printf("NVIDIA Computer Vision SDK\n");\r
-    printf("Face Detection in video and live feed\n");\r
-    printf("=========================================\n");\r
-    printf("  Esc   - Quit\n");\r
-    printf("  Space - Switch between NCV and OpenCV\n");\r
-    printf("  L     - Switch between FullSearch and LargestFace modes\n");\r
-    printf("  U     - Toggle unfiltered hypotheses visualization in FullSearch\n");\r
-       \r
-    VideoCapture capture;    \r
-    bool bQuit = false;\r
+    ncvAssertPrintReturn(cv::gpu::getCudaEnabledDeviceCount() != 0, "No GPU found or the library is compiled without GPU support", -1);\r
+    ncvAssertPrintReturn(argc == 3, "Invalid number of arguments", -1);\r
 \r
-    Size2i frameSize;\r
+    string cascadeName = argv[1];\r
+    string inputName = argv[2];\r
 \r
-    if (argc != 4 && argc != 1)\r
-    {\r
-        printSyntax();\r
-        return -1;\r
-    }\r
+    NCVStatus ncvStat;\r
+    NcvBool bQuit = false;\r
+    VideoCapture capture;\r
+    Size2i frameSize;\r
 \r
-   if (argc == 1 || strcmp(argv[1], "-c") == 0)\r
+    //open content source\r
+    Mat image = imread(inputName);\r
+    Mat frame;\r
+    if (!image.empty())\r
     {\r
-        // Camera input is specified\r
-        int camIdx = (argc == 3) ? atoi(argv[2]) : 0;\r
-        if(!capture.open(camIdx))        \r
-            return printf("Error opening camera\n"), -1;        \r
-            \r
-        capture.set(CV_CAP_PROP_FRAME_WIDTH, preferredVideoFrameSize.width);\r
-        capture.set(CV_CAP_PROP_FRAME_HEIGHT, preferredVideoFrameSize.height);\r
-        capture.set(CV_CAP_PROP_FPS, 25);\r
-        frameSize = preferredVideoFrameSize;\r
+        frameSize.width = image.cols;\r
+        frameSize.height = image.rows;\r
     }\r
-    else if (strcmp(argv[1], "-v") == 0)\r
+    else\r
     {\r
-        // Video file input (avi)\r
-        if(!capture.open(argv[2]))\r
-            return printf("Error opening video file\n"), -1;\r
+        if (!capture.open(inputName))\r
+        {\r
+            int camid = -1;\r
 \r
-        frameSize.width  = (int)capture.get(CV_CAP_PROP_FRAME_WIDTH);\r
-        frameSize.height = (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT);\r
-    }\r
-    else\r
-        return printSyntax(), -1;\r
+            istringstream ss(inputName);\r
+            int x = 0;\r
+            ss >> x;\r
 \r
-    NcvBool bUseOpenCV = true;\r
-    NcvBool bLargestFace = false; //LargestFace=true is used usually during training\r
-    NcvBool bShowAllHypotheses = false;\r
+            ncvAssertPrintReturn(capture.open(camid) != 0, "Can't open source", -1);\r
+        }\r
 \r
-    CascadeClassifier classifierOpenCV;\r
-    std::string classifierFile;\r
-    if (argc == 1)\r
-    {\r
-        classifierFile = preferredClassifier;\r
-    }\r
-    else\r
-    {\r
-        classifierFile.assign(argv[3]);\r
-    }\r
+        capture >> frame;\r
+        ncvAssertPrintReturn(!frame.empty(), "Empty video source", -1);\r
 \r
-    if (!classifierOpenCV.load(classifierFile))\r
-    {\r
-        printf("Error (in OpenCV) opening classifier\n");\r
-        printSyntax();\r
-        return -1;\r
+        frameSize.width = frame.cols;\r
+        frameSize.height = frame.rows;\r
     }\r
 \r
+    NcvBool bUseGPU = true;\r
+    NcvBool bLargestObject = false;\r
+    NcvBool bFilterRects = true;\r
+    NcvBool bHelpScreen = false;\r
+\r
+    CascadeClassifier classifierOpenCV;\r
+    ncvAssertPrintReturn(classifierOpenCV.load(cascadeName) != 0, "Error (in OpenCV) opening classifier", -1);\r
+\r
     int devId;\r
     ncvAssertCUDAReturn(cudaGetDevice(&devId), -1);\r
     cudaDeviceProp devProp;\r
     ncvAssertCUDAReturn(cudaGetDeviceProperties(&devProp, devId), -1);\r
-    printf("Using GPU %d %s, arch=%d.%d\n", devId, devProp.name, devProp.major, devProp.minor);\r
+    cout << "Using GPU: " << devId << "(" << devProp.name <<\r
+            "), arch=" << devProp.major << "." << devProp.minor << endl;\r
 \r
     //==============================================================================\r
     //\r
@@ -199,7 +212,7 @@ int main( int argc, const char** argv )
     ncvAssertPrintReturn(cpuCascadeAllocator.isInitialized(), "Error creating cascade CPU allocator", -1);\r
 \r
     Ncv32u haarNumStages, haarNumNodes, haarNumFeatures;\r
-    ncvStat = ncvHaarGetClassifierSize(classifierFile, haarNumStages, haarNumNodes, haarNumFeatures);\r
+    ncvStat = ncvHaarGetClassifierSize(cascadeName, haarNumStages, haarNumNodes, haarNumFeatures);\r
     ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error reading classifier size (check the file)", -1);\r
 \r
     NCVVectorAlloc<HaarStage64> h_haarStages(cpuCascadeAllocator, haarNumStages);\r
@@ -210,7 +223,7 @@ int main( int argc, const char** argv )
     ncvAssertPrintReturn(h_haarFeatures.isMemAllocated(), "Error in cascade CPU allocator", -1);\r
 \r
     HaarClassifierCascadeDescriptor haar;\r
-    ncvStat = ncvHaarLoadFromFile_host(classifierFile, haar, h_haarStages, h_haarNodes, h_haarFeatures);\r
+    ncvStat = ncvHaarLoadFromFile_host(cascadeName, haar, h_haarStages, h_haarNodes, h_haarFeatures);\r
     ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error loading classifier", -1);\r
 \r
     NCVVectorAlloc<HaarStage64> d_haarStages(gpuCascadeAllocator, haarNumStages);\r
@@ -258,30 +271,25 @@ int main( int argc, const char** argv )
     //\r
     //==============================================================================\r
 \r
-       namedWindow(wndTitle, 1);\r
-    Mat frame, gray, frameDisp;\r
+    namedWindow(wndTitle, 1);\r
+    Mat gray, frameDisp;\r
 \r
     do\r
     {\r
-               // For camera and video file, capture the next image                \r
-        capture >> frame;\r
-        if (frame.empty())\r
-            break;\r
-\r
         Mat gray;\r
-        cvtColor(frame, gray, CV_BGR2GRAY);\r
+        cvtColor((image.empty() ? frame : image), gray, CV_BGR2GRAY);\r
 \r
         //\r
         // process\r
         //\r
 \r
         NcvSize32u minSize = haar.ClassifierSize;\r
-        if (bLargestFace)\r
+        if (bLargestObject)\r
         {\r
             Ncv32u ratioX = preferredVideoFrameSize.width / minSize.width;\r
             Ncv32u ratioY = preferredVideoFrameSize.height / minSize.height;\r
-            Ncv32u ratioSmallest = std::min(ratioX, ratioY);\r
-            ratioSmallest = std::max((Ncv32u)(ratioSmallest / 2.5f), (Ncv32u)1);\r
+            Ncv32u ratioSmallest = min(ratioX, ratioY);\r
+            ratioSmallest = max((Ncv32u)(ratioSmallest / 2.5f), (Ncv32u)1);\r
             minSize.width *= ratioSmallest;\r
             minSize.height *= ratioSmallest;\r
         }\r
@@ -289,10 +297,10 @@ int main( int argc, const char** argv )
         Ncv32f avgTime;\r
         NcvTimer timer = ncvStartTimer();\r
 \r
-        if (!bUseOpenCV)\r
+        if (bUseGPU)\r
         {\r
             ncvStat = process(&gray, frameSize.width, frameSize.height,\r
-                              bShowAllHypotheses, bLargestFace, haar,\r
+                              bFilterRects, bLargestObject, haar,\r
                               d_haarStages, d_haarNodes,\r
                               d_haarFeatures, h_haarStages,\r
                               gpuAllocator, cpuAllocator, devProp);\r
@@ -306,8 +314,8 @@ int main( int argc, const char** argv )
                 gray,\r
                 rectsOpenCV,\r
                 1.2f,\r
-                bShowAllHypotheses && !bLargestFace ? 0 : 4,\r
-                (bLargestFace ? CV_HAAR_FIND_BIGGEST_OBJECT : 0)\r
+                bFilterRects ? 4 : 0,\r
+                (bLargestObject ? CV_HAAR_FIND_BIGGEST_OBJECT : 0)\r
                 | CV_HAAR_SCALE_IMAGE,\r
                 Size(minSize.width, minSize.height));\r
 \r
@@ -318,32 +326,41 @@ int main( int argc, const char** argv )
         avgTime = (Ncv32f)ncvEndQueryTimerMs(timer);\r
 \r
         cvtColor(gray, frameDisp, CV_GRAY2BGR);\r
+        displayState(frameDisp, bHelpScreen, bUseGPU, bLargestObject, bFilterRects, 1000.0f / avgTime);\r
+        imshow(wndTitle, frameDisp);\r
 \r
-        imagePrintf(frameDisp, 0, CV_RGB(255,  0,0), "Space - Switch NCV%s / OpenCV%s", bUseOpenCV?"":" (ON)", bUseOpenCV?" (ON)":"");\r
-        imagePrintf(frameDisp, 1, CV_RGB(255,  0,0), "L - Switch FullSearch%s / LargestFace%s modes", bLargestFace?"":" (ON)", bLargestFace?" (ON)":"");\r
-        imagePrintf(frameDisp, 2, CV_RGB(255,  0,0), "U - Toggle unfiltered hypotheses visualization in FullSearch %s", bShowAllHypotheses?"(ON)":"(OFF)");\r
-        imagePrintf(frameDisp, 3, CV_RGB(118,185,0), "   Running at %f FPS on %s", 1000.0f / avgTime, bUseOpenCV?"CPU":"GPU");\r
-\r
-        cv::imshow(wndTitle, frameDisp);\r
-\r
+        //handle input\r
         switch (cvWaitKey(3))\r
         {\r
         case ' ':\r
-            bUseOpenCV = !bUseOpenCV;\r
+            bUseGPU = !bUseGPU;\r
+            break;\r
+        case 'm':\r
+        case 'M':\r
+            bLargestObject = !bLargestObject;\r
             break;\r
-        case 'L':\r
-        case 'l':\r
-            bLargestFace = !bLargestFace;\r
+        case 'f':\r
+        case 'F':\r
+            bFilterRects = !bFilterRects;\r
             break;\r
-        case 'U':\r
-        case 'u':\r
-            bShowAllHypotheses = !bShowAllHypotheses;\r
+        case 'h':\r
+        case 'H':\r
+            bHelpScreen = !bHelpScreen;\r
             break;\r
         case 27:\r
             bQuit = true;\r
             break;\r
         }\r
 \r
+        // For camera and video file, capture the next image\r
+        if (capture.isOpened())\r
+        {\r
+            capture >> frame;\r
+            if (frame.empty())\r
+            {\r
+                break;\r
+            }\r
+        }\r
     } while (!bQuit);\r
 \r
     cvDestroyWindow(wndTitle.c_str());\r
@@ -351,5 +368,4 @@ int main( int argc, const char** argv )
     return 0;\r
 }\r
 \r
-\r
-#endif\r
+#endif //!defined(HAVE_CUDA)\r