Click here to Skip to main content
Click here to Skip to main content

Local Binary Pattern

By , 19 Jan 2014
Rate this:
Please Sign up or sign in to vote.

Introduction

  • In this article, we will look at the concept of Local Binary Pattern and computation of LBP image.
  • 2D surface texture is characterized by spatial pattern and intensity/contrast.
  • Spatial Pattern is affected by rotation, scale changes, hence for a good texture description we require a rotation and scale invariant descriptor.
  • Local binary pattern binarizes the local neighborhood of each pixel and builds a histogram on these binary neighborhood patterns.
  • Let P be the number of neighborhood pixels and R the distance from the center pixel $l_c$ and $l_p$ be neighborhood pixel.
  • A $LBP_{P,R}$ number characterizes the local texture by assigning the binomial factor $2^P$ for each sign $sgn(l_p-l_c)$ \[ LBP_{P,R} = \sum_{p=0}^{P-1} sgn(l_p - l_c) 2^p \]
  • $l_p$ for $p={0\ldots P-1}$ are a set of equally spaced pixels on a circle of radius $R$.
  • $LBP_{P,R}$ features has $2^P$ possible values.For P=8 we have a binary feature vector of length $256$.
  • Patterns are classified as uniform and non uniform.
  • Uniform patterns have single contiguous regions of 0 and 1 while non uniform patterns do not. For example, 01100000 is a uniform pattern while 01010000 is an example of non uniform pattern
  • We can see that there are 9 possible uniform pattern values
    0 0 0 0 0 0 0 0
    1 0 0 0 0 0 0 0
    1 1 0 0 0 0 0 0
    1 1 1 0 0 0 0 0
    1 1 1 1 0 0 0 0
    1 1 1 1 1 0 0 0
    1 1 1 1 1 1 0 0
    1 1 1 1 1 1 1 0
    1 1 1 1 1 1 1 1
  • Now consider the effect of rotation on the feature vector.
  • Rotating the image results in circular shift of values of feature vector.
  • To incorporate rotational invariance, we need to assign all possible rotations of a feature vector to a single LBP value. For example, all the below patterns
    1 0 0 0 0 0 0 0
    0 1 0 0 0 0 0 0
    0 0 1 0 0 0 0 0
    0 0 0 1 0 0 0 0
    0 0 0 0 1 0 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 0 0 1 0
    0 0 0 0 0 0 0 1
    \\ will be assigned to a single value.
  • In the present article however, we are not considering rotational invariant features
  • Let us consider the implementation details of LBP
  • If we only consider a 3x3 neighborhood, we need to threshold the rectangular region about
  • Another method would be to divide image into square blocks of size BxB. Instead of central pixel value, we consider the mean value of pixels in the central block.
  • Similarly, instead of considering the single pixel value in the neighborhood, we would consider the mean value of pixels in the block.
  • All the pixels in the block are encoded with the same binary value 0 or 1.
  • To compute mean value over rectangular regions of image, integral images are used.
  • The output of lbp images for block size 1,2 and 8 is showing in figure f1
    LBP Images
    f1
  • We can see that as block size increases, quantization effects can be seen and the information in the encoded image cannot be recognized.

     <![CDATA[       
                     #include "ImgFeatures/integralImage.h" 
                     class LBPFeatures 
                     { 
                     public:     LBPFeatures(){};     
                     Mat image;     
                     vector<uchar> features;     
                     Mat mask;     
                     IntegralImage ix; //function to compute LBP image with block size 1     
                     void compute(Mat image,Mat &dst)     
                     {         
                     uchar *ptr=image.data;         
                     image.copyTo(dst);         
                     uchar *optr=dst.data;         
                     int width=image.cols;         
                     int height=image.rows;          
                     for(int i=1;i<height-1;i++) 
                     code|="((int)ptr[(j-1)+(i-1)*width]" 
                     code="0;" 
                     center="(int)ptr[j+i*width];" 
                     j="0;j<width-1;j++)">=center)<<7 ;                 
                     code|=((int)ptr[j+(i-1)*width] >=center)<<6 ;                 
                     code|=((int)ptr[(j+1)+(i-1)*width] >=center)<<5 ;                 
                     code|=((int)ptr[(j+1)+(i)*width] >=center)<<4 ;                 
                     code|=((int)ptr[(j+1)+(i+1)*width] >=center)<<3 ;                 
                     code|=((int)ptr[j+(i+1)*width] >=center)<<2 ;                 
                     code|=((int)ptr[j-1+(i+1)*width] >=center)<<1 ;                 
                     code|=((int)ptr[j-1+(i)*width] >=center)<<0 ;                 
                     optr[j+i*width]=code;             
                     }         
                     }      
                     }      //computing integral image for block     
                     void computeBlock(Mat image,Mat & dst,int block=2)     
                     {  //computing integral image         
                     ix.compute(image);         
                     image.copyTo(dst);         
                     dst.setTo(cv::Scalar::all(0));         
                     int width=image.cols;         
                     int height=image.rows;         
                     for(int i=block;i<height-block;i=i+block) 
                     code|="(meanv" code="0;" 
                     j="block;j<width-block;j=j+block)" 
                     val="(int)ix.calcMean(r1);" r1="Rect(x,y,block,block);" 
                     x="i;" y="j;" k="0;k<8;k++)" 
                     meanv="ix.calcMean(r);" 
                     r="Rect(j,i,block,block);">= val)<<(7-k);                  
                     }                 
                     Mat roi=dst(r);                 //setting value of all pixel in output                 
                     //image to the encoded value for visualization                 
                     roi.setTo(cv::Scalar::all(code));             
                     }         
                     }       
                     }  
                     }; 
  • The code for the same can be found in the git repo for OpenVisionLibrary https://github.com/pi19404/OpenVision/ in the following files ImgFeatures/lbpfeatures.hpp and lbpFeatures.cpp.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

pi19404
Student IIT Bombay
India India
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 19 Jan 2014
Article Copyright 2014 by pi19404
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid