Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cascadedetect_convert.cpp Source File

cascadedetect_convert.cpp

00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2013, Itseez Inc, all rights reserved.
00014 // Third party copyrights are property of their respective owners.
00015 //
00016 // Redistribution and use in source and binary forms, with or without modification,
00017 // are permitted provided that the following conditions are met:
00018 //
00019 //   * Redistribution's of source code must retain the above copyright notice,
00020 //     this list of conditions and the following disclaimer.
00021 //
00022 //   * Redistribution's in binary form must reproduce the above copyright notice,
00023 //     this list of conditions and the following disclaimer in the documentation
00024 //     and/or other materials provided with the distribution.
00025 //
00026 //   * The name of Intel Corporation may not be used to endorse or promote products
00027 //     derived from this software without specific prior written permission.
00028 //
00029 // This software is provided by the copyright holders and contributors "as is" and
00030 // any express or implied warranties, including, but not limited to, the implied
00031 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00032 // In no event shall the Intel Corporation or contributors be liable for any direct,
00033 // indirect, incidental, special, exemplary, or consequential damages
00034 // (including, but not limited to, procurement of substitute goods or services;
00035 // loss of use, data, or profits; or business interruption) however caused
00036 // and on any theory of liability, whether in contract, strict liability,
00037 // or tort (including negligence or otherwise) arising in any way out of
00038 // the use of this software, even if advised of the possibility of such damage.
00039 //
00040 //M*/
00041 
00042 /* Haar features calculation */
00043 #include "opencv2/core.hpp"
00044 #include "precomp.hpp"
00045 #include <stdio.h>
00046 
00047 namespace cv
00048 {
00049 
00050 /* field names */
00051 
00052 #define ICV_HAAR_SIZE_NAME            "size"
00053 #define ICV_HAAR_STAGES_NAME          "stages"
00054 #define ICV_HAAR_TREES_NAME           "trees"
00055 #define ICV_HAAR_FEATURE_NAME         "feature"
00056 #define ICV_HAAR_RECTS_NAME           "rects"
00057 #define ICV_HAAR_TILTED_NAME          "tilted"
00058 #define ICV_HAAR_THRESHOLD_NAME       "threshold"
00059 #define ICV_HAAR_LEFT_NODE_NAME       "left_node"
00060 #define ICV_HAAR_LEFT_VAL_NAME        "left_val"
00061 #define ICV_HAAR_RIGHT_NODE_NAME      "right_node"
00062 #define ICV_HAAR_RIGHT_VAL_NAME       "right_val"
00063 #define ICV_HAAR_STAGE_THRESHOLD_NAME "stage_threshold"
00064 #define ICV_HAAR_PARENT_NAME          "parent"
00065 #define ICV_HAAR_NEXT_NAME            "next"
00066 
00067 namespace haar_cvt
00068 {
00069 
00070 struct HaarFeature
00071 {
00072     enum { RECT_NUM = 3 };
00073 
00074     HaarFeature()
00075     {
00076         tilted = false;
00077         for( int i = 0; i < RECT_NUM; i++ )
00078         {
00079             rect[i].r = Rect(0,0,0,0);
00080             rect[i].weight = 0.f;
00081         }
00082     }
00083     bool tilted;
00084     struct
00085     {
00086         Rect r;
00087         float weight;
00088     } rect[RECT_NUM];
00089 };
00090 
00091 struct HaarClassifierNode
00092 {
00093     HaarClassifierNode()
00094     {
00095         f = left = right = 0;
00096         threshold = 0.f;
00097     }
00098     int f, left, right;
00099     float threshold;
00100 };
00101 
00102 struct HaarClassifier
00103 {
00104     std::vector<HaarClassifierNode> nodes;
00105     std::vector<float> leaves;
00106 };
00107 
00108 struct HaarStageClassifier
00109 {
00110     double threshold;
00111     std::vector<HaarClassifier> weaks;
00112 };
00113 
00114 static bool convert(const String& oldcascade, const String& newcascade)
00115 {
00116     FileStorage oldfs(oldcascade, FileStorage::READ);
00117     if( !oldfs.isOpened() )
00118         return false;
00119     FileNode oldroot = oldfs.getFirstTopLevelNode();
00120 
00121     FileNode sznode = oldroot[ICV_HAAR_SIZE_NAME];
00122     if( sznode.empty() )
00123         return false;
00124     Size cascadesize;
00125     cascadesize.width = (int)sznode[0];
00126     cascadesize.height = (int)sznode[1];
00127     std::vector<HaarFeature> features;
00128 
00129     int i, j, k, n;
00130 
00131     FileNode stages_seq = oldroot[ICV_HAAR_STAGES_NAME];
00132     int nstages = (int)stages_seq.size();
00133     std::vector<HaarStageClassifier> stages(nstages);
00134 
00135     for( i = 0; i < nstages; i++ )
00136     {
00137         FileNode stagenode = stages_seq[i];
00138         HaarStageClassifier& stage = stages[i];
00139         stage.threshold = (double)stagenode[ICV_HAAR_STAGE_THRESHOLD_NAME];
00140         FileNode weaks_seq = stagenode[ICV_HAAR_TREES_NAME];
00141         int nweaks = (int)weaks_seq.size();
00142         stage.weaks.resize(nweaks);
00143 
00144         for( j = 0; j < nweaks; j++ )
00145         {
00146             HaarClassifier& weak = stage.weaks[j];
00147             FileNode weaknode = weaks_seq[j];
00148             int nnodes = (int)weaknode.size();
00149 
00150             for( n = 0; n < nnodes; n++ )
00151             {
00152                 FileNode nnode = weaknode[n];
00153                 FileNode fnode = nnode[ICV_HAAR_FEATURE_NAME];
00154                 HaarFeature f;
00155                 HaarClassifierNode node;
00156                 node.f = (int)features.size();
00157                 f.tilted = (int)fnode[ICV_HAAR_TILTED_NAME] != 0;
00158                 FileNode rects_seq = fnode[ICV_HAAR_RECTS_NAME];
00159                 int nrects = (int)rects_seq.size();
00160 
00161                 for( k = 0; k < nrects; k++ )
00162                 {
00163                     FileNode rnode = rects_seq[k];
00164                     f.rect[k].r.x = (int)rnode[0];
00165                     f.rect[k].r.y = (int)rnode[1];
00166                     f.rect[k].r.width = (int)rnode[2];
00167                     f.rect[k].r.height = (int)rnode[3];
00168                     f.rect[k].weight = (float)rnode[4];
00169                 }
00170                 features.push_back(f);
00171                 node.threshold = nnode[ICV_HAAR_THRESHOLD_NAME];
00172                 FileNode leftValNode = nnode[ICV_HAAR_LEFT_VAL_NAME];
00173                 if( !leftValNode.empty() )
00174                 {
00175                     node.left = -(int)weak.leaves.size();
00176                     weak.leaves.push_back((float)leftValNode);
00177                 }
00178                 else
00179                 {
00180                     node.left = (int)nnode[ICV_HAAR_LEFT_NODE_NAME];
00181                 }
00182                 FileNode rightValNode = nnode[ICV_HAAR_RIGHT_VAL_NAME];
00183                 if( !rightValNode.empty() )
00184                 {
00185                     node.right = -(int)weak.leaves.size();
00186                     weak.leaves.push_back((float)rightValNode);
00187                 }
00188                 else
00189                 {
00190                     node.right = (int)nnode[ICV_HAAR_RIGHT_NODE_NAME];
00191                 }
00192                 weak.nodes.push_back(node);
00193             }
00194         }
00195     }
00196 
00197     FileStorage newfs(newcascade, FileStorage::WRITE);
00198     if( !newfs.isOpened() )
00199         return false;
00200 
00201     int maxWeakCount = 0, nfeatures = (int)features.size();
00202     for( i = 0; i < nstages; i++ )
00203         maxWeakCount = std::max(maxWeakCount, (int)stages[i].weaks.size());
00204 
00205     newfs << "cascade" << "{:opencv-cascade-classifier"
00206     << "stageType" << "BOOST"
00207     << "featureType" << "HAAR"
00208     << "height" << cascadesize.width
00209     << "width" << cascadesize.height
00210     << "stageParams" << "{"
00211         << "maxWeakCount" << (int)maxWeakCount
00212     << "}"
00213     << "featureParams" << "{"
00214         << "maxCatCount" << 0
00215     << "}"
00216     << "stageNum" << (int)nstages
00217     << "stages" << "[";
00218 
00219     for( i = 0; i < nstages; i++ )
00220     {
00221         int nweaks = (int)stages[i].weaks.size();
00222         newfs << "{" << "maxWeakCount" << (int)nweaks
00223             << "stageThreshold" << stages[i].threshold
00224             << "weakClassifiers" << "[";
00225         for( j = 0; j < nweaks; j++ )
00226         {
00227             const HaarClassifier& c = stages[i].weaks[j];
00228             newfs << "{" << "internalNodes" << "[";
00229             int nnodes = (int)c.nodes.size(), nleaves = (int)c.leaves.size();
00230             for( k = 0; k < nnodes; k++ )
00231                 newfs << c.nodes[k].left << c.nodes[k].right
00232                     << c.nodes[k].f << c.nodes[k].threshold;
00233             newfs << "]" << "leafValues" << "[";
00234             for( k = 0; k < nleaves; k++ )
00235                 newfs << c.leaves[k];
00236             newfs << "]" << "}";
00237         }
00238         newfs << "]" << "}";
00239     }
00240 
00241     newfs << "]"
00242         << "features" << "[";
00243 
00244     for( i = 0; i < nfeatures; i++ )
00245     {
00246         const HaarFeature& f = features[i];
00247         newfs << "{" << "rects" << "[";
00248         for( j = 0; j < HaarFeature::RECT_NUM; j++ )
00249         {
00250             if( j >= 2 && fabs(f.rect[j].weight) < FLT_EPSILON )
00251                 break;
00252             newfs << "[" << f.rect[j].r.x << f.rect[j].r.y <<
00253                 f.rect[j].r.width << f.rect[j].r.height << f.rect[j].weight << "]";
00254         }
00255         newfs << "]";
00256         if( f.tilted )
00257             newfs << "tilted" << 1;
00258         newfs << "}";
00259     }
00260 
00261     newfs << "]" << "}";
00262     return true;
00263 }
00264 
00265 }
00266 
00267 //bool CascadeClassifier::convert(const String& oldcascade, const String& newcascade)
00268 //{
00269 //    bool ok = haar_cvt::convert(oldcascade, newcascade);
00270 //    if( !ok && newcascade.size() > 0 )
00271 //        remove(newcascade.c_str());
00272 //    return ok;
00273 //}
00274 
00275 }
00276