Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Pi19404
January 23, 2014
Contents
Contents
Uniform LBP Features and Spatial Histogram Computation
0.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.2 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 8 8
2|8
Uniform LBP features are considered as one which have only 2 contigious regions corresponding to 0s and 1s,while non uniform LBP have more than 1 contigious regions corresponding to 0s and 1s. This we need a mapping from which assign each on 28 possible codes to one of 58 encoded uniform LBP values. All the non uniform codes are assigned to a single values. The uniform LBPs can be viewed as corners,line,ramp gradient The non uniform LBPs are assumed to be irrelevant and can be ignored. A uniform binary pattern can be identified by performing a bit wise traversal and checking if number of bit transitions are atmost 2 . This is done by first circular right/left shifting the given code and performing XOR operation with the original code. Since we need to only consider 8 bit numbers ,we need perform circular shift and masking MSB for integers.
int rightshift(int num, int shift) { //right shift the number to right
3|8
//left shift numbers and mask the MSB for 8 bit number return (num >> shift) | ((num << (8 - shift)&0xFF));
Now number of bit operations is simply the number of set bits in the result The code for this can be as follows
int countSetBits(int code) { int count=0; while(code!=0) { if(code&&0x01) count++; code=code>>1; } return count; } bool checkUniform(int code) { int b = rightshift(code,1); int c = code ^ b; int count=countSetBits(c); if (count <=2) return true; else return false; }
the method to count bits is naive way and since we are using 8 bit words,it will take 8 iterations of the for loop. Brian Kernighans method performs this by going through as many iterations as set bits
int countSetBits(int code) { int count=0; int v=code; for(count=0;v;count++) { v&=v-1; //clears the LSB } return count; }
4|8
The result can be precomputed for possible input code to determine if a LBP is a uniform code or not. The next task is to map the LBP codes to one of 58 uniform codes. The encoding will be done along the rows as per the below figure
Since we known the possible input codes before hand,we can prepare a lookup table before hand to check if a uniform code or not Now if it is a uniform code we need to map it to one of possible 58 codes.
5|8
To do this we move from all numbers from 0 28 ,check if they are uniform and assign them to a one of 58 possible code. However we can see than
//3x3 neighborhood will have 8 neighborhood pixels //all non uniform codes are assigned to 59 void initUniform() { lookup.resize(255); int index=0; for(int i=0;i<=255;i++) { bool status=checkUniform(i); if(status==true) { lookup[i]=index; index++; } else { lookup[i]=59; } } }
Thus we modify the existing lbp image code to return only uniform lbp coded as destination lbp image by performing a simple lookup operations. Now next task is to compute a spatial histogram,the histogram may be computed over the entire image or dividing the image into grids
ocv::Histogram hist; //class for computing histogram vector<float> spatialHistogram(Mat lbpImage,Size grid) { //feature vector vector<float> histogram; histogram.resize(grid.width*grid.height*59); int width=lbpImage.cols/grid.width; int height=lbpImage.rows/grid.height; int cnt=0; //#pragma omp parallel for
6|8
for(int i=0;i<grid.height;i++) { for(int j=0;j<grid.width;j++) { Mat cell=lbpImage(Rect(j*width,i*height,width,height)); Mat cell_hist=computeHistogram(cell); Mat tmp_feature; //reshape the feature vector into 1 row cell_hist.reshape(1,1).convertTo(tmp_feature,CV_32FC1); float * ptr=tmp_feature.ptr<float>(0); for(int k=0;k<tmp_feature.cols;k++) { //if no LBP feature is found assing it a small value if(ptr[k]==0) ptr[k]=1/58; //update the histogram vector histogram[cnt*59+k]=ptr[k]; } cnt++; } } } return histogram;
The LBP spatial histogram can be used as a texture descriptor. However the LBP image is a gradient image in some sense,it encode information about different types of gradiants The LBP pattern can be used to identify isolated corners or flat region ( all 0 or 1) The LBP pattern can be used to identify corner a continuous run of 0 or 1 of length (5-8 and its rotated version) The LBP pattern can be used to identify a edge a continous run of 0 or 1(length 4 and rotated version ) The LBP pattern can be used to identify horizontal or vertical edge ( vertical/horizontal run of 0 and 1 ) The LBP pattern can be used to identiy a line end (1000000 and its rotated version) The LBP pattern with 2 continous 12 can be considered as a horizonal or vertical line
7|8
0.2 Code
The code for the same can be found at git rep https://github. com/pi19404/OpenVision/ in ImgFeatures/lbpfeatures.cpp and ImgFeatures/lbpfeatures.hpp files.
8|8