用 svm 训练了个分类器。
给图片分类的。
目标 : 1
else : 0
载入分类器查看效果
#include "stdafx.h" #include "cv.h" #include "highgui.h" #include <ml.h> #include <iostream> #include <fstream> #include <string> #include <vector> using namespace cv; using namespace std; int main(int argc, char** argv) { CvSVM svm = CvSVM();//新建一个SVM svm.load("SVM_DATA.xml", 0); //if(svm == NULL) //{ // printf("Cant load ur xml!\n"); //} CvCapture *video = cvCaptureFromAVI("D:\\video\\s.avi"); IplImage *test = NULL; //从视频中抓取的一帧 IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3); //its size must = img's size which used to train ur xml ofstream predict_txt( "SVM_PREDICT.txt" );//把预测结果存储在这个文本中 int cnt = 0; //用来标记第几帧 cvNamedWindow( "video"); while(1) { test = cvQueryFrame(video); if(test == NULL) { break; } else { char line[512]; cvZero(trainImg); cvResize(test,trainImg); //读取图片 HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //具体意思见参考文章1,2 vector<float> descriptors;//结果数组 hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算 cout<<"HOG dims: "<<descriptors.size()<<endl; CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1); int n = 0; for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++) { cvmSet(SVMtrainMat,0,n,*iter); n++; } int ret = svm.predict(SVMtrainMat);//获取最终检测结果,这个predict的用法见 OpenCV的文档 std::sprintf( line, "Frame : %d\r\n", ret ); predict_txt<<line; if(ret == 1) { CvFont font; //定义字体结构体 cvInitFont(&font,0,1.0,1.0,0,2,8); //初始化字体结构体 char* warn=" Target!!!"; cvPutText(test, sun,cvPoint(10,10),&font,CV_RGB(255, 0, 0)); //在窗口中显示warning的红色提示信息 } cvShowImage("video", test); cvWaitKey(20); } } cvReleaseImage( &trainImg); predict_txt.close(); system("PAUSE"); return 0; }
测试某个 目录 下的图片:
#include "stdafx.h" #include "cv.h" #include "highgui.h" #include <ml.h> #include <iostream> #include <fstream> #include <string> #include <vector> using namespace cv; using namespace std; int main(int argc, char** argv) { CvSVM svm = CvSVM();//新建一个SVM svm.load("F:\\test\\SVM_DATA.xml", 0); //if(svm == NULL) //{ // printf("Cant load ur xml!\n"); //} cout<<" load xml"<<endl; string buf; int n = 0; IplImage *test; vector<string> img_tst_path; ifstream img_tst( "F:\\test\\test.txt" );//同输入训练样本,这里也是一样的,只不过不需要标注图片属于哪一类了 while( img_tst ) { if( getline( img_tst, buf ) ) { img_tst_path.push_back( buf ); } } img_tst.close(); IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);//需要分析的图片,这里默认设定图片是64*64大小,所以上面定义了1764,如果要更改图片大小,可以先用debug查看一下descriptors是多少,然后设定好再运行 CvMat *test_hog = cvCreateMat( 1, 1764, CV_32FC1 );//注意这里的1764,同上面一样 char line[512]; ofstream predict_txt( "F:\\test\\SVM_PREDICT.txt" );//把预测结果存储在这个文本中 for( string::size_type j = 0; j != img_tst_path.size(); j++ )//依次遍历所有的待检测图片 { test = cvLoadImage( img_tst_path[j].c_str(), 1); if( test == NULL ) { cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl; continue; } cvZero(trainImg); cvResize(test,trainImg); //读取图片 HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //具体意思见参考文章1,2 vector<float>descriptors;//结果数组 hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算 cout<<"HOG dims: "<<descriptors.size()<<endl; CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1); n=0; for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++) { cvmSet(SVMtrainMat,0,n,*iter); n++; } int ret = svm.predict(SVMtrainMat);//获取最终检测结果,这个predict的用法见 OpenCV的文档 std::sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret ); predict_txt<<line; } predict_txt.close(); cvReleaseImage(&trainImg); system("PAUSE"); return 0; }