zoukankan      html  css  js  c++  java
  • Opencv学习之路——自己编写的HOG算法

    #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();
            }
        }
    }
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/code-wangjun/p/5691078.html
Copyright © 2011-2022 走看看