hog
2015-06-12 16:07
162 查看
// #include"stdafx.h" #include<stdio.h> #include "opencv2\opencv.hpp" #include "windows.h" #include "fstream" #include <iostream> #include<iterator> #include<string> #include<objdetect\objdetect.hpp> #include<opencv2\core\core.hpp> #ifdef HAVE_IPP #include "ipp.h" #endif using namespace std; using namespace cv; class HOGInvoker : public ParallelLoopBody { public: HOGInvoker( const HOGDescriptor* _hog, const Mat& _img, double _hitThreshold, Size _winStride, Size _padding, const double* _levelScale, std::vector<Rect> * _vec, Mutex* _mtx, std::vector<double>* _weights=0, std::vector<double>* _scales=0 ) { hog = _hog; img = _img; hitThreshold = _hitThreshold; winStride = _winStride; padding = _padding; levelScale = _levelScale; vec = _vec; weights = _weights; scales = _scales; mtx = _mtx; } void operator()( const Range& range ) const { int i, i1 = range.start, i2 = range.end; double minScale = i1 > 0 ? levelScale[i1] : i2 > 1 ? levelScale[i1+1] : max(img.cols, img.rows); printf("%d , %d \n",i1,i2); //double minScale=levelScale[i1]; Size maxSz(cvCeil(img.cols/minScale), cvCeil(img.rows/minScale)); Mat smallerImgBuf(maxSz, img.type()); vector<Point> locations; vector<double> hitsWeights; for( i = i1; i < i2; i++ ) { double scale = levelScale[i]; Size sz(cvRound(img.cols/scale), cvRound(img.rows/scale)); Mat smallerImg(sz, img.type(), smallerImgBuf.data); if( sz == img.size() ) smallerImg = Mat(sz, img.type(), img.data, img.step); else resize(img, smallerImg, sz); hog->detect(smallerImg, locations, hitsWeights, hitThreshold/scale, winStride, padding); Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale)); mtx->lock(); for( size_t j = 0; j < locations.size(); j++ ) { vec->push_back(Rect(cvRound(locations[j].x*scale), cvRound(locations[j].y*scale), scaledWinSize.width, scaledWinSize.height)); if (scales) { scales->push_back(scale); } } mtx->unlock(); if (weights && (!hitsWeights.empty())) { mtx->lock(); for (size_t j = 0; j < locations.size(); j++) { weights->push_back(hitsWeights[j]); } mtx->unlock(); } } } const HOGDescriptor* hog; Mat img; double hitThreshold; Size winStride; Size padding; const double* levelScale; std::vector<Rect>* vec; std::vector<double>* weights; std::vector<double>* scales; Mutex* mtx; }; struct MyHog:public HOGDescriptor { public: void get(const Mat& img, vector<Rect>& foundLocations, double hitThreshold, Size winStride, Size padding, double scale0, double finalThreshold, bool useMeanshiftGrouping) { vector<double> foundWeights; this->detectMultiScale2(img, foundLocations, foundWeights, hitThreshold, winStride, padding, scale0, finalThreshold, useMeanshiftGrouping); } void get1(const Mat& img, vector<Rect>& foundLocations, double hitThreshold, Size winStride, Size padding, double scale0, double finalThreshold, bool useMeanshiftGrouping) { vector<double> foundWeights; this->detectMultiScale3(img, foundLocations, foundWeights, hitThreshold, winStride, padding, scale0, finalThreshold, useMeanshiftGrouping); } void detectMultiScale2( const Mat& img, vector<Rect>& foundLocations, vector<double>& foundWeights, double hitThreshold, Size winStride, Size padding, double scale0, double finalThreshold, bool useMeanshiftGrouping) const { double scale = 1.; int levels = 0; vector<double> levelScale; for( levels = 0; levels < nlevels; levels++ ) { levelScale.push_back(scale); if( cvRound(img.cols/scale) < img.cols*0.55 ||// 可以自己制定图像的终止大小 cvRound(img.rows/scale) < img.rows*0.55 || scale0 <= 1 ) break; scale *= scale0; } //修改后 // for( levels = 0; levels < 4; levels++ ) // { // levelScale.push_back(scale__[levels]); //} levels = max(levels, 1); levelScale.resize(levels); std::vector<Rect> allCandidates; std::vector<double> tempScales; std::vector<double> tempWeights; std::vector<double> foundScales; Mutex mtx; parallel_for_(Range(0, (int)levelScale.size()), HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &mtx, &tempWeights, &tempScales));//并行寻找候选区域 std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales)); foundLocations.clear(); std::copy(allCandidates.begin(), allCandidates.end(), back_inserter(foundLocations)); foundWeights.clear(); std::copy(tempWeights.begin(), tempWeights.end(), back_inserter(foundWeights)); if ( useMeanshiftGrouping ) { groupRectangles_meanshift1(foundLocations, foundWeights, foundScales, finalThreshold, winSize); } else { groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2); } } void detectMultiScale3( const Mat& img, vector<Rect>& foundLocations, vector<double>& foundWeights, double hitThreshold, Size winStride, Size padding, double scale0, double finalThreshold, bool useMeanshiftGrouping) const { double scale = 1.; int levels = 0; vector<double> levelScale; for( levels = 0; levels < nlevels; levels++ ) { levelScale.push_back(scale); if( cvRound(img.cols/scale) < img.cols ||// 可以自己制定图像的终止大小 cvRound(img.rows/scale) < img.rows || scale0 <= 1 ) break; scale *= scale0; } levels = max(levels, 1); levelScale.resize(levels); std::vector<Rect> allCandidates; std::vector<double> tempScales; std::vector<double> tempWeights; std::vector<double> foundScales; Mutex mtx; parallel_for_(Range(0, (int)levelScale.size()), HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &mtx, &tempWeights, &tempScales));//并行寻找候选区域 std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales)); foundLocations.clear(); std::copy(allCandidates.begin(), allCandidates.end(), back_inserter(foundLocations)); foundWeights.clear(); std::copy(tempWeights.begin(), tempWeights.end(), back_inserter(foundWeights)); if ( useMeanshiftGrouping ) { groupRectangles_meanshift1(foundLocations, foundWeights, foundScales, finalThreshold, winSize); } else { groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2); } } class MeanshiftGrouping { public: MeanshiftGrouping(const Point3d& densKer, const vector<Point3d>& posV, const vector<double>& wV, double eps, int maxIter = 20) { densityKernel = densKer; weightsV = wV; positionsV = posV; positionsCount = (int)posV.size(); meanshiftV.resize(positionsCount); distanceV.resize(positionsCount); iterMax = maxIter; modeEps = eps; for (unsigned i = 0; i<positionsV.size(); i++) { meanshiftV[i] = getNewValue(positionsV[i]); distanceV[i] = moveToMode(meanshiftV[i]);//做最大为iterMax次循环//均值漂移后的符合要求的距离 meanshiftV[i] -= positionsV[i]; } } void getModes(vector<Point3d>& modesV, vector<double>& resWeightsV, const double eps) { for (size_t i=0; i <distanceV.size(); i++) { bool is_found = false; for(size_t j=0; j<modesV.size(); j++) { if ( getDistance(distanceV[i], modesV[j]) < eps) { is_found=true; break; } } if (!is_found) { modesV.push_back(distanceV[i]); } } resWeightsV.resize(modesV.size()); for (size_t i=0; i<modesV.size(); i++) { resWeightsV[i] = getResultWeight(modesV[i]); } } protected: vector<Point3d> positionsV; vector<double> weightsV; Point3d densityKernel; int positionsCount; vector<Point3d> meanshiftV; vector<Point3d> distanceV; int iterMax; double modeEps; Point3d getNewValue(const Point3d& inPt) const { Point3d resPoint(.0); Point3d ratPoint(.0); for (size_t i=0; i<positionsV.size(); i++) { Point3d aPt= positionsV[i]; Point3d bPt = inPt; Point3d sPt = densityKernel; //////////////////////////////////////// sPt.x *= exp(aPt.z); sPt.y *= exp(aPt.z); aPt.x /= sPt.x; aPt.y /= sPt.y; aPt.z /= sPt.z; bPt.x /= sPt.x; bPt.y /= sPt.y; bPt.z /= sPt.z; ///映射到对应尺度的图片的坐标/////////sPt为scale// //////////////////////////////////////////// double w = (weightsV[i])*std::exp(-((aPt-bPt).dot(aPt-bPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1))); //重新计算的权重,原权重为线性SVM的得分 resPoint += w*aPt; ratPoint.x += w/sPt.x;//这边除以权重值,使得放缩后的图像权重变小 ratPoint.y += w/sPt.y; ratPoint.z += w/sPt.z; } resPoint.x /= ratPoint.x; resPoint.y /= ratPoint.y; resPoint.z /= ratPoint.z; return resPoint; } double getResultWeight(const Point3d& inPt) const { double sumW=0; int num=0; size_t aa=positionsV.size(); int len = int(aa); for (size_t i=0; i<aa; i++) { Point3d aPt = positionsV[i]; Point3d sPt = densityKernel; sPt.x *= exp(aPt.z); sPt.y *= exp(aPt.z); aPt -= inPt; aPt.x /= sPt.x; aPt.y /= sPt.y; aPt.z /= sPt.z; sumW+=(weightsV[i])*std::exp(-(aPt.dot(aPt))/2)/std::sqrt(sPt.dot(Point3d(1,1,1))); } return sumW; } Point3d moveToMode(Point3d aPt) const { Point3d bPt; for (int i = 0; i<iterMax; i++) { bPt = aPt; aPt = getNewValue(bPt); if ( getDistance(aPt, bPt) <= modeEps ) { break; } } return aPt; } double getDistance(Point3d p1, Point3d p2) const { Point3d ns = densityKernel; ns.x *= exp(p2.z); ns.y *= exp(p2.z); p2 -= p1; p2.x /= ns.x; p2.y /= ns.y; p2.z /= ns.z; return p2.dot(p2); } }; void groupRectangles_meanshift1(vector<Rect>& rectList, vector<double>& foundWeights, vector<double>& foundScales, double detectThreshold, Size winDetSize)const { groupRectangles_meanshift(rectList, detectThreshold, &foundWeights, foundScales, winDetSize); } //new grouping function with using meanshift static void groupRectangles_meanshift(vector<Rect>& rectList, double detectThreshold, vector<double>* foundWeights, vector<double>& scales, Size winDetSize) { int detectionCount = (int)rectList.size(); vector<Point3d> hits(detectionCount), resultHits; vector<double> hitWeights(detectionCount), resultWeights; Point2d hitCenter; for (int i=0; i < detectionCount; i++) { hitWeights[i] = (*foundWeights)[i]; hitCenter = (rectList[i].tl() + rectList[i].br())*(0.5); //center of rectangles hits[i] = Point3d(hitCenter.x, hitCenter.y, std::log(scales[i])); } rectList.clear(); if (foundWeights) foundWeights->clear(); double logZ = std::log(1.3); Point3d smothing(8, 16, logZ); MeanshiftGrouping msGrouping(smothing, hits, hitWeights, 1e-5, 100); msGrouping.getModes(resultHits, resultWeights, 1); for (unsigned i=0; i < resultHits.size(); ++i) { double scale = exp(resultHits[i].z); hitCenter.x = resultHits[i].x; hitCenter.y = resultHits[i].y; Size s( int(winDetSize.width * scale), int(winDetSize.height * scale) ); Rect resultRect( int(hitCenter.x-s.width/2), int(hitCenter.y-s.height/2), int(s.width), int(s.height) ); if (resultWeights[i] > detectThreshold)//detectThreshold { rectList.push_back(resultRect); foundWeights->push_back(resultWeights[i]); } } } }; int _tmain(int argc, _TCHAR* argv[]) { vector<float> x; vector<float> x1; ifstream fileIn1("1.txt", ios::in); ifstream fileIn("2.txt", ios::in); float val = 0.0f; while(!fileIn.eof()) { fileIn>>val; x.push_back(val); } fileIn.close(); while(!fileIn1.eof()) { fileIn1>>val; x1.push_back(val); } fileIn1.close(); MyHog hog_; hog_.gammaCorrection=false; hog_.blockSize=cv::Size(16,16); hog_.blockStride=cv::Size(8,8); hog_.cellSize=cv::Size(8,8); hog_.winSize=cv::Size(64,64); hog_.setSVMDetector(x); MyHog hog_1; hog_1.gammaCorrection=false; hog_1.blockSize=cv::Size(16,16); hog_1.blockStride=cv::Size(8,8); hog_1.cellSize=cv::Size(8,8); hog_1.winSize=cv::Size(64,64); hog_1.setSVMDetector(x1); vector<Rect> found, found_filtered; vector<Rect> found1; vector<double> weigths; Mat img; int n = 0; std::stringstream ss; std::string str; str=str+str; vector<string> img_path;//输入文件名变量 string buf; ifstream filename( "list.txt" ); while( filename )//将训练样本文件依次读取进来 { if( getline( filename, buf ) ) { img_path.push_back( buf );//图像路径 } } img = imread("D:/1.png"); double scale=1.3;//将原图放大1.3倍 int wid = (int)img.size().width*scale; int hei = (int)img.size().height*scale; Mat imgResize=Mat(wid,hei,CV_8U); Size dsize = Size(wid,hei); resize(img,imgResize,dsize); double t = (double)getTickCount(); hog_.get(imgResize, found,0.0, Size(2, 2), Size(1, 1), 1.15, 5,true);//1 hog_1.get(imgResize, found1,0.0, Size(2, 2), Size(1, 1), 1.15, 5,true);//2 double t1 =(double)getTickCount(); double tt=(t1 - t)/getTickFrequency(); cout << "Times passed in seconds: " << tt << endl; copy(found1.begin(),found1.end(),back_inserter(found)); int i=0,j=0; for( i = 0; i < found.size(); i++ ) { //进行了重合去除 Rect r = found[i]; for( j = 0; j < found.size(); j++ ) if( j != i && (r & found[j]) == r) break; if( j == found.size() ) found_filtered.push_back(r); } for( i = 0; i < found_filtered.size(); i++ ) { Rect r = found_filtered[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. //r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*1.15); //r.y += cvRound(r.height*0.1); r.height = cvRound(r.height*1.15); rectangle(imgResize, r.tl(), r.br(), cv::Scalar(0,255,0), 3); } found.clear(); found_filtered.clear(); Size dsize1 = Size(img.size().width,img.size().height); Mat img2=Mat(dsize1,CV_8U); resize(imgResize,img2,dsize1); string name=str; name+= "aa.jpg";//保存图片 imwrite(name,imgResize); <span style="white-space:pre"> </span> imshow("people detector", img2); waitKey(); return 0; }
相关文章推荐
- session超时,处理ajax请求
- JavaScript语法
- beaglebone black spi使用笔记(2)-adt7320代码编写
- C宏系统缺陷
- 适用的链接收藏
- PL/SQL Developer 远程连接Oracle数据库
- android studio 导入jar包
- excel 返回符合条件的所有数据
- 通达OA web页面与精灵显示内容更新后不一致的问题
- VC操作INI文件
- HBase在腾讯大数据的应用实践
- srm 536
- 把字符串转换成整数
- 通达OA web页面与精灵显示内容更新后不一致的问题
- Oracle 使用小计(3)
- Android初学习 - 实现“重置应用偏好设置”的功能
- 【Qt编程】基于QWT的曲线绘制及图例显示操作
- 如何在应用中发送自己定义的广播Broadcast
- LeetCode63:Unique Paths II
- 不错的在线印章生成器网站