本文轉載自http://blog.csdn.net/quarryman/article/details/9906047
LBP(Local binary pattern)是一個易了解和很有效的圖像局部紋理特征,應用也很廣泛。在網上可以搜到一大把的LBP介紹,是以本博文就忽略了對其的介紹。直接附上代碼,代碼不難,隻是希望對大家有用!如有錯誤和補充,歡迎提出,大家共同進步哈!
一)一般的LBP,256維
[cpp] view plain copy
- //====================================================================
- // 作者 : 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)*(1<<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;
- }
結果圖像為:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcVnRXJWNK52YoZFWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TOwYjN1EDNyITMxgDMzEDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
二)Uniform Pattern的LBP,将256維降為59維。
絕大多數LBP模式最多隻包含兩次從1到0或從0到1的跳變。是以,Ojala将Uniform Pattern定義為:當某個LBP所對應的循環二進制數從0到1或從1到0最多有兩次跳變時,該LBP所對應的二進制就稱為一個等價模式類。
代碼一:
[cpp] view plain copy
- #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維。
代碼二:
[cpp] view plain copy
- //====================================================================
- // 作者 : 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)*(1<<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;
- }
輸出圖像為: