svm 行人识别 训练 基于Opencv

来源:互联网 发布:java web开发流程图 编辑:程序博客网 时间:2024/06/09 20:20

写得很好的svm+ hog 的分类器训练


class Mysvm: public CvSVM{public:int get_alpha_count(){return this->sv_total;}int get_sv_dim(){return this->var_all;}int get_sv_count(){return this->decision_func->sv_count;}double* get_alpha(){return this->decision_func->alpha;}float** get_sv(){return this->sv;}float get_rho(){return this->decision_func->rho;}};void Train(){char classifierSavePath[256] = "c:/pedestrianDetect-peopleFlow.txt";string positivePath = "E:\\pictures\\train1\\pos\\";string negativePath = "E:\\pictures\\train1\\neg\\";int positiveSampleCount = 4900;int negativeSampleCount = 6192;int totalSampleCount = positiveSampleCount + negativeSampleCount;cout<<"//////////////////////////////////////////////////////////////////"<<endl;cout<<"totalSampleCount: "<<totalSampleCount<<endl;cout<<"positiveSampleCount: "<<positiveSampleCount<<endl;cout<<"negativeSampleCount: "<<negativeSampleCount<<endl;CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount , 1764, CV_32FC1);//64*128的训练样本,该矩阵将是totalSample*3780,64*64的训练样本,该矩阵将是totalSample*1764cvSetZero(sampleFeaturesMat);  CvMat *sampleLabelMat = cvCreateMat(totalSampleCount, 1, CV_32FC1);//样本标识  cvSetZero(sampleLabelMat);  cout<<"************************************************************"<<endl;cout<<"start to training positive samples..."<<endl;char positiveImgName[256];string path;for(int i=0; i<positiveSampleCount; i++)  {  memset(positiveImgName, '\0', 256*sizeof(char));sprintf(positiveImgName, "%d.jpg", i);int len = strlen(positiveImgName);string tempStr = positiveImgName;path = positivePath + tempStr;cv::Mat img = cv::imread(path);if( img.data == NULL ){cout<<"positive image sample load error: "<<i<<" "<<path<<endl;system("pause");continue;}cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);vector<float> featureVec; hog.compute(img, featureVec, cv::Size(8,8));  int featureVecSize = featureVec.size();for (int j=0; j<featureVecSize; j++)  {  CV_MAT_ELEM( *sampleFeaturesMat, float, i, j ) = featureVec[j]; }  sampleLabelMat->data.fl[i] = 1;}cout<<"end of training for positive samples..."<<endl;cout<<"*********************************************************"<<endl;cout<<"start to train negative samples..."<<endl;char negativeImgName[256];for (int i=0; i<negativeSampleCount; i++){  memset(negativeImgName, '\0', 256*sizeof(char));sprintf(negativeImgName, "%d.jpg", i);path = negativePath + negativeImgName;cv::Mat img = cv::imread(path);if(img.data == NULL){cout<<"negative image sample load error: "<<path<<endl;continue;}cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);  vector<float> featureVec; hog.compute(img,featureVec,cv::Size(8,8));//计算HOG特征int featureVecSize = featureVec.size();  for ( int j=0; j<featureVecSize; j ++)  {  CV_MAT_ELEM( *sampleFeaturesMat, float, i + positiveSampleCount, j ) = featureVec[ j ];}  sampleLabelMat->data.fl[ i + positiveSampleCount ] = -1;}  cout<<"end of training for negative samples..."<<endl;cout<<"********************************************************"<<endl;cout<<"start to train for SVM classifier..."<<endl;CvSVMParams params;  params.svm_type = CvSVM::C_SVC;  params.kernel_type = CvSVM::LINEAR;  params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, FLT_EPSILON);params.C = 0.01;Mysvm svm;svm.train( sampleFeaturesMat, sampleLabelMat, NULL, NULL, params ); //用SVM线性分类器训练svm.save(classifierSavePath);cvReleaseMat(&sampleFeaturesMat);cvReleaseMat(&sampleLabelMat);int supportVectorSize = svm.get_support_vector_count();cout<<"support vector size of SVM:"<<supportVectorSize<<endl;cout<<"************************ end of training for SVM ******************"<<endl;CvMat *sv,*alp,*re;//所有样本特征向量 sv  = cvCreateMat(supportVectorSize , 1764, CV_32FC1);alp = cvCreateMat(1 , supportVectorSize, CV_32FC1);re  = cvCreateMat(1 , 1764, CV_32FC1);CvMat *res  = cvCreateMat(1 , 1, CV_32FC1);cvSetZero(sv);cvSetZero(re);  for(int i=0; i<supportVectorSize; i++){memcpy( (float*)(sv->data.fl+i*1764), svm.get_support_vector(i), 1764*sizeof(float));}double* alphaArr = svm.get_alpha();int alphaCount = svm.get_alpha_count();for(int i=0; i<supportVectorSize; i++){        alp->data.fl[i] = alphaArr[i];}cvMatMul(alp, sv, re);int posCount = 0;for (int i=0; i<1764; i++){re->data.fl[i] *= -1;}FILE* fp = fopen("c:/hogSVMDetector-peopleFlow.txt","wb");if( NULL == fp ){return 1;}for(int i=0; i<1764; i++){fprintf(fp,"%f \n",re->data.fl[i]);}float rho = svm.get_rho();fprintf(fp, "%f", rho);cout<<"c:/hogSVMDetector.txt 保存完毕"<<endl;//保存HOG能识别的分类器fclose(fp);return 1;}


检测代码那和opencv的差不多了

void Detect(){CvCapture* cap = cvCreateFileCapture("E:\\02.avi");if (!cap){cout<<"avi file load error..."<<endl;system("pause");exit(-1);}vector<float> x;ifstream fileIn("c:/hogSVMDetector-peopleFlow.txt", ios::in);float val = 0.0f;while(!fileIn.eof()){fileIn>>val;x.push_back(val);}fileIn.close();vector<cv::Rect>  found;cv::HOGDescriptor hog(cv::Size(64,64), cv::Size(16,16), cv::Size(8,8), cv::Size(8,8), 9);hog.setSVMDetector(x);IplImage* img = NULL;cvNamedWindow("img", 0);while(img=cvQueryFrame(cap)){hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);if (found.size() > 0){for (int i=0; i<found.size(); i++){CvRect tempRect = cvRect(found[i].x, found[i].y, found[i].width, found[i].height);cvRectangle(img, cvPoint(tempRect.x,tempRect.y),cvPoint(tempRect.x+tempRect.width,tempRect.y+tempRect.height),CV_RGB(255,0,0), 2);}}}cvReleaseCapture(&cap);}


svm + hog算法,做行人识别,效果其实不错的,和haar +adaboost应该有得比,在dm3730 arm + dsp 双核的,我实现了两种方法,感觉svm+hog速度慢了点,haar + adaboost 速度还可以,做了行人识别, 分类器自己训练的,18个 stage那样,640X480.  如果在DM8148或 Dm8168做,应该很实用了。如果是纯的dsp,以前在dm6437上做,感觉速度也不怎么行。目前正在研究dm8148的架构,和omap或Dm3730差不多,多了一些OpenMax之类,估计是照顾android开发用户,我还是喜欢直接基于linux开发,代码直接是c的,新的opencv多了一些 vector之类,估计ti的dsp环境可能不支持。
 

原创粉丝点击