added test for GPU LBP cascade: load cascade
authorMarina Kolpakova <no@email>
Mon, 25 Jun 2012 08:46:34 +0000 (08:46 +0000)
committerMarina Kolpakova <no@email>
Mon, 25 Jun 2012 08:46:34 +0000 (08:46 +0000)
modules/gpu/include/opencv2/gpu/gpu.hpp
modules/gpu/src/cascadeclassifier.cpp
modules/gpu/test/test_objdetect.cpp

index d9a5d73..383c80d 100644 (file)
@@ -1451,7 +1451,7 @@ private:
     bool isStumps;\r
     int ncategories;\r
     struct Stage;\r
-    Stage* stages;\r
+    // Stage* stages;\r
 \r
     struct DTree;\r
     // DTree* classifiers;\r
index afd9796..1cd0273 100644 (file)
@@ -42,6 +42,7 @@
 \r
 #include "precomp.hpp"\r
 #include <vector>\r
+#include <iostream>\r
 \r
 using namespace cv;\r
 using namespace cv::gpu;\r
@@ -133,7 +134,7 @@ bool cv::gpu::CascadeClassifier_GPU_LBP::load(const string& classifierAsXml)
 \r
 bool CascadeClassifier_GPU_LBP::read(const FileNode &root)\r
 {\r
-    string stageTypeStr = (string)root[GPU_CC_STAGE_TYPE];\r
+    std::string stageTypeStr = (string)root[GPU_CC_STAGE_TYPE];\r
     CV_Assert(stageTypeStr == GPU_CC_BOOST);\r
 \r
     string featureTypeStr = (string)root[GPU_CC_FEATURE_TYPE];\r
@@ -151,17 +152,15 @@ bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
         return false;\r
 \r
     ncategories = fn[GPU_CC_MAX_CAT_COUNT];\r
-    int subsetSize = (ncategories + 31)/32, nodeStep = 3 + ( ncategories > 0 ? subsetSize : 1 );// ?\r
+\r
+    int subsetSize = (ncategories + 31) / 32, nodeStep = 3 + ( ncategories > 0 ? subsetSize : 1 );\r
 \r
     fn = root[GPU_CC_STAGES];\r
     if (fn.empty())\r
         return false;\r
 \r
-    delete[] stages;\r
-    // delete[] classifiers;\r
-    // delete[] nodes;\r
-\r
-    stages = new Stage[fn.size()];\r
+    std::vector<Stage> stages;\r
+    stages.reserve(fn.size());\r
 \r
     std::vector<DTree> cl_trees;\r
     std::vector<DTreeNode> cl_nodes;\r
@@ -169,18 +168,21 @@ bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
     std::vector<int> subsets;\r
 \r
     FileNodeIterator it = fn.begin(), it_end = fn.end();\r
-    size_t s_it = 0;\r
-\r
+    int i = 0;\r
     for (size_t si = 0; it != it_end; si++, ++it )\r
     {\r
         FileNode fns = *it;\r
+        Stage st;\r
+        st.threshold = (float)fns[GPU_CC_STAGE_THRESHOLD] - GPU_THRESHOLD_EPS;\r
 \r
         fns = fns[GPU_CC_WEAK_CLASSIFIERS];\r
         if (fns.empty())\r
             return false;\r
 \r
-        stages[s_it++] = Stage((float)fns[GPU_CC_STAGE_THRESHOLD] - GPU_THRESHOLD_EPS,\r
-                               (int)cl_trees.size(), (int)fns.size());\r
+        st.ntrees = (int)fns.size();\r
+        st.first = (int)cl_trees.size();\r
+\r
+        stages.push_back(st);\r
 \r
         cl_trees.reserve(stages[si].first + stages[si].ntrees);\r
 \r
@@ -194,6 +196,7 @@ bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
             FileNode leafValues = fnw[GPU_CC_LEAF_VALUES];\r
             if ( internalNodes.empty() || leafValues.empty() )\r
                 return false;\r
+\r
             DTree tree((int)internalNodes.size()/nodeStep );\r
             cl_trees.push_back(tree);\r
 \r
@@ -211,20 +214,19 @@ bool CascadeClassifier_GPU_LBP::read(const FileNode &root)
                 DTreeNode node((int)*(iIt++), (int)*(iIt++), (int)*(iIt++));\r
                 cl_nodes.push_back(node);\r
 \r
-                if ( subsetSize > 0 )\r
-                {\r
+                if( subsetSize > 0 )\r
                     for( int j = 0; j < subsetSize; j++, ++iIt )\r
-                        subsets.push_back((int)*iIt); //????\r
-                }\r
+                        subsets.push_back((int)*iIt);\r
             }\r
 \r
-            iIt = leafValues.begin(), iEnd = leafValues.end();\r
             // leaves\r
+            iIt = leafValues.begin(), iEnd = leafValues.end();\r
             for( ; iIt != iEnd; ++iIt )\r
                 cl_leaves.push_back((float)*iIt);\r
         }\r
     }\r
-\r
+    // copy data structures on gpu\r
+    // GpuMat stages;\r
     return true;\r
 }\r
 \r
@@ -513,9 +515,6 @@ void groupRectangles(std::vector<NcvRect32u> &hypotheses, int groupThreshold, do
     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
@@ -714,272 +713,4 @@ NCVStatus loadFromXML(const std::string &filename,
     return NCV_SUCCESS;\r
 }\r
 \r
-#else /* loadFromXML implementation switch */\r
-\r
-#include "e:/devNPP-OpenCV/src/external/_rapidxml-1.13/rapidxml.hpp"\r
-\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
-\r
-    haar.NumStages = 0;\r
-    haar.NumClassifierRootNodes = 0;\r
-    haar.NumClassifierTotalNodes = 0;\r
-    haar.NumFeatures = 0;\r
-    haar.ClassifierSize.width = 0;\r
-    haar.ClassifierSize.height = 0;\r
-    haar.bNeedsTiltedII = false;\r
-    haar.bHasStumpsOnly = false;\r
-\r
-    FILE *fp;\r
-    fopen_s(&fp, filename.c_str(), "r");\r
-    ncvAssertReturn(fp != NULL, NCV_FILE_ERROR);\r
-\r
-    //get file size\r
-    fseek(fp, 0, SEEK_END);\r
-    Ncv32u xmlSize = ftell(fp);\r
-    fseek(fp, 0, SEEK_SET);\r
-\r
-    //load file to vector\r
-    std::vector<char> xmlFileCont;\r
-    xmlFileCont.resize(xmlSize+1);\r
-    memset(&xmlFileCont[0], 0, xmlSize+1);\r
-    fread_s(&xmlFileCont[0], xmlSize, 1, xmlSize, fp);\r
-    fclose(fp);\r
-\r
-    haar.bHasStumpsOnly = true;\r
-    haar.bNeedsTiltedII = false;\r
-    Ncv32u curMaxTreeDepth;\r
-\r
-    std::vector<HaarClassifierNode128> h_TmpClassifierNotRootNodes;\r
-    haarStages.resize(0);\r
-    haarClassifierNodes.resize(0);\r
-    haarFeatures.resize(0);\r
-\r
-    //XML loading and OpenCV XML classifier syntax verification\r
-    try\r
-    {\r
-        rapidxml::xml_document<> doc;\r
-        doc.parse<0>(&xmlFileCont[0]);\r
-\r
-        //opencv_storage\r
-        rapidxml::xml_node<> *parserGlobal = doc.first_node();\r
-        ncvAssertReturn(!strcmp(parserGlobal->name(), "opencv_storage"), NCV_HAAR_XML_LOADING_EXCEPTION);\r
-\r
-        //classifier type\r
-        parserGlobal = parserGlobal->first_node();\r
-        ncvAssertReturn(parserGlobal, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-        rapidxml::xml_attribute<> *attr = parserGlobal->first_attribute("type_id");\r
-        ncvAssertReturn(!strcmp(attr->value(), "opencv-haar-classifier"), NCV_HAAR_XML_LOADING_EXCEPTION);\r
-\r
-        //classifier size\r
-        parserGlobal = parserGlobal->first_node("size");\r
-        ncvAssertReturn(parserGlobal, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-        sscanf_s(parserGlobal->value(), "%d %d", &(haar.ClassifierSize.width), &(haar.ClassifierSize.height));\r
-\r
-        //parse stages\r
-        parserGlobal = parserGlobal->next_sibling("stages");\r
-        ncvAssertReturn(parserGlobal, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-        parserGlobal = parserGlobal->first_node("_");\r
-        ncvAssertReturn(parserGlobal, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-\r
-        while (parserGlobal)\r
-        {\r
-            HaarStage64 curStage;\r
-            curStage.setStartClassifierRootNodeOffset(haarClassifierNodes.size());\r
-            Ncv32u tmpNumClassifierRootNodes = 0;\r
-\r
-            rapidxml::xml_node<> *parserStageThreshold = parserGlobal->first_node("stage_threshold");\r
-            ncvAssertReturn(parserStageThreshold, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-            Ncv32f tmpStageThreshold;\r
-            sscanf_s(parserStageThreshold->value(), "%f", &tmpStageThreshold);\r
-            curStage.setStageThreshold(tmpStageThreshold);\r
-\r
-            //parse trees\r
-            rapidxml::xml_node<> *parserTree;\r
-            parserTree = parserGlobal->first_node("trees");\r
-            ncvAssertReturn(parserTree, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-            parserTree = parserTree->first_node("_");\r
-            ncvAssertReturn(parserTree, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-\r
-            while (parserTree)\r
-            {\r
-                rapidxml::xml_node<> *parserNode;\r
-                parserNode = parserTree->first_node("_");\r
-                ncvAssertReturn(parserNode, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                Ncv32u nodeId = 0;\r
-\r
-                while (parserNode)\r
-                {\r
-                    HaarClassifierNode128 curNode;\r
-\r
-                    rapidxml::xml_node<> *parserNodeThreshold = parserNode->first_node("threshold");\r
-                    ncvAssertReturn(parserNodeThreshold, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                    Ncv32f tmpThreshold;\r
-                    sscanf_s(parserNodeThreshold->value(), "%f", &tmpThreshold);\r
-                    curNode.setThreshold(tmpThreshold);\r
-\r
-                    rapidxml::xml_node<> *parserNodeLeft = parserNode->first_node("left_val");\r
-                    HaarClassifierNodeDescriptor32 nodeLeft;\r
-                    if (parserNodeLeft)\r
-                    {\r
-                        Ncv32f leftVal;\r
-                        sscanf_s(parserNodeLeft->value(), "%f", &leftVal);\r
-                        ncvStat = nodeLeft.create(leftVal);\r
-                        ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat);\r
-                    }\r
-                    else\r
-                    {\r
-                        parserNodeLeft = parserNode->first_node("left_node");\r
-                        ncvAssertReturn(parserNodeLeft, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                        Ncv32u leftNodeOffset;\r
-                        sscanf_s(parserNodeLeft->value(), "%d", &leftNodeOffset);\r
-                        nodeLeft.create(h_TmpClassifierNotRootNodes.size() + leftNodeOffset - 1);\r
-                        haar.bHasStumpsOnly = false;\r
-                    }\r
-                    curNode.setLeftNodeDesc(nodeLeft);\r
-\r
-                    rapidxml::xml_node<> *parserNodeRight = parserNode->first_node("right_val");\r
-                    HaarClassifierNodeDescriptor32 nodeRight;\r
-                    if (parserNodeRight)\r
-                    {\r
-                        Ncv32f rightVal;\r
-                        sscanf_s(parserNodeRight->value(), "%f", &rightVal);\r
-                        ncvStat = nodeRight.create(rightVal);\r
-                        ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat);\r
-                    }\r
-                    else\r
-                    {\r
-                        parserNodeRight = parserNode->first_node("right_node");\r
-                        ncvAssertReturn(parserNodeRight, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                        Ncv32u rightNodeOffset;\r
-                        sscanf_s(parserNodeRight->value(), "%d", &rightNodeOffset);\r
-                        nodeRight.create(h_TmpClassifierNotRootNodes.size() + rightNodeOffset - 1);\r
-                        haar.bHasStumpsOnly = false;\r
-                    }\r
-                    curNode.setRightNodeDesc(nodeRight);\r
-\r
-                    rapidxml::xml_node<> *parserNodeFeatures = parserNode->first_node("feature");\r
-                    ncvAssertReturn(parserNodeFeatures, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-\r
-                    rapidxml::xml_node<> *parserNodeFeaturesTilted = parserNodeFeatures->first_node("tilted");\r
-                    ncvAssertReturn(parserNodeFeaturesTilted, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                    Ncv32u tiltedVal;\r
-                    sscanf_s(parserNodeFeaturesTilted->value(), "%d", &tiltedVal);\r
-                    haar.bNeedsTiltedII = (tiltedVal != 0);\r
-\r
-                    rapidxml::xml_node<> *parserNodeFeaturesRects = parserNodeFeatures->first_node("rects");\r
-                    ncvAssertReturn(parserNodeFeaturesRects, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                    parserNodeFeaturesRects = parserNodeFeaturesRects->first_node("_");\r
-                    ncvAssertReturn(parserNodeFeaturesRects, NCV_HAAR_XML_LOADING_EXCEPTION);\r
-                    Ncv32u featureId = 0;\r
-\r
-                    while (parserNodeFeaturesRects)\r
-                    {\r
-                        Ncv32u rectX, rectY, rectWidth, rectHeight;\r
-                        Ncv32f rectWeight;\r
-                        sscanf_s(parserNodeFeaturesRects->value(), "%d %d %d %d %f", &rectX, &rectY, &rectWidth, &rectHeight, &rectWeight);\r
-                        HaarFeature64 curFeature;\r
-                        ncvStat = curFeature.setRect(rectX, rectY, rectWidth, rectHeight, haar.ClassifierSize.width, haar.ClassifierSize.height);\r
-                        curFeature.setWeight(rectWeight);\r
-                        ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat);\r
-                        haarFeatures.push_back(curFeature);\r
-\r
-                        parserNodeFeaturesRects = parserNodeFeaturesRects->next_sibling("_");\r
-                        featureId++;\r
-                    }\r
-\r
-                    HaarFeatureDescriptor32 tmpFeatureDesc;\r
-                    ncvStat = tmpFeatureDesc.create(haar.bNeedsTiltedII, featureId, haarFeatures.size() - featureId);\r
-                    ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat);\r
-                    curNode.setFeatureDesc(tmpFeatureDesc);\r
-\r
-                    if (!nodeId)\r
-                    {\r
-                        //root node\r
-                        haarClassifierNodes.push_back(curNode);\r
-                        curMaxTreeDepth = 1;\r
-                    }\r
-                    else\r
-                    {\r
-                        //other node\r
-                        h_TmpClassifierNotRootNodes.push_back(curNode);\r
-                        curMaxTreeDepth++;\r
-                    }\r
-\r
-                    parserNode = parserNode->next_sibling("_");\r
-                    nodeId++;\r
-                }\r
-\r
-                parserTree = parserTree->next_sibling("_");\r
-                tmpNumClassifierRootNodes++;\r
-            }\r
-\r
-            curStage.setNumClassifierRootNodes(tmpNumClassifierRootNodes);\r
-            haarStages.push_back(curStage);\r
-\r
-            parserGlobal = parserGlobal->next_sibling("_");\r
-        }\r
-    }\r
-    catch (...)\r
-    {\r
-        return NCV_HAAR_XML_LOADING_EXCEPTION;\r
-    }\r
-\r
-    //fill in cascade stats\r
-    haar.NumStages = haarStages.size();\r
-    haar.NumClassifierRootNodes = haarClassifierNodes.size();\r
-    haar.NumClassifierTotalNodes = haar.NumClassifierRootNodes + h_TmpClassifierNotRootNodes.size();\r
-    haar.NumFeatures = haarFeatures.size();\r
-\r
-    //merge root and leaf nodes in one classifiers array\r
-    Ncv32u offsetRoot = haarClassifierNodes.size();\r
-    for (Ncv32u i=0; i<haarClassifierNodes.size(); i++)\r
-    {\r
-        HaarClassifierNodeDescriptor32 nodeLeft = haarClassifierNodes[i].getLeftNodeDesc();\r
-        if (!nodeLeft.isLeaf())\r
-        {\r
-            Ncv32u newOffset = nodeLeft.getNextNodeOffset() + offsetRoot;\r
-            nodeLeft.create(newOffset);\r
-        }\r
-        haarClassifierNodes[i].setLeftNodeDesc(nodeLeft);\r
-\r
-        HaarClassifierNodeDescriptor32 nodeRight = haarClassifierNodes[i].getRightNodeDesc();\r
-        if (!nodeRight.isLeaf())\r
-        {\r
-            Ncv32u newOffset = nodeRight.getNextNodeOffset() + offsetRoot;\r
-            nodeRight.create(newOffset);\r
-        }\r
-        haarClassifierNodes[i].setRightNodeDesc(nodeRight);\r
-    }\r
-    for (Ncv32u i=0; i<h_TmpClassifierNotRootNodes.size(); i++)\r
-    {\r
-        HaarClassifierNodeDescriptor32 nodeLeft = h_TmpClassifierNotRootNodes[i].getLeftNodeDesc();\r
-        if (!nodeLeft.isLeaf())\r
-        {\r
-            Ncv32u newOffset = nodeLeft.getNextNodeOffset() + offsetRoot;\r
-            nodeLeft.create(newOffset);\r
-        }\r
-        h_TmpClassifierNotRootNodes[i].setLeftNodeDesc(nodeLeft);\r
-\r
-        HaarClassifierNodeDescriptor32 nodeRight = h_TmpClassifierNotRootNodes[i].getRightNodeDesc();\r
-        if (!nodeRight.isLeaf())\r
-        {\r
-            Ncv32u newOffset = nodeRight.getNextNodeOffset() + offsetRoot;\r
-            nodeRight.create(newOffset);\r
-        }\r
-        h_TmpClassifierNotRootNodes[i].setRightNodeDesc(nodeRight);\r
-\r
-        haarClassifierNodes.push_back(h_TmpClassifierNotRootNodes[i]);\r
-    }\r
-\r
-    return NCV_SUCCESS;\r
-}\r
-\r
-#endif /* loadFromXML implementation switch */\r
-\r
 #endif /* HAVE_CUDA */\r
index 4b5a2fa..02c800e 100644 (file)
@@ -40,6 +40,7 @@
 //M*/\r
 \r
 #include "precomp.hpp"\r
+#include <string>\r
 \r
 namespace {\r
 \r
@@ -284,4 +285,28 @@ TEST_P(HOG, GetDescriptors)
 \r
 INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, HOG, ALL_DEVICES);\r
 \r
+PARAM_TEST_CASE(LBP_Read_classifier, cv::gpu::DeviceInfo, int)\r
+{\r
+    cv::gpu::DeviceInfo devInfo;\r
+\r
+    virtual void SetUp()\r
+    {\r
+        devInfo = GET_PARAM(0);\r
+        cv::gpu::setDevice(devInfo.deviceID());\r
+    }\r
+};\r
+\r
+TEST_P(LBP_Read_classifier, Accuracy)\r
+{\r
+    cv::gpu::CascadeClassifier_GPU_LBP classifier;\r
+    std::cout << (std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml") << std::endl;\r
+    std::string classifierXmlPath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml";\r
+    classifier.load(classifierXmlPath);\r
+}\r
+\r
+INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, LBP_Read_classifier, testing::Combine(\r
+    ALL_DEVICES,\r
+    testing::Values<int>(0)\r
+    ));\r
+\r
 } // namespace\r