Path: blob/master/modules/objdetect/src/cascadedetect_convert.cpp
16337 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2013, Itseez Inc, all rights reserved.13// Third party copyrights are property of their respective owners.14//15// Redistribution and use in source and binary forms, with or without modification,16// are permitted provided that the following conditions are met:17//18// * Redistribution's of source code must retain the above copyright notice,19// this list of conditions and the following disclaimer.20//21// * Redistribution's in binary form must reproduce the above copyright notice,22// this list of conditions and the following disclaimer in the documentation23// and/or other materials provided with the distribution.24//25// * The name of Intel Corporation may not be used to endorse or promote products26// derived from this software without specific prior written permission.27//28// This software is provided by the copyright holders and contributors "as is" and29// any express or implied warranties, including, but not limited to, the implied30// warranties of merchantability and fitness for a particular purpose are disclaimed.31// In no event shall the Intel Corporation or contributors be liable for any direct,32// indirect, incidental, special, exemplary, or consequential damages33// (including, but not limited to, procurement of substitute goods or services;34// loss of use, data, or profits; or business interruption) however caused35// and on any theory of liability, whether in contract, strict liability,36// or tort (including negligence or otherwise) arising in any way out of37// the use of this software, even if advised of the possibility of such damage.38//39//M*/4041/* Haar features calculation */4243#include "precomp.hpp"44#include <stdio.h>4546namespace cv47{4849/* field names */5051#define ICV_HAAR_SIZE_NAME "size"52#define ICV_HAAR_STAGES_NAME "stages"53#define ICV_HAAR_TREES_NAME "trees"54#define ICV_HAAR_FEATURE_NAME "feature"55#define ICV_HAAR_RECTS_NAME "rects"56#define ICV_HAAR_TILTED_NAME "tilted"57#define ICV_HAAR_THRESHOLD_NAME "threshold"58#define ICV_HAAR_LEFT_NODE_NAME "left_node"59#define ICV_HAAR_LEFT_VAL_NAME "left_val"60#define ICV_HAAR_RIGHT_NODE_NAME "right_node"61#define ICV_HAAR_RIGHT_VAL_NAME "right_val"62#define ICV_HAAR_STAGE_THRESHOLD_NAME "stage_threshold"63#define ICV_HAAR_PARENT_NAME "parent"64#define ICV_HAAR_NEXT_NAME "next"6566namespace haar_cvt67{6869struct HaarFeature70{71enum { RECT_NUM = 3 };7273HaarFeature()74{75tilted = false;76for( int i = 0; i < RECT_NUM; i++ )77{78rect[i].r = Rect(0,0,0,0);79rect[i].weight = 0.f;80}81}82bool tilted;83struct84{85Rect r;86float weight;87} rect[RECT_NUM];88};8990struct HaarClassifierNode91{92HaarClassifierNode()93{94f = left = right = 0;95threshold = 0.f;96}97int f, left, right;98float threshold;99};100101struct HaarClassifier102{103std::vector<HaarClassifierNode> nodes;104std::vector<float> leaves;105};106107struct HaarStageClassifier108{109double threshold;110std::vector<HaarClassifier> weaks;111};112113static bool convert(const String& oldcascade, const String& newcascade)114{115FileStorage oldfs(oldcascade, FileStorage::READ);116if( !oldfs.isOpened() )117return false;118FileNode oldroot = oldfs.getFirstTopLevelNode();119120FileNode sznode = oldroot[ICV_HAAR_SIZE_NAME];121if( sznode.empty() )122return false;123Size cascadesize;124cascadesize.width = (int)sznode[0];125cascadesize.height = (int)sznode[1];126std::vector<HaarFeature> features;127128int i, j, k, n;129130FileNode stages_seq = oldroot[ICV_HAAR_STAGES_NAME];131int nstages = (int)stages_seq.size();132std::vector<HaarStageClassifier> stages(nstages);133134for( i = 0; i < nstages; i++ )135{136FileNode stagenode = stages_seq[i];137HaarStageClassifier& stage = stages[i];138stage.threshold = (double)stagenode[ICV_HAAR_STAGE_THRESHOLD_NAME];139FileNode weaks_seq = stagenode[ICV_HAAR_TREES_NAME];140int nweaks = (int)weaks_seq.size();141stage.weaks.resize(nweaks);142143for( j = 0; j < nweaks; j++ )144{145HaarClassifier& weak = stage.weaks[j];146FileNode weaknode = weaks_seq[j];147int nnodes = (int)weaknode.size();148149for( n = 0; n < nnodes; n++ )150{151FileNode nnode = weaknode[n];152FileNode fnode = nnode[ICV_HAAR_FEATURE_NAME];153HaarFeature f;154HaarClassifierNode node;155node.f = (int)features.size();156f.tilted = (int)fnode[ICV_HAAR_TILTED_NAME] != 0;157FileNode rects_seq = fnode[ICV_HAAR_RECTS_NAME];158int nrects = (int)rects_seq.size();159160for( k = 0; k < nrects; k++ )161{162FileNode rnode = rects_seq[k];163f.rect[k].r.x = (int)rnode[0];164f.rect[k].r.y = (int)rnode[1];165f.rect[k].r.width = (int)rnode[2];166f.rect[k].r.height = (int)rnode[3];167f.rect[k].weight = (float)rnode[4];168}169features.push_back(f);170node.threshold = nnode[ICV_HAAR_THRESHOLD_NAME];171FileNode leftValNode = nnode[ICV_HAAR_LEFT_VAL_NAME];172if( !leftValNode.empty() )173{174node.left = -(int)weak.leaves.size();175weak.leaves.push_back((float)leftValNode);176}177else178{179node.left = (int)nnode[ICV_HAAR_LEFT_NODE_NAME];180}181FileNode rightValNode = nnode[ICV_HAAR_RIGHT_VAL_NAME];182if( !rightValNode.empty() )183{184node.right = -(int)weak.leaves.size();185weak.leaves.push_back((float)rightValNode);186}187else188{189node.right = (int)nnode[ICV_HAAR_RIGHT_NODE_NAME];190}191weak.nodes.push_back(node);192}193}194}195196FileStorage newfs(newcascade, FileStorage::WRITE);197if( !newfs.isOpened() )198return false;199200int maxWeakCount = 0, nfeatures = (int)features.size();201for( i = 0; i < nstages; i++ )202maxWeakCount = std::max(maxWeakCount, (int)stages[i].weaks.size());203204newfs << "cascade" << "{:opencv-cascade-classifier"205<< "stageType" << "BOOST"206<< "featureType" << "HAAR"207<< "height" << cascadesize.width208<< "width" << cascadesize.height209<< "stageParams" << "{"210<< "maxWeakCount" << (int)maxWeakCount211<< "}"212<< "featureParams" << "{"213<< "maxCatCount" << 0214<< "}"215<< "stageNum" << (int)nstages216<< "stages" << "[";217218for( i = 0; i < nstages; i++ )219{220int nweaks = (int)stages[i].weaks.size();221newfs << "{" << "maxWeakCount" << (int)nweaks222<< "stageThreshold" << stages[i].threshold223<< "weakClassifiers" << "[";224for( j = 0; j < nweaks; j++ )225{226const HaarClassifier& c = stages[i].weaks[j];227newfs << "{" << "internalNodes" << "[";228int nnodes = (int)c.nodes.size(), nleaves = (int)c.leaves.size();229for( k = 0; k < nnodes; k++ )230newfs << c.nodes[k].left << c.nodes[k].right231<< c.nodes[k].f << c.nodes[k].threshold;232newfs << "]" << "leafValues" << "[";233for( k = 0; k < nleaves; k++ )234newfs << c.leaves[k];235newfs << "]" << "}";236}237newfs << "]" << "}";238}239240newfs << "]"241<< "features" << "[";242243for( i = 0; i < nfeatures; i++ )244{245const HaarFeature& f = features[i];246newfs << "{" << "rects" << "[";247for( j = 0; j < HaarFeature::RECT_NUM; j++ )248{249if( j >= 2 && fabs(f.rect[j].weight) < FLT_EPSILON )250break;251newfs << "[" << f.rect[j].r.x << f.rect[j].r.y <<252f.rect[j].r.width << f.rect[j].r.height << f.rect[j].weight << "]";253}254newfs << "]";255if( f.tilted )256newfs << "tilted" << 1;257newfs << "}";258}259260newfs << "]" << "}";261return true;262}263264}265266bool CascadeClassifier::convert(const String& oldcascade, const String& newcascade)267{268bool ok = haar_cvt::convert(oldcascade, newcascade);269if( !ok && newcascade.size() > 0 )270remove(newcascade.c_str());271return ok;272}273274}275276277