以每个个体的照片集为每个个体建立一个分类器
一、代码
#include <iostream>
#include <opencv2/opencv.hpp>
#define N_BINS 16
#define N_DIVS 3
#define N_PHOG N_DIVS*N_DIVS*N_BINS
#define BIN_RANGE (2*CV_PI)/N_BINS
using namespace cv;
using namespace std;
using namespace ml;
const string SF="D:\\code\\c\\opencv\\opencv_face_catch\\sample";
const string OF="D:\\code\\c\\opencv\\opencv_face_catch\\output";
const string TF="D:\\code\\c\\opencv\\opencv_face_catch\\sample\\main.txt";
char char_filename[1024];
int fsign[1010];
string change_int_to_char(int a);
void change_string_to_char(string s);
Mat hog(const Mat &Img);
int main()
{
FILE *fp;
change_string_to_char(TF);
fp=fopen(char_filename,"rb");
char file[24],tfile[24];
int id,tid,TFN,tTFN,sum=0,tsum=0;
string filename;
Mat img,img_gray,feature;
Ptr<SVM> svm =SVM::create();
int DescriptorDim;
Mat sampleFeatureMat;
Mat sampleLabelMat;
if(fp==NULL)
{
cout<<"打开失败"<<endl<<TF<<endl;
return 0;
}
while(fscanf(fp,"%d %s %d",&id,file,&TFN)!=EOF)
{
sum+=TFN;
}
fclose(fp);
fp=fopen(char_filename,"rb");
while(fscanf(fp,"%d %s %d",&id,file,&TFN)!=EOF)
{
if(fsign[id]||id==0)
continue;
fsign[id]=1;
Ptr<SVM> svm = SVM::create();
for(int i=1; i<=TFN; i++)
{
filename=SF+"\\"+file+"_"+change_int_to_char(id)+"\\"+change_int_to_char(i)+".jpg";
img=imread(filename,1);
if(img.empty())
{
cout<<"打开失败"<<endl<<filename<<endl;
return 0;
}
resize(img,img,Size(64,64));
cvtColor(img,img_gray,0);
feature=hog(img_gray);
if(i==1)
{
DescriptorDim = feature.cols;
sampleFeatureMat = Mat::zeros(sum, DescriptorDim, CV_32FC1);
sampleLabelMat = Mat::zeros(sum, 1, CV_32SC1);
}
for(int j = 0; j < DescriptorDim; j++)
sampleFeatureMat.at<float>(i - 1, j) = feature.at<float>(0, j);
sampleLabelMat.at<int>(i - 1, 0) = 1;
}
fclose(fp);
change_string_to_char(TF);
fp=fopen(char_filename,"rb");
tsum=0;
while(fscanf(fp,"%d %s %d",&tid,tfile,&tTFN)!=EOF)
{
if(tid!=id)
{
for(int i=1; i<=tTFN; i++)
{
filename=SF+"\\"+tfile+"_"+change_int_to_char(tid)+"\\"+change_int_to_char(i)+".jpg";
img=imread(filename,1);
if(img.empty())
{
cout<<"打开失败"<<endl<<filename<<endl;
return 0;
}
resize(img,img,Size(64,64));
cvtColor(img,img_gray,0);
feature=hog(img_gray);
for(int j = 0; j < DescriptorDim; j++)
sampleFeatureMat.at<float>(TFN+tsum+i - 1, j) = feature.at<float>(0, j);
sampleLabelMat.at<int>(TFN+tsum+i - 1, 0) = -1;
}
tsum+=tTFN;
}
}
fclose(fp);
svm->setType(SVM::Types::C_SVC);
svm->setKernel(SVM::KernelTypes::RBF);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 1000, 1e-6));
svm->train(sampleFeatureMat,SampleTypes::ROW_SAMPLE, sampleLabelMat);
cout<<file<<endl<<"sample:";
for(int i=1; i<=TFN; i++)
{
filename=SF+"\\"+file+"_"+change_int_to_char(id)+"\\"+change_int_to_char(i)+".jpg";
img=imread(filename,1);
if(img.empty())
{
cout<<"打开失败"<<endl<<filename<<endl;
return 0;
}
resize(img,img,Size(64,64));
cvtColor(img,img_gray,0);
feature=hog(img_gray);
cout<<svm->predict(feature)<<" ";
}
change_string_to_char(TF);
fp=fopen(char_filename,"rb");
cout<<endl<<"opp:";
tsum=0;
while(fscanf(fp,"%d %s %d",&tid,tfile,&tTFN)!=EOF)
{
if(tid!=id)
{
for(int i=1; i<=tTFN; i++)
{
filename=SF+"\\"+tfile+"_"+change_int_to_char(tid)+"\\"+change_int_to_char(i)+".jpg";
img=imread(filename,1);
if(img.empty())
{
cout<<"打开失败"<<endl<<filename<<endl;
return 0;
}
resize(img,img,Size(64,64));
cvtColor(img,img_gray,0);
feature=hog(img_gray);
cout<<svm->predict(feature)<<" ";
}
tsum+=tTFN;
}
}
fclose(fp);
cout<<endl;
filename=OF+"\\"+file+"_"+change_int_to_char(id)+".xml";
svm->save(filename);
svm.release();
sampleFeatureMat.release();
sampleLabelMat.release();
change_string_to_char(TF);
fp=fopen(char_filename,"rb");
}
fclose(fp);
return 0;
}
string change_int_to_char(int a)
{
string jpg="";
if(a==0)
{
return "0";
}
int b,t;
char c[10];
t=0;
while(a!=0)
{
b=a%10;
a/=10;
c[++t]=b+'0';
}
for(int i=t; i>=1; i--)
jpg+=c[i];
return jpg;
}
void change_string_to_char(string s)
{
long long unsigned int t=0;
while(t<s.size())
{
char_filename[t]=s[t];
t++;
}
char_filename[t]='\0';
return ;
}
Mat hog(const Mat &Img)
{
Mat Hog;
Hog = Mat::zeros(1, N_PHOG, CV_32FC1);
Mat Ix, Iy;
Sobel(Img, Ix, CV_16S, 1, 0, 3);
Sobel(Img, Iy, CV_16S, 0, 1, 3);
int cellx = Img.cols / N_DIVS;
int celly = Img.rows / N_DIVS;
int img_area = Img.rows * Img.cols;
for (int m = 0; m < N_DIVS; m++)
{
for (int n = 0; n < N_DIVS; n++)
{
for (int i = 0; i<cellx; i++)
{
for (int j = 0; j<celly; j++)
{
float px, py, grad, norm_grad, angle, nth_bin;
px = static_cast<float>(Ix.at<int16_t>((m*cellx) + i, (n*celly) + j));
py = static_cast<float>(Iy.at<int16_t>((m*cellx) + i, (n*celly) + j));
grad = static_cast<float>(std::sqrt(1.0*px*px + py*py));
norm_grad = grad / img_area;
angle = std::atan2(py, px);
if (angle < 0)
angle += 2 * CV_PI;
nth_bin = angle / BIN_RANGE;
Hog.at<float>(0, (m*N_DIVS + n)*N_BINS + static_cast<int>(angle)) += norm_grad;
}
}
}
}
for (int i = 0; i< N_DIVS*N_DIVS; i++)
{
float max = 0;
int j;
for (j = 0; j<N_BINS; j++)
{
if (Hog.at<float>(0, i*N_BINS + j) > max)
max = Hog.at<float>(0, i*N_BINS + j);
}
for (j = 0; j<N_BINS; j++)
Hog.at<float>(0, i*N_BINS + j) /= max;
}
return Hog;
}