Local Binary
Pattern
Pi19404
January 18, 2014
Contents
Contents
Local Binary Pattern
2|8
Local Binary Pattern
Local Binary Pattern
In this article we will look at concept of Local Binary Pattern
and computation of LBP image.
2D surface texture is characterize 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 and l be neighborhood pixel.
c
A LBP
number characterizes the local texture by assigning
the binomial factor 2 for each sign sgn(l
l )
P;R
LBPP;R
lp
LBPP;R
for p = 0 : : : P
of radius R.
1
sgn(lp
lc )2
=0
are a set of equally spaced pixels on a circle
P
features has 2 possible [Link] P=8 we have a binary
feature vector of length 256.
Patterns are classified as uniform and non uniform.
Uniform pattern have single contigious regions of 0 and 1 while
non uniform patterns do [Link] example 01100000 is a uniform pattern while 01010000 is a example of non uniform
pattern
3|8
Local Binary 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 encorporate rotational invariance we need to assign all possible rotation 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 [Link] of central pixel value we consider the mean
value of pixels in the central block.
Similariy 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.
4|8
Local Binary Pattern
to compute mean value over rectangular regions of image,integral
images are used.
output of lbp images for block size 1,2 and 8 is showing in figure
1
Figure 1: LBP Images
1
2
we can see that as block size increases,quantization effects can
be seen and the information in the encoded image cannot be
recognized.
nclude "ImgFeatures/integralImage.h"
ass LBPFeatures
3
4
5
6
7
8
9
blic:
LBPFeatures(){};
Mat image;
vector<uchar> features;
Mat mask;
IntegralImage ix;
10
11
12
13
14
15
16
17
//function to compute LBP image with block size 1
void compute(Mat image,Mat &dst)
{
uchar *ptr=[Link];
[Link](dst);
uchar *optr=[Link];
5|8
Local Binary Pattern
int width=[Link];
int height=[Link];
18
19
20
for(int i=1;i<height-1;i++)
{
for(int j=0;j<width-1;j++)
{
int center=(int)ptr[j+i*width];
unsigned char code=0;
code|=((int)ptr[(j-1)+(i-1)*width] >=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;
}
}
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//computing integral image for block
void computeBlock(Mat image,Mat & dst,int block=2)
{
/computing integral image
[Link](image);
[Link](dst);
[Link](cv::Scalar::all(0));
int width=[Link];
int height=[Link];
for(int i=block;i<height-block;i=i+block)
{
for(int j=block;j<width-block;j=j+block)
{
int x=i;
int y=j;
Rect r=Rect(j,i,block,block);
//computing mean value of central block
int meanv=[Link](r);
int code=0;
for(int k=0;k<8;k++)
{
6|8
Local Binary Pattern
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//offsets of neighbouring values
switch(k)
{
case 0:
y=i-block;
x=j-block;
break;
case 1:
y=i;
x=j-block;
break;
case 2:
y=i+block;
x=j-block;
break;
case 3:
y=i+block;
x=j;
break;
case 4:
y=i+block;
x=j+block;
break;
case 5:
y=i;
x=j+block;
break;
case 6:
y=i-block;
x=j+block;
break;
case 7:
y=i-block;
x=j;
break;
default:
break;
}
Rect r1=Rect(x,y,block,block);
//computing mean value of neighbouring block
int val=(int)[Link](r1);
code|=(meanv >= val)<<(7-k);
104
105
7|8
Local Binary Pattern
106
107
108
109
110
111
Mat roi=dst(r);
//setting value of all pixel in output
//image to the encoded value for visualization
[Link](cv::Scalar::all(code));
112
113
114
115
116
the code for the same can be found in the git repo for OpenVisionLibrary [Link] in following
files ImgFeatures/[Link] and [Link] files
8|8