LBP(Local binary pattern)是一个易理解且有效的局部图像特征,应用很广泛。在网上可以搜到一大把的LBP介绍,所以本博文就忽略了对其的介绍。直接附上代码,代码不难,只是希望对大家有用!如有错误和补充,欢迎提出,大家共同进步哈!
注意:下面代码仅为示例便利,牺牲了一些效率!
一)一般的LBP,256维
-
//====================================================================
-
// 作者 : quarryman
-
// 邮箱 : quarrying{at}qq.com
-
// 主页 : http://blog.csdn.net/quarryman
-
// 日期 : 2013年08月11日
-
// 描述 : 实现一般的LBP
-
//====================================================================
-
#include <cv.h>
-
#include <highgui.h>
-
void LBP(IplImage* src, IplImage* dst)
-
{
-
int width=src->width;
-
int height=src->height;
-
for(int j=1;j<width-1;j++)
-
{
-
for(int i=1;i<height-1;i++)
-
{
-
uchar neighborhood[8]={0};
-
neighborhood[7] = CV_IMAGE_ELEM( src, uchar, i-1, j-1);
-
neighborhood[6] = CV_IMAGE_ELEM( src, uchar, i-1, j);
-
neighborhood[5] = CV_IMAGE_ELEM( src, uchar, i-1, j+1);
-
neighborhood[4] = CV_IMAGE_ELEM( src, uchar, i, j-1);
-
neighborhood[3] = CV_IMAGE_ELEM( src, uchar, i, j+1);
-
neighborhood[2] = CV_IMAGE_ELEM( src, uchar, i+1, j-1);
-
neighborhood[1] = CV_IMAGE_ELEM( src, uchar, i+1, j);
-
neighborhood[0] = CV_IMAGE_ELEM( src, uchar, i+1, j+1);
-
uchar center = CV_IMAGE_ELEM( src, uchar, i, j);
-
uchar temp=0;
-
for(int k=0;k<8;k++)
-
{
-
temp+=(neighborhood[k]>=center)<<k;
-
}
-
CV_IMAGE_ELEM( dst, uchar, i, j)=temp;
-
}
-
}
-
}
-
int main()
-
{
-
IplImage* img=cvLoadImage("lena.jpg", 0);
-
IplImage* dst=cvCreateImage(cvGetSize(img),8,1);
-
LBP(img,dst);
-
cvNamedWindow("图像", 1);
-
cvShowImage("图像", dst);
-
cvWaitKey(0);
-
cvDestroyAllWindows();
-
cvReleaseImage(&img);
-
cvReleaseImage(&dst);
-
return 0;
-
}
结果图像为:
二)Uniform Pattern的LBP,将256维降为59维。
绝大多数LBP模式最多只包含两次从1到0或从0到1的跳变。因此,Ojala将Uniform Pattern定义为:当某个LBP所对应的循环二进制数从0到1或从1到0最多有两次跳变时,该LBP所对应的二进制就称为一个等价模式类。
代码一:
-
#include <stdio.h>
-
typedef unsigned char uchar;
-
int getHopCount(uchar i)
-
{
-
int a[8]={0};
-
int k=7;
-
int cnt=0;
-
while(i)
-
{
-
a[k]=i&1;
-
i>>=1;
-
--k;
-
}
-
for(int k=0;k<8;++k)
-
{
-
if(a[k]!=a[k+1==8?0:k+1])
-
{
-
++cnt;
-
}
-
}
-
return cnt;
-
}
-
int main()
-
{
-
int cnt[9]={0};
-
for(int i=0;i<256;++i)
-
{
-
cnt[getHopCount(i)]++;
-
}
-
for(int i=0;i<9;++i)
-
{
-
printf("跳变%d次的数目:%d\n",i,cnt[i]);
-
}
-
return 0;
-
}
输出结果为:
跳变0次的数目:2
跳变1次的数目:0
跳变2次的数目:56
跳变3次的数目:0
跳变4次的数目:140
跳变5次的数目:0
跳变6次的数目:56
跳变7次的数目:0
跳变8次的数目:2
可见:56+2+1==59,所以有59维。
代码二:
-
//====================================================================
-
// 作者 : quarryman
-
// 邮箱 : quarrying{at}qq.com
-
// 主页 : http://blog.csdn.net/quarryman
-
// 日期 : 2013年08月11日
-
// 描述 : Uniform Pattern的LBP
-
//====================================================================
-
#include <cv.h>
-
#include <highgui.h>
-
int getHopCount(uchar i)
-
{
-
int a[8]={0};
-
int k=7;
-
int cnt=0;
-
while(i)
-
{
-
a[k]=i&1;
-
i>>=1;
-
--k;
-
}
-
for(int k=0;k<8;++k)
-
{
-
if(a[k]!=a[k+1==8?0:k+1])
-
{
-
++cnt;
-
}
-
}
-
return cnt;
-
}
-
void lbp59table(uchar* table)
-
{
-
memset(table,0,256);
-
uchar temp=1;
-
for(int i=0;i<256;++i)
-
{
-
if(getHopCount(i)<=2)
-
{
-
table[i]=temp;
-
temp++;
-
}
-
// printf("%d\n",table[i]);
-
}
-
}
-
void LBP(IplImage* src, IplImage* dst)
-
{
-
int width=src->width;
-
int height=src->height;
-
uchar table[256];
-
lbp59table(table);
-
for(int j=1;j<width-1;j++)
-
{
-
for(int i=1;i<height-1;i++)
-
{
-
uchar neighborhood[8]={0};
-
neighborhood[7] = CV_IMAGE_ELEM( src, uchar, i-1, j-1);
-
neighborhood[6] = CV_IMAGE_ELEM( src, uchar, i-1, j);
-
neighborhood[5] = CV_IMAGE_ELEM( src, uchar, i-1, j+1);
-
neighborhood[4] = CV_IMAGE_ELEM( src, uchar, i, j+1);
-
neighborhood[3] = CV_IMAGE_ELEM( src, uchar, i+1, j+1);
-
neighborhood[2] = CV_IMAGE_ELEM( src, uchar, i+1, j);
-
neighborhood[1] = CV_IMAGE_ELEM( src, uchar, i+1, j-1);
-
neighborhood[0] = CV_IMAGE_ELEM( src, uchar, i, j-1);
-
uchar center = CV_IMAGE_ELEM( src, uchar, i, j);
-
uchar temp=0;
-
for(int k=0;k<8;k++)
-
{
-
temp+=(neighborhood[k]>=center)<<k;
-
}
-
//CV_IMAGE_ELEM( dst, uchar, i, j)=temp;
-
CV_IMAGE_ELEM( dst, uchar, i, j)=table[temp];
-
}
-
}
-
}
-
int main()
-
{
-
IplImage* img=cvLoadImage("lena.jpg", 0);
-
IplImage* dst=cvCreateImage(cvGetSize(img),8,1);
-
LBP(img,dst);
-
cvNamedWindow("图像", 1);
-
cvShowImage("图像", dst);
-
cvWaitKey(0);
-
cvDestroyAllWindows();
-
cvReleaseImage(&img);
-
cvReleaseImage(&dst);
-
return 0;
-
}
输出图像为: