#include<opencv2corecore.hpp> #include<opencv2highguihighgui.hpp> #include<opencv2opencv.hpp> #include<iostream> #include<fstream> using namespace std; using namespace cv; #define Max 100 class Cell{ private: int pixel_x; //cell的像素的起始位置行坐标; int pixel_y; //cell的像素的起始位置纵坐标; Mat img; //待处理的图像,通常该该图像是经过Gamma校正的灰度图; double pixel[10][10]; //我们一般默认cell为8*8的像素大小,但是为了储存周边店的像素,需要多加两个像素储存点的位置; double gradient_M[9][9]; //保存梯度的幅值; double gradient_Angle[9][9]; //保存像素梯度的方向; double gradient_h[9][9]; double gradient_v[9][9]; public: double bin[9]; //将梯度方向分成九个方向,在根据具体像素梯度的方向大小,进行投票; Cell(Mat src){ //构造函数; img=src; } void Set_Cell(int x,int y); void Get_Pixel(); //为了计算机使用方便,我们把一个cell当中的像素先读下来,用pixel[][]数组储存; void Gradient_Pixel(); //计算机图像像素的梯度幅值和梯度角度; void Bin_Selection_Normalization(); //根据每个像素的幅值进行维度的区分和归一化,并且返回bin[]数组; }; void Cell::Set_Cell(int x,int y){ pixel_x=x; pixel_y=y; } void Cell::Get_Pixel(){ for(int i=pixel_x-1,m=0;i<pixel_x+9;i++,m++){ uchar *data=img.ptr<uchar>(i); for(int j=pixel_y-1,n=0;j<pixel_y+9;j++,n++){ pixel[m][n]=data[j]; } } // for(int i=0;i<9;i++){ // for(int j=0;j<9;j++){ // cout<<i<<j<<" "<<pixel[i][j]<<" "; // } // } } void Cell::Gradient_Pixel(){ for(int i=1;i<9;i++){ for(int j=1;j<9;j++){ gradient_h[i][j]=pixel[i+1][j]-pixel[i-1][j]; gradient_v[i][j]=pixel[i][j+1]-pixel[i][j-1]; gradient_M[i][j]=sqrt(gradient_h[i][j]*gradient_h[i][j]+gradient_v[i][j]*gradient_v[i][j]); gradient_Angle[i][j]=atan2(gradient_h[i][j],gradient_v[i][j])*180; } } // for(int i=0;i<9;i++){ // for(int j=0;j<9;j++){ // cout<<i<<j<<" "<<gradient_h[i][j]<<" "<<gradient_v[i][j]<<" "<<gradient_M[i][j]<<" "<<gradient_Angle[i][j]<<" "; // } // } } void Cell::Bin_Selection_Normalization(){ for(int i=0;i<9;i++){ bin[i]=0; } for(int i=1;i<9;i++){ for(int j=1;j<9;j++){ if((gradient_Angle[i][j]>=0&&gradient_Angle[i][j]<20)||(gradient_Angle[i][j]>=180&&gradient_Angle[i][j]<200)){ bin[0]=bin[0]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=20&&gradient_Angle[i][j]<40)||(gradient_Angle[i][j]>=200&&gradient_Angle[i][j]<220)){ bin[1]=bin[1]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=40&&gradient_Angle[i][j]<60)||(gradient_Angle[i][j]>=220&&gradient_Angle[i][j]<240)){ bin[2]=bin[2]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=60&&gradient_Angle[i][j]<80)||(gradient_Angle[i][j]>=240&&gradient_Angle[i][j]<260)){ bin[3]=bin[3]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=80&&gradient_Angle[i][j]<100)||(gradient_Angle[i][j]>=260&&gradient_Angle[i][j]<280)){ bin[4]=bin[4]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=100&&gradient_Angle[i][j]<120)||(gradient_Angle[i][j]>=280&&gradient_Angle[i][j]<300)){ bin[5]=bin[5]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=120&&gradient_Angle[i][j]<140)||(gradient_Angle[i][j]>=300&&gradient_Angle[i][j]<320)){ bin[6]=bin[6]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=140&&gradient_Angle[i][j]<160)||(gradient_Angle[i][j]>=320&&gradient_Angle[i][j]<340)){ bin[7]=bin[7]+gradient_M[i][j]; } if((gradient_Angle[i][j]>=160&&gradient_Angle[i][j]<=180)||(gradient_Angle[i][j]>=340&&gradient_Angle[i][j]<=360)){ bin[8]=bin[8]+gradient_M[i][j]; } } } //////////////////////////////////// //归一化; double sum_bin=0; for(int i=0;i<9;i++){ sum_bin=sum_bin+bin[i]; } for(int i=0;i<9;i++){ bin[i]=bin[i]/sum_bin; if(bin[i]>0.2){ bin[i]=0.2; } } sum_bin=0; for(int i=0;i<9;i++){ sum_bin=sum_bin+bin[i]; } for(int i=0;i<9;i++){ bin[i]=bin[i]/sum_bin; } } //Block类部分**************** class Block{ int block_pixel_x; //block的起始像素点横坐标位置; int block_pixel_y; //block的起始像素点纵坐标位置; Mat src; //图像必须是灰度图; double bins[38]; //该类主要是对block进行相关处理,我们默认block为四个cell,即2*2;所以bins为36维; int k; public: Block(Mat img){ src=img; k=0; } void Set_Block(int x,int y); void Cut_Block(); //本人认为这是整个算法当中比较重要的一部分,即图像切割划分部分; void Block_into_HistImage(); void output_bins(); }; void Block::Set_Block(int x,int y){ block_pixel_x=x; block_pixel_y=y; } void Block::Cut_Block(){ k=0; Cell cell(src); for(int i=block_pixel_x, m=0;m<2;i=i+8,m++){ for(int j=block_pixel_y, n=0;n<2;j=j+8,n++){ cell.Set_Cell(i,j); cell.Get_Pixel(); cell.Gradient_Pixel(); cell.Bin_Selection_Normalization(); for(int i=0;i<9;i++){ bins[k++]=cell.bin[i]; } } } } void Block::Block_into_HistImage(){ //该部分算法是将bins生成直方图; int hight=256; int width=80; IplImage *hist_image=cvCreateImage(Size(80,256),8,3); for(int i=0;i<36;i++){ cvRectangle(hist_image,CvPoint(i*2,hight-1),CvPoint((i+1)*2-1,hight-bins[i]*100),CV_RGB(255,255,255)); } cvNamedWindow("1",1); cvShowImage("1",hist_image); cvWaitKey(0); } void Block::output_bins(){ //ofstream out ("1.txt"); for(int i=0;i<36;i++){ cout<<bins[i]<<" "; } cout<<"******************************************* "; } int main(){ Mat img=imread("G:/2.png",1); //载入图片; if(img.empty()) { return -1; } Mat gray1; Mat gray; cvtColor(img,gray1,COLOR_RGB2GRAY); resize(gray1,gray,Size(130,66),0,0,1); namedWindow("gray",1); imshow("gray",gray); // cvWaitKey(0); Block block(gray); for(int i=1,m=0;m<7;m++,i=i+8){ for(int j=1,n=0;n<15;n++,j=j+8){ block.Set_Block(i,j); block.Cut_Block(); //block.Block_into_HistImage(); block.output_bins(); } } }