使用3*3的窗口提取LBP特征,处理之后的像素值还是从0~255的,直方图的bin应该有256个。后来Ojala提出了一个uniform pattern,意思是比如3x3的operator周围一圈有8个像素,和中间元素比较之后他们不是0就是1了,把他们看成一个圈,相邻的元素从0到1或者从1到0表示一个跳变,uniform pattern的指那种跳变不超过两个的pattern,比如0000000,11111111,00111110这些都是uniform pattern,有人统计说,LBP里面uniform pattern占到所有pattern元素的85%~90%,于是乎,在进行LBP处理之后,很多人就将uniform pattern作为处理的主要对象。在0~255这些二进制中uniform pattern有58个,剩余的198中pattern全部归为另一类,这样就构成了59维,使用直方图表示,共有59个bins。
在opencv中实现的代码入下:
const int uniformLBP[58]={0,1,2,3,4,6,7,8,12,14,15,16,24,28,30,31,32,48,56,60,62,63,64,
96,112,120,124,126,127,128,129,131,135,143,159,191,192,193,195,
199,207,223,224,225,227,231,239,240,241,243,247,248,249,251,252,
253,254,255};//unifor LBP算子01跳变次数小于等于2的值,即uniform pattern
void compute_uniformLBP(CvMat* src,vector<double>& vec_out)
{
map<int,int> myMap;
vector<int> myVec;
map<int,int>::iterator itMap;
vector<int>::iterator itVec;
int lastLBP=0;
int sumLBP=0;
int tmp[8]={0};
uchar *data=src->data.ptr;
int step=src->step;
for (int i=1;i<src->height-1;i++)
for(int j=1;j<src->width-1;j++)
{
int sum=0;
if(data[(i-1)*step+j-1]>data[i*step+j])
tmp[0]=1;
else
tmp[0]=0;
if(data[i*step+(j-1)]>data[i*step+j])
tmp[1]=1;
else
tmp[1]=0;
if(data[(i+1)*step+(j-1)]>data[i*step+j])
tmp[2]=1;
else
tmp[2]=0;
if (data[(i+1)*step+j]>data[i*step+j])
tmp[3]=1;
else
tmp[3]=0;
if (data[(i+1)*step+(j+1)]>data[i*step+j])
tmp[4]=1;
else
tmp[4]=0;
if(data[i*step+(j+1)]>data[i*step+j])
tmp[5]=1;
else
tmp[5]=0;
if(data[(i-1)*step+(j+1)]>data[i*step+j])
tmp[6]=1;
else
tmp[6]=0;
if(data[(i-1)*step+j]>data[i*step+j])
tmp[7]=1;
else
tmp[7]=0;
//计算LBP编码
sum=(tmp[0]*1+tmp[1]*2+tmp[2]*4+tmp[3]*8+tmp[4]*16+tmp[5]*32+tmp[6]*64+tmp[7]*128);
myMap[sum]++;
}
for (int i=0; i<58; i++)
{
myVec.push_back(myMap[uniformLBP[i]]);
sumLBP+=myMap[uniformLBP[i]];
myMap.erase(uniformLBP[i]);
}
for (itMap=myMap.begin(); itMap!=myMap.end(); itMap++)
{
lastLBP += itMap->second;
}//剩余的非uniform pattern归为一类
sumLBP+=lastLBP;
myVec.push_back(lastLBP);
for (itVec=myVec.begin(); itVec!=myVec.end(); itVec++)
{
vec_out.push_back(*itVec/double(sumLBP));
}//归一化处理,使用直方图进行表示,包含59个bins
}