上学期,投出去一篇论文,关于表情识别的,结果被拒了。我的主要任务在于提取最佳表征人脸表情的特征,这里采用了Gabor特征,提取多尺度,多方向的Gabor特征,然后在用DCT来降维,环境采用vc做的。
论文反馈意见。
意见:
1)论文创新性不足。分块对图像进行处理的思想以及Gabor小波理论已经非常成熟,而论文并没有对其进行实质性的改进。
2)分块的数量和大小直接会影响到算法的效能。论文中为何将预处理后的面部图像平均分为上下两个部分而不用其他的分割方法?
3)论文缺乏对算法实时性和内存占用量的分析。
4)部分参考文献格式不规范(参考文献2、4未标明页码范围;参考文献2、5、10未标明文献类型)。
经过暑假的实习,上学期做实验的过程,已经生疏,再次回顾一下先,把实验捋顺了,然后在找突破口修改实验方案。
首先利用一段程序来得到
Gabor.h
#ifndef CVGABOR_H #define CVGABOR_H #include <iostream> #include <cv.h> #include <highgui.h> #define PI 3.14159265 #define CV_GABOR_REAL 1 //实部 #define CV_GABOR_IMAG 2 //虚部 #define CV_GABOR_MAG 3 //模 #define CV_GABOR_PHASE 4 //相位 //写成一个类:CvGabor class CvGabor { public: CvGabor(); //缺省构造函数 ~CvGabor(); //析构函数 //以下是重载构造函数 CvGabor(int iMu, int iNu, double dSigma); //参数分别代表:方向、尺度、带宽 CvGabor(int iMu, int iNu, double dSigma, double dF); CvGabor(double dPhi, int iNu);//dPhi:方向的弧度值 CvGabor(double dPhi, int iNu, double dSigma); CvGabor(double dPhi, int iNu, double dSigma, double dF); bool IsInit(); long mask_width();//操作掩膜宽度 IplImage* get_image(int Type); bool IsKernelCreate(); long get_mask_width(); void Init(int iMu, int iNu, double dSigma, double dF); void Init(double dPhi, int iNu, double dSigma, double dF); void output_file(const char *filename, int Type); CvMat* get_matrix(int Type); void show(int Type); void conv_img(IplImage *src, IplImage *dst, int Type); CvGabor(int iMu, int iNu); void normalize( const CvArr* src, CvArr* dst, double a, double b, int norm_type, const CvArr* mask ); void conv_img_a(IplImage *src, IplImage *dst, int Type); //void DCTtransform(IplImage* image,IplImage** dst); protected: double Sigma; //小波滤波器的带宽 double F; //频率中内核间隔因子 double Kmax; //最大频率 double K; //Kmax/F K = Kmax / pow(F, (double)iNu) double Phi; //相位 bool bInitialised; bool bKernel; long Width; CvMat *Imag; CvMat *Real; private: void creat_kernel(); }; #endif
Gabor.cpp
#include "cvgabor.h" //构造函数定义 CvGabor::CvGabor() { } //析构函数定义 CvGabor::~CvGabor() { cvReleaseMat( &Real );//实部 cvReleaseMat( &Imag );//虚部 } CvGabor::CvGabor(int iMu, int iNu, double dSigma) { F = sqrt(2.0); Init(iMu, iNu, dSigma, F); } CvGabor::CvGabor(int iMu, int iNu, double dSigma, double dF) { Init(iMu, iNu, dSigma, dF); } CvGabor::CvGabor(double dPhi, int iNu) { Sigma = 2*PI; F = sqrt(2.0); Init(dPhi, iNu, Sigma, F); } CvGabor::CvGabor(double dPhi, int iNu, double dSigma) { F = sqrt(2.0); Init(dPhi, iNu, dSigma, F); } CvGabor::CvGabor(double dPhi, int iNu, double dSigma, double dF) { Init(dPhi, iNu, dSigma,dF); } bool CvGabor::IsInit() { return bInitialised; } long CvGabor::mask_width() //加窗宽度? { long lWidth; if (IsInit() == false) { perror ("Error: The Object has not been initilised in mask_width()!\n"); return 0; } else { double dModSigma = Sigma/K; double dWidth = cvRound(dModSigma*6 + 1); if (fmod(dWidth, 2.0)==0.0) { dWidth++; } lWidth = (long)dWidth; return lWidth; } } void CvGabor::creat_kernel() //构建Gabor内核 { if (IsInit() == false) { perror("Error: The Object has not been initilised in creat_kernel()!\n"); } else { CvMat *mReal, *mImag; mReal = cvCreateMat( Width, Width, CV_32FC1); mImag = cvCreateMat( Width, Width, CV_32FC1); /**************************** Gabor Function ****************************/ int x, y; double dReal; double dImag; double dTemp1, dTemp2, dTemp3; for (int i = 0; i < Width; i++) { for (int j = 0; j < Width; j++) { x = i-(Width-1)/2; y = j-(Width-1)/2; dTemp1 = (pow(K,2)/pow(Sigma,2))*exp(-(pow((double)x,2)+pow((double)y,2))*pow(K,2)/(2*pow(Sigma,2))); dTemp2 = cos(K*cos(Phi)*x + K*sin(Phi)*y) - exp(-(pow(Sigma,2)/2)); dTemp3 = sin(K*cos(Phi)*x + K*sin(Phi)*y); dReal = dTemp1*dTemp2; dImag = dTemp1*dTemp3; cvSetReal2D((CvMat*)mReal, i, j, dReal ); cvSetReal2D((CvMat*)mImag, i, j, dImag ); } } /**************************** Gabor Function ****************************/ bKernel = true; cvCopy(mReal, Real, NULL); cvCopy(mImag, Imag, NULL); cvReleaseMat( &mReal ); cvReleaseMat( &mImag ); } } IplImage* CvGabor::get_image(int Type) //获取图片信息 { if(IsKernelCreate() == false) { perror("Error: the Gabor kernel has not been created in get_image()!\n"); return NULL; } else { IplImage* pImage; IplImage *newimage; newimage = cvCreateImage(cvSize(Width,Width), IPL_DEPTH_8U, 1 ); pImage = cvCreateImage( cvSize(Width,Width), IPL_DEPTH_32F, 1 ); CvMat* kernel = cvCreateMat(Width, Width, CV_32FC1); CvMat* re = cvCreateMat(Width, Width, CV_32FC1); CvMat* im = cvCreateMat(Width, Width, CV_32FC1); double ve, ve1,ve2; CvSize size = cvGetSize( kernel ); int rows = size.height; int cols = size.width; switch(Type) { case 1: //Real cvCopy( (CvMat*)Real, (CvMat*)kernel, NULL ); //pImage = cvGetImage( (CvMat*)kernel, pImageGL ); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { ve = cvGetReal2D((CvMat*)kernel, i, j); cvSetReal2D( (IplImage*)pImage, j, i, ve ); } } break; case 2: //Imag cvCopy( (CvMat*)Imag, (CvMat*)kernel, NULL ); //pImage = cvGetImage( (CvMat*)kernel, pImageGL ); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { ve = cvGetReal2D((CvMat*)kernel, i, j); cvSetReal2D( (IplImage*)pImage, j, i, ve ); } } break; case 3: //Magnitude //add by yao cvCopy( (CvMat*)Real, (CvMat*)re, NULL ); cvCopy( (CvMat*)Imag, (CvMat*)im, NULL ); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { ve1 = cvGetReal2D((CvMat*)re, i, j); ve2 = cvGetReal2D((CvMat*)im, i, j); ve = cvSqrt(ve1*ve1+ve2*ve2); cvSetReal2D( (IplImage*)pImage, j, i, ve ); } } break; case 4: //Phase ///@todo break; } cvNormalize((IplImage*)pImage, (IplImage*)pImage, 0, 255, CV_MINMAX, NULL ); cvConvertScaleAbs( (IplImage*)pImage, (IplImage*)newimage, 1, 0 ); cvReleaseMat(&kernel); cvReleaseImage(&pImage); return newimage; } } bool CvGabor::IsKernelCreate() { return bKernel; } long CvGabor::get_mask_width() { return Width; } void CvGabor::Init(int iMu, int iNu, double dSigma, double dF) //初始化Gabor { bInitialised = false; bKernel = false; Sigma = dSigma; F = dF; Kmax = PI/2; K = Kmax / pow(F, (double)iNu); Phi = PI*iMu/8; bInitialised = true; Width = mask_width(); Real = cvCreateMat( Width, Width, CV_32FC1); Imag = cvCreateMat( Width, Width, CV_32FC1); creat_kernel(); } void CvGabor::Init(double dPhi, int iNu, double dSigma, double dF) { bInitialised = false; bKernel = false; Sigma = dSigma; F = dF; Kmax = PI/2; K = Kmax / pow(F, (double)iNu); Phi = dPhi; bInitialised = true; Width = mask_width(); Real = cvCreateMat( Width, Width, CV_32FC1); Imag = cvCreateMat( Width, Width, CV_32FC1); creat_kernel(); } CvMat* CvGabor::get_matrix(int Type) //获取矩阵图像 { if (!IsKernelCreate()) { perror("Error: the gabor kernel has not been created!\n"); return NULL; } switch (Type) { case CV_GABOR_REAL: return Real; break; case CV_GABOR_IMAG: return Imag; break; case CV_GABOR_MAG: return NULL; break; case CV_GABOR_PHASE: return NULL; break; default: return NULL; } } void CvGabor::output_file(const char *filename, int Type) //输出的图像文件 { IplImage *pImage; pImage = get_image(Type); if(pImage != NULL) { if( cvSaveImage(filename, pImage )) { printf("%s has been written successfully!\n", filename); } else { printf("Error: writting %s has failed!\n", filename); } } else { perror("Error: the image is empty in output_file()!\n"); } cvReleaseImage(&pImage); } void CvGabor::show(int Type) { if(!IsInit()) { perror("Error: the gabor kernel has not been created!\n"); } } CvGabor::CvGabor(int iMu, int iNu) { double dSigma = 2*PI; F = sqrt(2.0); Init(iMu, iNu, dSigma, F); } void CvGabor::conv_img(IplImage *src, IplImage *dst, int Type) { double ve; CvMat *mat = cvCreateMat(src->width, src->height, CV_32FC1); for (int i = 0; i < src->width; i++) //将传进来的图像RGB信息赋值给矩阵mat { for (int j = 0; j < src->height; j++) { ve = CV_IMAGE_ELEM(src, uchar, j, i); CV_MAT_ELEM(*mat, float, i, j) = (float)ve; } } CvMat *rmat = cvCreateMat(src->width, src->height, CV_32FC1); CvMat *imat = cvCreateMat(src->width, src->height, CV_32FC1); switch (Type) { case CV_GABOR_REAL: cvFilter2D( (CvMat*)mat, (CvMat*)mat, (CvMat*)Real, cvPoint( (Width-1)/2, (Width-1)/2));//卷积运算 break; case CV_GABOR_IMAG: cvFilter2D( (CvMat*)mat, (CvMat*)mat, (CvMat*)Imag, cvPoint( (Width-1)/2, (Width-1)/2)); break; case CV_GABOR_MAG://求模 cvFilter2D( (CvMat*)mat, (CvMat*)rmat, (CvMat*)Real, cvPoint( (Width-1)/2, (Width-1)/2)); cvFilter2D( (CvMat*)mat, (CvMat*)imat, (CvMat*)Imag, cvPoint( (Width-1)/2, (Width-1)/2)); cvPow(rmat,rmat,2); //实部平方 cvPow(imat,imat,2); //虚部平方 cvAdd(imat,rmat,mat);//实部和虚部的平方和 cvPow(mat,mat,0.5); //实部和虚部的平方和开方后得到模值 break; case CV_GABOR_PHASE: break; } if (dst->depth == IPL_DEPTH_8U) { cvNormalize((CvMat*)mat, (CvMat*)mat, 0, 255, CV_MINMAX); for (int i = 0; i < mat->rows; i++) { for (int j = 0; j < mat->cols; j++) { ve = CV_MAT_ELEM(*mat, float, i, j); CV_IMAGE_ELEM(dst, uchar, j, i) = (uchar)cvRound(ve); } } } if (dst->depth == IPL_DEPTH_32F) { for (int i = 0; i < mat->rows; i++) { for (int j = 0; j < mat->cols; j++) { ve = cvGetReal2D((CvMat*)mat, i, j); cvSetReal2D( (IplImage*)dst, j, i, ve ); } } } cvReleaseMat(&imat); cvReleaseMat(&rmat); cvReleaseMat(&mat); //output_file(const char *filename, int Type) //output_file("c:\123.jpg", 1); }
这两个文件是Gabor变换的头文件和实现文件
下面这段程序是DCT变换的C语言实现
#include "targetver.h" #include <stdio.h> #include <tchar.h> #include"cvgabor.h" #include "stdafx.h" #include "zigzag.h" using namespace std; vector<double> DCTtransform(IplImage* image) { CvMat* OldMat=cvCreateMat(image->height,image->width,CV_32FC1); //原矩阵 CvMat* Mat=cvCreateMat(image->width,image->height,CV_32FC1); //因为特征信息是以列向量存储的,所以要将矩阵进行转置,这个矩阵为转置之后的矩阵 CvMat* DCT=cvCreateMat(image->width,image->height,CV_32FC1); //DCT变换后的矩阵,用DCT变换要保证图像的高和宽都要为偶数 cvConvert(image, OldMat); //将源图像内容赋值给矩阵(Mat)cvSacle cvTranspose(OldMat,Mat); //转置操作 cvDCT(Mat,DCT, CV_DXT_FORWARD); //对矩阵进行DCT变化,结果在矩阵DCT中 //cvWaitKey(0); //将DCT变换的矩阵结果通过ZigZag算法,取其前100位,实现DCT降维 unsigned int width = DCT->cols; unsigned int height =DCT->rows; double * orig = new double[height*width]; int i1 = 0; for( int y=0;y<DCT->rows;++y) //取矩阵值 { for(int x=0;x<DCT->cols;++x) { *(orig + i1) = cvmGet(DCT,y,x); i1++; } } double * zigzagVector = new double[width*height]; memset(zigzagVector , 0 ,sizeof(float) * width*height); ZigZag(orig,width,height,zigzagVector); //ZigZag变换 vector<double> vec; //ZigZag之后的完整向量 vector<double> vec1; //截取前100位的向量 for(unsigned int i = 0; i < height; ++i) { for(unsigned int j = 0;j < width;++j) { if(vec.size()<=150) { vec.push_back(*(zigzagVector + i * height +j)); } else vec.push_back(0); } } for(vector<double>::size_type i = 0; i <200; ++i) { vec1.push_back(vec[i]); } cvReleaseMat(&DCT); //释放内存空间 cvReleaseMat(&Mat); delete orig; delete zigzagVector; return vec1; } vector<double> DCTtransform_mat(CvMat* image_mat) { CvMat *OldMat = image_mat; CvMat* Mat=cvCreateMat(image_mat->width,image_mat->height,CV_32FC1); //因为特征信息是以列向量存储的,所以要将矩阵进行转置,这个矩阵为转置之后的矩阵 CvMat* DCT=cvCreateMat(image_mat->width,image_mat->height,CV_32FC1); //DCT变换后的矩阵,用DCT变换要保证图像的高和宽都要为偶数 cvConvert(image_mat, OldMat); //将源图像内容赋值给矩阵(Mat)cvSacle cvTranspose(OldMat,Mat); //转置操作 cvDCT(Mat,DCT, CV_DXT_FORWARD); //对矩阵进行DCT变化,结果在矩阵DCT中 //cvWaitKey(0); //将DCT变换的矩阵结果通过ZigZag算法,取其前100位,实现DCT降维 unsigned int width = DCT->cols; unsigned int height =DCT->rows; double * orig = new double[height*width]; int i1 = 0; for( int y=0;y<DCT->rows;++y) //取矩阵值 { for(int x=0;x<DCT->cols;++x) { *(orig + i1) = cvmGet(DCT,y,x); i1++; } } double * zigzagVector = new double[width*height]; memset(zigzagVector , 0 ,sizeof(float) * width*height); ZigZag(orig,width,height,zigzagVector); //ZigZag变换 vector<double> vec; //ZigZag之后的完整向量 vector<double> vec1; //截取前100位的向量 for(unsigned int i = 0; i < height; ++i) { for(unsigned int j = 0;j < width;++j) { if(vec.size()<=150) { vec.push_back(*(zigzagVector + i * height +j)); } else vec.push_back(0); } } for(vector<double>::size_type i = 0; i <100; ++i) { vec1.push_back(vec[i]); } cvReleaseMat(&DCT); //释放内存空间 cvReleaseMat(&Mat); delete orig; delete zigzagVector; return vec1; }
DCT变换的同时需要进行ZigZag变换
ZigZag.h
// Zigzag.h #ifndef _Zigzag_H #define _Zigzag_H #include <stdlib.h> #include <string.h> //******************************************************************************************* #ifdef __cplusplus extern "C" { #endif //******************************************************************************************** void ZigZag(double *DCTMatrix,int width,int height,double *zigzagVector); void iZigZag(float *zigzagVector,int width,int height,float* DCTMatrix);//inverse Zigzag! //******************************************************************************************** #ifdef __cplusplus } #endif //********************************************************************************************* #endif
zigzag.cpp
#include"zigzag.h" void ZigZag(double *DCTMatrix,int width,int height,double *zigzagVector) { int h = 1,v = 1; int vmin = 1,hmin = 1; int vmax = height, hmax = width; //vertical, horizontal int i; memset(zigzagVector, 0, sizeof(float) * height * width ); i=1; while(v<=vmax && h<=hmax) { if((h+v)%2==0) { if(v==vmin) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); if(h==hmax) { v=v+1; } else { h=h+1; } i=i+1; } else if((h==hmax) && (v<vmax)) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); v=v+1; i=i+1; } else if((v>vmin) && (h<hmax)) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); v=v-1; h=h+1; i=i+1; } } else { if((v==vmax) && (h<=hmax)) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); h=h+1; i=i+1; } else if(h==hmin) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); if(v==vmax) h=h+1; else v=v+1; i=i+1; } else if((v<vmax) && (h>hmin)) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); v=v+1; h=h-1; i=i+1; } } if((v==vmax) && (h==hmax)) { zigzagVector[i-1]=*(DCTMatrix + width*(v-1) + h-1); break; } } }
下面这段程序是调用Gabor,获取Gabor特征,并且组成weka所需的格式,输出到文件中。
// GaborTest.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include "cvgabor.h" #include <fstream> #include <string> using namespace std; vector<double> DCTtransform(IplImage* image);//DCT变换函数,参数为源图像Gabor响应的模图像,返回值为降维后的前100位特征值 vector<double> DCTtransform_mat(CvMat* image_mat); int _tmain(int argc, _TCHAR* argv[]) { double Sigma = 2*PI; double F = sqrt(2.0); vector<double> v1[18]; //方向尺度一共6个组合,用于存储这18副图像转化出来的向量$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ int v1num; //v1数组的下标(数组的下标而不是向量的下标,这里v1是一个数组,每个元素都是向量) vector<double> v2; //最终的到得向量,18个组合衔接在一起的向量 char cn1[3]; char nn1[3]; string FileName; //每一次循环读取的路径名 char* p; //最终路径名,由于opencv只接受char*,因为opencv是基于标准C的 //@@@@@@@@@文件输出部分@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //ofstream file; //file.open("d:\\train\\arff\\test-6-3-2011-12-12.arff",ios_base::out); //file<<"@relation 'FER'"<<endl; //char *ch = new char; //for(int i=1;i<=100;i++) //{ // itoa(i,ch,10); // file<<"@attribute tezheng"+string(ch)+" real"<<endl; //} //file << "@data" << endl; //@@@@@@@@@文件输出部分@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CvvImage pSrcImg; IplImage *img = cvCreateImage( cvSize(pSrcImg.Width(), pSrcImg.Height()), IPL_DEPTH_8U, 1); int ClassE_num=0; int dimension=0; int num=1; //for(int classNum=0; classNum<=19; ++classNum)//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ for(int classNum=1; classNum<=1; ++classNum)//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ { //for(int SameClassNum=26; SameClassNum<=30; ++SameClassNum)//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ for(int SameClassNum=1; SameClassNum<=1; ++SameClassNum)//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ { itoa(SameClassNum,nn1,10); itoa(classNum,cn1,10); //FileName= string("E:\\Testphotos\\surprise\\test_")+cn1;//原始图片目录$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ FileName= string("C:\\Users\\user\\Desktop\\test原来\\test_")+cn1; FileName= FileName+"_"; FileName= FileName+ nn1; FileName= FileName+ string(".jpg");//.bmp->.jpg cout<<FileName<<endl; v1num=0;//将向量数组v1的下标清零 p = (char*)FileName.c_str();//string转char* pSrcImg.Load( p ,CV_LOAD_IMAGE_GRAYSCALE); img = pSrcImg.GetImage(); IplImage *reimg2 = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1); //创建Gabor变换后的图像指针 //********* char num_str[3]; //********* //for(int i=2;i<=4;++i)//方向参数 取三个(30度、60度、90度) for(int i=0;i<6;++i)//方向参数 取6个(0度,30度、60度、90度、120度、150度) { //for(int j=0;j<2;++j)//尺度参数 取两个(0、1) for(int j=0;j<3;++j)//尺度参数 取三个(0、1、2) { //////////////////////////////////////////////////////Gabor变换+降维/////////////////////////////////////////////////////////// CvGabor *gabor1 = new CvGabor(); //创建Gabor指针 gabor1->Init(i*PI/6, j, Sigma, F);//初始化Gabor滤波器 gabor1->conv_img(img, reimg2, CV_GABOR_MAG);//将Gabor滤波器与源图像进行卷积操作,取模 //***添加与2011年12月13日晚,想利用Matlab做PCA,所以在此处截断,把Gabor图像弄出来 //把Gabor特征暂存一下 itoa(num,num_str,10); string file; //file = string("E:\\Gabor2012surprise\\")+num_str; //Gabor滤波后的地址 file = string("C:\\Users\\user\\Desktop\\test原来\\")+num_str; file = file + string(".jpg"); cvSaveImage((char*)file.c_str(),reimg2); num++; //********************** v1[v1num]=DCTtransform(reimg2);//DCT降维获得 前100位的特征值 v1num++; delete gabor1; //释放Gabor指针 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } } cvReleaseImage(&reimg2); //释放模图像指针 /*2011年12月19日,注释这段 for(v1num=0;v1num<6;v1num++) { v2.insert(v2.end(),v1[v1num].begin(),v1[v1num].end());//将得到的6个向量连接起来,存在v2中 } dimension = v2.size(); ClassE[ClassE_num]=v2; ClassE_num++; */ // //将vector<double>数组转成普通数组 a[] // double a[30*1200]={0.0}; // int k=0; // for(vector<double>::size_type j=0; j < v2.size() ;++j) // { // a[k] = v2.at(j); // k++; // } //CvMat *image_mat = cvCreateMat(30,40,CV_32FC1); //cvSetData(image_mat,a,image_mat->step);//向矩阵中添加数据,a:是一个数组 //v2=DCTtransform_mat(image_mat); //for(int v2n=0;v2n<100;v2n++) //{ // file<<","<<v2[v2n];//将这个图像的18*100个特征值按SVM分类的训练数据格式要求存为TXT文件 //} //file<<endl; v2.clear();//将v2清零,以便下一副图像使用 } } cvReleaseImage(&img ); //将所有创建的图像释放 // delete ch; //file.close(); return 0; }