图像特征之LBP(OpenCV)

xiaoxiao2021-02-28  92

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)<<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所对应的二进制就称为一个等价模式类。

代码一:

[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)<<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;   }   输出图像为:

转载请注明原文地址: https://www.6miu.com/read-27670.html

最新回复(0)