标签:
#include "cv.h"
#include "highgui.h"
#include "ml.h"
#include <iostream>
#include <fstream>
#include <string.h>
#include "objdetect.hpp"
#include <vector>
//#include <opencv2/highgui/highgui.hpp>
//#include <opencv2/core/core.hpp>
//#include <opencv2/imgproc/imgproc.hpp>
///LoadLibrary("opencv_objdetect245.dll");
#define MyStride 8
#define Dst_img_width 28
#define Dst_img_height 28
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
/* vector<string> img_path;//输入文件名变量
vector<int> img_catg;
int nLine = 0;
string buf;
ifstream svm_data( "svmTrainSet.txt" );
//首先,这里搞一个文件列表,把训练样本图片的路径都写在这个txt文件中,使用bat批处理文件可以得到这个txt文件
unsigned long n;
while( svm_data )//将训练样本文件依次读取进来
{
if( getline( svm_data, buf ) )
{
nLine ++;
if( nLine % 2 == 0 )//这里的分类比较有意思,看得出来上面的SVM_DATA.txt文本中应该是一行是文件路径,接着下一行就是该图片的类别,可以设置为0或者1,当然多个也无所谓
{
img_catg.push_back( atoi( buf.c_str() ) );//atoi将字符串转换成整型,标志(0,1),注意这里至少要有两个类别,否则会出错
}
else
{
img_path.push_back( buf );//图像路径
}
}
}
svm_data.close();//关闭文件
CvMat *data_mat, *res_mat;
int nImgNum = nLine / 2; //读入样本数量 ,因为是每隔一行才是图片路径,所以要除以2
////样本矩阵,nImgNum:横坐标是样本数量, WIDTH * HEIGHT:样本特征向量,即图像大小
//这里第二个参数,即矩阵的列是由下面的descriptors的大小决定的,可以由descriptors.size()得到,且对于不同大小的输入训练图片,这个值是不同的
data_mat = cvCreateMat( nImgNum, 1296, CV_32FC1 );
cvSetZero( data_mat );
//类型矩阵,存储每个样本的类型标志
res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 | CV_32SC1 );
cvSetZero( res_mat );
IplImage* src;
string path;
//IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);//需要分析的图片,这里默认设定图片是64*64大小,所以上面定义了1764,如果要更改图片大小,可以先用debug查看一下descriptors是多少,然后设定好再运行
IplImage* trainImg=cvCreateImage(cvSize(28,28),8,1);
vector<float>descriptors;//结果数组
//开始搞HOG特征
// HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //具体意思见参考文章1,2
HOGDescriptor *hog=new HOGDescriptor(cvSize(28,28),cvSize(12,12),cvSize(8,8),cvSize(3,3),9);
for( string::size_type i = 0; i != img_path.size(); i++ )
{
path=".\\TrainData\\"+img_path[i];
// src=cvLoadImage(path.c_str(),1);
src=cvLoadImage(path.c_str(),CV_LOAD_IMAGE_GRAYSCALE);
if( src == NULL )
{
cout<<" can not load the image: "<<img_path[i].c_str()<<endl;
continue;
}
cout<<" processing "<<img_path[i].c_str()<<endl;
cvResize(src,trainImg); //读取图片
// cvSaveImage("./woshinibaba.bmp",trainImg);
cout<<"HOG dims: "<<descriptors.size()<<endl;
vector<Point> locations;
locations.push_back(Point(0,0));
// cout<<locations.size();
// hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0), locations);
// hog->compute(trainImg, descriptors,Size(1,1), Size(0,0));
cout<<"HOG dims: "<<descriptors.size()<<endl;
//CvMat* SVMtrainMat=cvCreateMat(descriptors.size(),1,CV_32FC1);
n=0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(data_mat,i,n,*iter);//把HOG存储下来
n++;
}
//cout<<SVMtrainMat->rows<<endl;
cvmSet( res_mat, i, 0, img_catg[i] );
//{
// vector<float>().swap(descriptors); //释放vector内存
//}
cout<<" end processing "<<img_path[i].c_str()<<" "<<img_catg[i]<<endl;
cvReleaseImage( &src );
src=NULL;
}
CvSVM svm = CvSVM();//新建一个SVM
CvSVMParams param;//这里是参数
CvTermCriteria criteria;
criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
// original: param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 5, 0.5, 1.0, NULL, criteria );
// SVM种类:CvSVM::C_SVC
// Kernel的种类:CvSVM::RBF
// degree:10.0(此次不使用)
// gamma:8.0
// coef0:1.0(此次不使用)
// C:10.0
// nu:0.5(此次不使用)
// p:0.1(此次不使用)
// 然后对训练数据正规化处理,并放在CvMat型的数组里。
//☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆
svm.train( data_mat, res_mat, NULL, NULL, param );//训练啦
//☆☆利用训练数据和确定的学参数,进行SVM学习☆☆☆☆
svm.save( "SVM_DATA.xml" );*/
//5.利用训练好的分类器进行测试
//检测样本
///my vararible wdy:
///
string buf;
HOGDescriptor *hog=new HOGDescriptor(cvSize(28,28),cvSize(12,12),cvSize(8,8),cvSize(3,3),9);
vector<float>descriptors;//结果数组
int n;
string imagename = "000.bmp";
string path;
///my vararible wdy:
///
// IplImage *test;
vector<string> img_tst_path;
std::ifstream img_tst( "train_list.txt" );//同输入训练样本,这里也是一样的,只不过不需要标注图片属于哪一类了
//std::ifstream img_tst( "temptest.txt" );
while( img_tst )
{
if( getline( img_tst, buf ) )
{
img_tst_path.push_back( buf );
}
}
img_tst.close();
CvMat *test_hog = cvCreateMat( 1, 1296, CV_32FC1 );//注意这里的1764,同上面一样
CvMat* SVMtrainMat;
// char line[512];
// ofstream predict_txt( "svmPredict.txt" );//把预测结果存储在这个文本中
CvSVM svm_hog;
svm_hog.load("SVM_DATA.xml");
for( string::size_type j = 0; j != img_tst_path.size(); j++ )//依次遍历所有的待检测图片
{
int MatchNums=0;
// path=".\\TestData\\"+img_tst_path[j];
path=img_tst_path[j];
// test = cvLoadImage(path.c_str(), 1);
cv::Mat img = cv::imread(path.c_str());
// cv::resize(img3,img,cv::Size(img3.rows,img3.cols));
cv::Mat imgClone=cv::imread(path.c_str());
if( !img.data )
{
cout<<" can not load the image: "<<img_tst_path[j].c_str()<<endl;
continue;
}
int m,n2,iii,jjj;
m = (img.rows-28)/15;
n2 = (img.cols-28)/15;
int times=0;
for (jjj = 0;jjj<m;jjj++)
for(iii = 0;iii<n2;iii++)
{
times++;
// if(times==59)
// times=times;
cv::Mat temImage(28,28,CV_8UC3,cv::Scalar(0,0,0));
cv::Mat imageROI = img(cv::Rect(iii*15,jjj*15,temImage.cols,temImage.rows));//rect(x, y, width, height)选定感兴趣区域
cv::addWeighted(temImage,1.0,imageROI,1.0,0.,temImage);//复制扫描出的边界内数据
IplImage trainImg(temImage);
// cvZero(trainImg);
// cvResize(test,trainImg); //读取图片
//vector<float>descriptors;//结果数组
vector<Point> locations;
locations.push_back(Point(0,0));
hog->compute(&trainImg, descriptors,Size(1,1), Size(0,0),locations); //调用计算函数开始计算
cout<<"HOG dims: "<<descriptors.size()<<endl;
if (j==0)
{
SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1);
cvSetZero( SVMtrainMat );
}
n=0;
for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
cvmSet(SVMtrainMat,0,n,*iter);
n++;
}
int ret = svm_hog.predict(SVMtrainMat);//获取最终检测结果,这个predict的用法见 OpenCV的文档
//std::sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
//printf("times:%d pic: %s label %d\r\n", times,img_tst_path[j].c_str(), ret );
if(ret==1)
{
for(int ii=0;ii<=0;ii++)
for(int jj=0;jj<=27;jj++)
{
imgClone.at<cv::Vec3b>(jjj*15+jj,iii*15+ii)[1]=255;
//printf("for 1,x:%d,y:%d\n",iii*5+ii,jjj*5+jj);
}
for(int ii=27;ii<=27;ii++)
for(int jj=0;jj<=27;jj++)
{
imgClone.at<cv::Vec3b>(jjj*15+jj,iii*15+ii)[1]=255;
//printf("for 2,x:%d,y:%d\n",iii*5+ii,jjj*5+jj);
}
for(int jj=0;jj<=0;jj++)
for(int ii=0;ii<=27;ii++)
{
imgClone.at<cv::Vec3b>(jjj*15+jj,iii*15+ii)[1]=255;
//printf("for 3,x:%d,y:%d\n",iii*5+ii,jjj*5+jj);
}
for(int jj=27;jj<=27;jj++)
for(int ii=0;ii<=27;ii++)
{
imgClone.at<cv::Vec3b>(jjj*15+jj,iii*15+ii)[1]=255;
//printf("for 4,x:%d,y:%d\n",iii*5+ii,jjj*5+jj);
}
}
// predict_txt<<line;
// cvReleaseImage( &test );
// test=NULL;
}
//printf("test is finished\n");
cv::imwrite(path.c_str(),imgClone);
}
// predict_txt.close();
}
标签:
原文地址:http://www.cnblogs.com/notlate/p/4179138.html