OpenCV:OpenCV目标检测Adaboost+haar源代码分析
生活随笔
收集整理的這篇文章主要介紹了
OpenCV:OpenCV目标检测Adaboost+haar源代码分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?????? 使用OpenCV作圖像檢測, Adaboost+haar決策過程,其中一部分源代碼如下:
?? ? ? 函數調用堆棧的底層為:
1、使用有序決策樁進行預測
2.上層調用:在某個點之處進行計算
int CascadeClassifier::runAt( Ptr<FeatureEvaluator>& evaluator, Point pt, double& weight ) {CV_Assert( oldCascade.empty() );assert( data.featureType == FeatureEvaluator::HAAR ||data.featureType == FeatureEvaluator::LBP ||data.featureType == FeatureEvaluator::HOG );if( !evaluator->setWindow(pt) )return -1;if( data.isStumpBased ){//若使用haar特征,則進行haar檢測過程 wishchin if( data.featureType == FeatureEvaluator::HAAR )return predictOrderedStump<HaarEvaluator>( *this, evaluator, weight );else if( data.featureType == FeatureEvaluator::LBP )return predictCategoricalStump<LBPEvaluator>( *this, evaluator, weight );else if( data.featureType == FeatureEvaluator::HOG )return predictOrderedStump<HOGEvaluator>( *this, evaluator, weight );elsereturn -2;}else{if( data.featureType == FeatureEvaluator::HAAR )return predictOrdered<HaarEvaluator>( *this, evaluator, weight );else if( data.featureType == FeatureEvaluator::LBP )return predictCategorical<LBPEvaluator>( *this, evaluator, weight );else if( data.featureType == FeatureEvaluator::HOG )return predictOrdered<HOGEvaluator>( *this, evaluator, weight );elsereturn -2;} }3. CascadeClassifierInvoker初始化時產生的 CascadeClassifier,
其中 每個inVoker繼承于并行循環的body:例如 class CascadeClassifier : public ParallelLoopBody,完成并行計算過程
??????? 其初始化過程,完成檢測。
4.使用多尺度計算過程,對每一層進行單層結果計算
bool CascadeClassifier::detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,int stripSize, int yStep, double factor, vector<Rect>& candidates,vector<int>& levels, vector<double>& weights, bool outputRejectLevels ) {if( !featureEvaluator->setImage( image, data.origWinSize ) )return false;#if defined (LOG_CASCADE_STATISTIC)logger.setImage(image); #endifMat currentMask;if (!maskGenerator.empty()) {currentMask=maskGenerator->generateMask(image);}vector<Rect> candidatesVector;vector<int> rejectLevels;vector<double> levelWeights;Mutex mtx;if( outputRejectLevels ){parallel_for_(Range(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,candidatesVector, rejectLevels, levelWeights, true, currentMask, &mtx));levels.insert( levels.end(), rejectLevels.begin(), rejectLevels.end() );weights.insert( weights.end(), levelWeights.begin(), levelWeights.end() );}else{//并行處理過程,對每一層初始化一個CascadeClassifierInvoker,完成計算parallel_for_(Range(0, stripCount), CascadeClassifierInvoker( *this, processingRectSize, stripSize, yStep, factor,candidatesVector, rejectLevels, levelWeights, false, currentMask, &mtx));}candidates.insert( candidates.end(), candidatesVector.begin(), candidatesVector.end() );#if defined (LOG_CASCADE_STATISTIC)logger.write(); #endifreturn true; }5. 進行多尺度檢測 void CascadeClassifier::detectMultiScale( const Mat& image, vector<Rect>& objects,vector<int>& rejectLevels,vector<double>& levelWeights,double scaleFactor, int minNeighbors,int flags, Size minObjectSize, Size maxObjectSize,bool outputRejectLevels ) {const double GROUP_EPS = 0.2;CV_Assert( scaleFactor > 1 && image.depth() == CV_8U );if( empty() )return;if( isOldFormatCascade() ){MemStorage storage(cvCreateMemStorage(0));CvMat _image = image;CvSeq* _objects = cvHaarDetectObjectsForROC( &_image, oldCascade, storage, rejectLevels, levelWeights, scaleFactor,minNeighbors, flags, minObjectSize, maxObjectSize, outputRejectLevels );vector<CvAvgComp> vecAvgComp;Seq<CvAvgComp>(_objects).copyTo(vecAvgComp);objects.resize(vecAvgComp.size());std::transform(vecAvgComp.begin(), vecAvgComp.end(), objects.begin(), getRect());return;}objects.clear();if (!maskGenerator.empty()) {maskGenerator->initializeMask(image);}if( maxObjectSize.height == 0 || maxObjectSize.width == 0 )maxObjectSize = image.size();Mat grayImage = image;if( grayImage.channels() > 1 ){Mat temp;cvtColor(grayImage, temp, CV_BGR2GRAY);grayImage = temp;}Mat imageBuffer(image.rows + 1, image.cols + 1, CV_8U);vector<Rect> candidates;for( double factor = 1; ; factor *= scaleFactor ){Size originalWindowSize = getOriginalWindowSize();Size windowSize( cvRound(originalWindowSize.width*factor), cvRound(originalWindowSize.height*factor) );Size scaledImageSize( cvRound( grayImage.cols/factor ), cvRound( grayImage.rows/factor ) );Size processingRectSize( scaledImageSize.width - originalWindowSize.width, scaledImageSize.height - originalWindowSize.height );if( processingRectSize.width <= 0 || processingRectSize.height <= 0 )break;if( windowSize.width > maxObjectSize.width || windowSize.height > maxObjectSize.height )break;if( windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height )continue;Mat scaledImage( scaledImageSize, CV_8U, imageBuffer.data );resize( grayImage, scaledImage, scaledImageSize, 0, 0, CV_INTER_LINEAR );int yStep;if( getFeatureType() == cv::FeatureEvaluator::HOG ){yStep = 4;}else{yStep = factor > 2. ? 1 : 2;}int stripCount, stripSize;const int PTS_PER_THREAD = 1000;stripCount = ((processingRectSize.width/yStep)*(processingRectSize.height + yStep-1)/yStep + PTS_PER_THREAD/2)/PTS_PER_THREAD;stripCount = std::min(std::max(stripCount, 1), 100);stripSize = (((processingRectSize.height + stripCount - 1)/stripCount + yStep-1)/yStep)*yStep;//對每一個尺度進行目標檢測 wishchin 2017 03 21 if( !detectSingleScale( scaledImage, stripCount, processingRectSize, stripSize, yStep, factor, candidates,rejectLevels, levelWeights, outputRejectLevels ) )break;}objects.resize(candidates.size());std::copy(candidates.begin(), candidates.end(), objects.begin());if( outputRejectLevels ){groupRectangles( objects, rejectLevels, levelWeights, minNeighbors, GROUP_EPS );}else{groupRectangles( objects, minNeighbors, GROUP_EPS );} }
以上為objectDetect過程的OpenCV的源代碼,外層調用的使用函數接口可以為: // 人眼檢測m_cascade.detectMultiScale(smallImg,eyes,fAdaBoostScale, // originally 1.1, 4 is faster 2, //minNeighbors//|CV_HAAR_FIND_BIGGEST_OBJECT//|CV_HAAR_DO_ROUGH_SEARCHCV_HAAR_DO_CANNY_PRUNING,Size(48, 32));//cout << "eyes size=:" << eyes.size() << endl;
總結:
??????? 上述過程即是Haar+Adaboost檢測計算大致的函數調用堆棧。
總結
以上是生活随笔為你收集整理的OpenCV:OpenCV目标检测Adaboost+haar源代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搜狗输入法如何设置快捷短语(搜狗搜索引擎
- 下一篇: 2厘利息怎么算