日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 目标检测 >内容正文

目标检测

OpenCV:OpenCV目标检测Adaboost+haar源代码分析

發布時間:2023/12/31 目标检测 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV:OpenCV目标检测Adaboost+haar源代码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?????? 使用OpenCV作圖像檢測, Adaboost+haar決策過程,其中一部分源代碼如下:

?? ? ? 函數調用堆棧的底層為:

1、使用有序決策樁進行預測

template<class FEval> inline int predictOrderedStump( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) {int nodeOfs = 0, leafOfs = 0;FEval& featureEvaluator = (FEval&)*_featureEvaluator;float* cascadeLeaves = &cascade.data.leaves[0];CascadeClassifier::Data::DTreeNode* cascadeNodes = &cascade.data.nodes[0];CascadeClassifier::Data::Stage* cascadeStages = &cascade.data.stages[0];//每一層進行計算,第一次訓練為19層 nstages=19//int nstages = (int)cascade.data.stages.size();for( int stageIdx = 0; stageIdx < nstages; stageIdx++ ){CascadeClassifier::Data::Stage& stage = cascadeStages[stageIdx];sum = 0.0;//每一層樹的個數int ntrees = stage.ntrees;for( int i = 0; i < ntrees; i++, nodeOfs++, leafOfs+= 2 ){CascadeClassifier::Data::DTreeNode& node = cascadeNodes[nodeOfs];//收集累積和//沒有顯示否定的特性?double value = featureEvaluator(node.featureIdx);sum += cascadeLeaves[ value < node.threshold ? leafOfs : leafOfs + 1 ];}if( sum < stage.threshold )return -stageIdx;}return 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,完成并行計算過程

??????? 其初始化過程,完成檢測。

void operator()(const Range& range) const{Ptr<FeatureEvaluator> evaluator = classifier->featureEvaluator->clone();Size winSize(cvRound(classifier->data.origWinSize.width * scalingFactor), cvRound(classifier->data.origWinSize.height * scalingFactor));int y1 = range.start * stripSize;int y2 = min(range.end * stripSize, processingRectSize.height);for( int y = y1; y < y2; y += yStep ){for( int x = 0; x < processingRectSize.width; x += yStep ){if ( (!mask.empty()) && (mask.at<uchar>(Point(x,y))==0)) {continue;}double gypWeight;//作為起始點檢測圖像是否為目標!!! wishchin 2017 03 20int result = classifier->runAt(evaluator, Point(x, y), gypWeight);#if defined (LOG_CASCADE_STATISTIC)logger.setPoint(Point(x, y), result); #endifif( rejectLevels ){if( result == 1 )result = -(int)classifier->data.stages.size();if( classifier->data.stages.size() + result < 4 ){mtx->lock();rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor), winSize.width, winSize.height));rejectLevels->push_back(-result);levelWeights->push_back(gypWeight);mtx->unlock();}}else if( result > 0 ){mtx->lock();rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor),winSize.width, winSize.height));mtx->unlock();}if( result == 0 )x += yStep;}}}CascadeClassifier* classifier;vector<Rect>* rectangles;Size processingRectSize;int stripSize, yStep;double scalingFactor;vector<int> *rejectLevels;vector<double> *levelWeights;Mat mask;Mutex* mtx; };


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源代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 男女交性视频播放 | 一区二区三区免费高清视频 | 青草青草视频 | 少妇毛片一区二区三区粉嫩av | 91麻豆精品国产91久久久久久久久 | 国产精品粉嫩 | 麻豆影视国产在线观看 | 国产精品第十页 | jzjzjzjzj亚洲成熟少妇 | 污视频网站在线播放 | 99热6这里只有精品 三级av在线免费观看 | 大地资源中文在线观看免费版 | 少妇第一次交换又紧又爽 | 在线黄色大片 | 中文字幕在线播出 | 日韩中文字幕高清 | 国产精品美女主播 | 伦在线| 青青草草 | 免费av网站在线观看 | 黄色无遮挡网站 | 久热亚洲| 亚洲少妇15p | 亚洲欧美一 | 一级特黄录像免费看 | 夜夜涩 | 中文精品在线观看 | 国产成人在线视频免费观看 | 久久在线中文字幕 | 国产又黄又粗又猛又爽视频 | 日韩在线中文字幕视频 | 国产毛片视频网站 | 精品人妻一区二区三区换脸明星 | 中文在线视频 | 99国产超薄肉色丝袜交足 | 男女日批| 成人性生交生交视频 | 黄色工厂这里只有精品 | 欧美日本中文字幕 | 制服丝袜一区二区三区 | 在线视频激情小说 | 看av免费毛片手机播放 | 日韩欧美在线第一页 | 欧美久久久一区二区三区 | 欧美日韩午夜 | 国产视频分类 | 西西人体大胆4444ww张筱雨 | 免费日韩在线 | 久久久久国产免费 | 欧美国产一区二区 | 亚洲熟妇中文字幕五十中出 | 丰满孕妇性春猛交xx大陆 | 欧美性受xxxx黑人xyx | 尤物网站在线观看 | 人妻系列一区 | 福利姬在线观看 | 日日噜噜噜噜久久久精品毛片 | 免费无码又爽又黄又刺激网站 | 一区不卡在线 | 亚洲免费视频网站 | 国产成人一区在线观看 | 天堂中文字幕免费一区 | 美人被强行糟蹋np各种play | 偷拍欧美另类 | 黄片毛片| 欧美黑人又粗又大高潮喷水 | 在哪看毛片 | 日韩成人区 | 欧美视频在线观看视频 | 光棍影院一区二区 | 99视频导航 | 国产一区二区激情 | 性欧美lx╳lx╳ | av在线男人天堂 | 欧美日韩中文国产一区发布 | 日本精品专区 | 国产精品久久久久久久免费 | 国产美女精品视频 | 亚洲av无码久久精品色欲 | 成人免费一区二区三区在线观看 | 播放灌醉水嫩大学生国内精品 | 91精品国产闺蜜国产在线闺蜜 | 一级片在线免费观看 | 中文字幕一区二区三区乱码人妻 | 亚洲一区中文字幕在线 | 国产三级精品三级在线观看 | 亚洲一级在线观看 | 国产乡下妇女做爰视频 | 亚洲s码欧洲m码国产av | 少妇激情四射 | 黄色一级片在线看 | 伊人免费在线观看高清版 | 波多野结衣 一区 | 老师用丝袜脚帮我脚交 | 丰满岳妇乱一区二区三区 | 四虎成人免费视频 | 国内精品久久久久久久影视简单 | 夏晴子在线| 精品人妻久久久久一区二区三区 |