LBP简介(转载)

LBP(local binary pattern)是一种用来描述图像局部纹理特征的算子。原始的LBP于1994年提出,它反映内容是每个像素与周围像素的关系。后被不断的改进和优化,分别提出了LBP旋转不变模式、LBP均匀模式等。

一:原始的LBP

   给出一个简单的案例计算LBP:如下图,周围8个像素点比中间点像素值大(或者相等)的记为1,小的记为0,这样就得到二值图,然后按顺时针方向得到二进制串10001111

 

这样中间点的像素值就用241来代替。注意这里的计算LBP的顺序并没有硬性要求,只是一个量化公式,在同一处理中保持相同的顺序即可。

下面给出LBP的计算公式:

二、旋转不变的LBP模式<LBPROT>

原始的LBP不具有旋转不变性,这样我们就提出了旋转不变的LBP模式。旋转不变的LBP计算公式如下:

 

这样计算出来的LBP共有36种,分布情况如下面两幅图:

 

其中白点代表1,黑点代表0。

 

三:均匀LBP模式

旋转LBP模式同样存在缺陷,大量的实验证明LBP模式的36种情况在一幅图像中分布出现的频率差异较大,得到的效果并不是很好。因此人们提出了均匀LBP模式即uniform LBP。

均匀模式就是一个二进制序列从0到1或是从1到0的变过不超过2次(这个二进制序列首尾相连)。比如:10100000的变化次数为3次所以不是一个uniform pattern。所有的8位二进制数中共有58(变化次数为0的有2种,变化次数为1的有0种,变化次数为2的有56种)个uniform pattern.为什么要提出这么个uniform LBP呢,因为研究者发现他们计算出来的大部分值都在这58种之中,可达到90%以上,所以他们把值分为59类,58个uniform pattern为一类,其它的所有值为第59类。59=(2+0+56)+1,这样直方图从原来的256维变成59维。起到了降维的作用。

 计算公式:

 

应用:

在模式识别如判断两幅图片的相似性时,我们可以统计这两幅图像的LBP特征的直方图。这样,在原始的LBP模式中,统计的直方图可以当做一个256维的向量。直接这样判断,很多时候会因为“位置没有对准”而产生很大的误差。大量研究表明,此时我们可以将一幅图片划分为若干的子区域,对每个子区域内的每个像素点都提取LBP特征,然后,在每个子区域内建立LBP特征的统计直方图。如此一来,每个子区域,就可以用一个统计直方图来进行描述;整个图片就由若干个统计直方图组成。比如将一幅图像划分为10*10个区域,这样得到向量的维数就是256*10*10。而针对uniform LBP,此时向量的维数就是59*10*10, 从而达到降维的目的。

目前,LBP局部纹理提取算子,已经成功应用在指纹识别、字符识别、人脸识别、车牌识别等领域。

 

Code:

原始的LBP:

 1 void LBP(Mat &image, Mat &result)
 2 {
 3     for(int y = 1; y < image.rows-1; y ++)
 4     {
 5         for(int x = 1; x < image.cols-1; x++)
 6         {
 7             uchar neighbor[8] = {0};
 8             neighbor[0] = image.at<uchar>(y-1, x-1);
 9             neighbor[1] = image.at<uchar>(y-1, x);
10             neighbor[2] = image.at<uchar>(y-1, x+1);
11             neighbor[3] = image.at<uchar>(y, x+1);
12             neighbor[4] = image.at<uchar>(y+1, x+1);
13             neighbor[5] = image.at<uchar>(y+1, x);
14             neighbor[6] = image.at<uchar>(y+1, x-1);
15             neighbor[7] = image.at<uchar>(y, x-1);
16             uchar center = image.at<uchar>(y, x);
17             uchar temp = 0;
18             for(int k = 0; k < 8; k++)
19             {
20                 temp += (neighbor[k] >= center)* (1<<k);  // 计算LBP的值
21             }
22             result.at<uchar>(y,x) = temp;    
23         }
24     }
25 }
26 
27 int main()
28 {
29     Mat image = imread("F:\\lena.png", 0);
30     if(!image.data)
31     {
32         cout << "Fail to load image" << endl;
33         return 0;
34     }
35     Mat result;
36     result.create(Size(image.cols, image.rows), image.type());
37     LBP(image, result);
38     namedWindow("result", 0);
39     imshow("result", result);
40     waitKey(0);
41     return 0;
42 }

uniform LBP:

 1 #include "Stafx.h"
 2 using namespace cv;
 3 using namespace std;
 4 
 5 // 计算跳变次数  
 6 int getHopCount(int i)  
 7 {  
 8     int a[8] = {0};  
 9     int cnt = 0;  
10     int k = 7;
11     /************************************************************************/
12     /* while循环详解:
13       例如i的二进制为000000000000000000000000abcdefgh,经过i&1后a[7]=h;经过i>>1后右移一位
14       变成000000000000000000000000abcdefg,再经过i&1后a[6]=g;经过i>>1后右移一位
15       0000000000000000000000000abcdef,依次类推,则数组a为a[0]=a,a[1]=b,a[2]=c,a[3]=d,a[4]=e,
16       a[5]=f,a[6]=g,a[7]=h
17     */
18     /************************************************************************/
19     while(i)  
20     {  
21         a[k] = i&1;  //取i的二进制的最低位
22         i = i >> 1;  //右移
23         --k;  
24     }
25     //a[0]~a[7]组成环形,只要相邻两个不同就加1
26     for(k = 0; k < 7; k++)  
27     {  
28         if(a[k] != a[k+1])  
29         {  
30             ++cnt;  
31         }  
32     }  
33     if(a[0] != a[7])  
34     {  
35         ++cnt;  
36     }  
37     return cnt;  
38 }  
39 
40 // 降维数组 由256->59  
41 void lbp59table(uchar *table)  
42 {  
43     memset(table, 0, 256);  
44     uchar temp = 1;  
45     for(int i = 0; i < 256; i++)  
46     {  
47         if(getHopCount(i) <= 2)    // 跳变次数<=2 的为非0值  
48         {  
49             table[i] = temp;    //划分为多少类,类标签从小到大排列,好比一个映射表,搜索索引值
50             temp ++;  
51         }  
52     }  
53 }  
54 
55 void uniformLBP(Mat &image, Mat &result, uchar *table)  
56 {  
57     for(int y = 1; y < image.rows-1; y ++)  
58     {  
59         for(int x = 1; x < image.cols-1; x++)  
60         {  
61             uchar neighbor[8] = {0};  
62             neighbor[0] = image.at<uchar>(y-1, x-1);  
63             neighbor[1] = image.at<uchar>(y-1, x);  
64             neighbor[2] = image.at<uchar>(y-1, x+1);  
65             neighbor[3] = image.at<uchar>(y, x+1);  
66             neighbor[4] = image.at<uchar>(y+1, x+1);  
67             neighbor[5] = image.at<uchar>(y+1, x);  
68             neighbor[6] = image.at<uchar>(y+1, x-1);  
69             neighbor[7] = image.at<uchar>(y, x-1);  
70             uchar center = image.at<uchar>(y, x);  
71             uchar temp = 0;  
72             for(int k = 0; k < 8; k++)  
73             {  
74                 //1<<k表示2^k次幂
75                 temp += (neighbor[k] >= center)* (1<<k);  // 计算LBP的值  
76             }  
77             result.at<uchar>(y,x) = table[temp];   //  降为59维空间  
78         }  
79     }  
80 }  
81 
82 int main()  
83 {  
84     uchar table[256];  
85     lbp59table(table);  
86     Mat image = imread("lena.png", 0);  
87     if(!image.data)  
88     {  
89         cout << "Fail to load image" << endl;  
90         return 0;  
91     }  
92     Mat result;  
93     result.create(Size(image.cols, image.rows), image.type());  
94     uniformLBP(image, result, table);  
95     namedWindow("uniformResult", 0);  
96     imshow("uniformResult", result);  
97     waitKey(0);  
98     return 0;  
99 }  

 unform lBP

 3 #include "Stafx.h"
 4 
 5 //提取局部纹理特征均匀LBP算子
 6 
 7 int gethopcount(int i) //判断环形二进制字符串两位的变化次数
 8 {
 9     int a[8]={0};
10     int temp=0;         //变换次数
11     int k=7;
12     while (i)
13     {
14         a[k]=i&1;  //取二进制最低位
15         i=i>>1;    //右移
16         k--;
17     }
18     for (int j=0;j<7;j++)  //判断下标0~7
19     {
20         if (a[j]!=a[j+1]) temp++;
21     }
22     //判断下标0和7
23     if (a[0]!=a[7]) temp++;
24     return temp;
25 }
26 //实现降维操作256->59
27 void lbp59table(uchar* table)
28 {
29     memset(table,0,256);
30     uchar temp=1;
31     for (int i=0;i<256;i++)
32     {
33         if (gethopcount(i)<=2)
34         {
35             table[i]=temp; 
36             temp++;
37         }
38     }
39 }
40 //均匀LBP算法
41 void uniformLBP(IplImage* src,IplImage* result, uchar* table)
42 {
43     cvCopy(src,result);  //注意到cvCopy与cvCloneImage的区别
44     /************************************************************************/
45     /* cvCopy必须先要创建内存空间,才能使用
46        而cvCloneImage会自动开辟内存空间,并返回指向该内存空间的指针
47        如果在这里使用result=cvCloneImage(src);则main函数中显示的result是无图像
48        说明这两个地址所指向的空间内存不一样。
49     */
50     /************************************************************************/
51     for (int i=1;i<src->width-1;i++)
52         for (int j=1;j<src->height-1;j++)
53         {
54             uchar neighbor[8]={0};
55             neighbor[0]=CV_IMAGE_ELEM(src,uchar,j-1,i-1);
56             neighbor[1]=CV_IMAGE_ELEM(src,uchar,j-1,i);
57             neighbor[2]=CV_IMAGE_ELEM(src,uchar,j-1,i+1);
58             neighbor[3]=CV_IMAGE_ELEM(src,uchar,j,i+1);
59             neighbor[4]=CV_IMAGE_ELEM(src,uchar,j+1,i+1);
60             neighbor[5]=CV_IMAGE_ELEM(src,uchar,j+1,i);
61             neighbor[6]=CV_IMAGE_ELEM(src,uchar,j+1,i-1);
62             neighbor[7]=CV_IMAGE_ELEM(src,uchar,j,i-1);
63             uchar central=CV_IMAGE_ELEM(src,uchar,j,i);
64             uchar temp=0;
65             for (int k=0;k<8;k++)
66             {
67                 temp+=(neighbor[k]>=central)*(1<<k); //1<<k表示2^k次幂
68             }
69             uchar*ptr=(uchar*) (result->imageData+j*result->widthStep+i);
70             *ptr=table[temp];
71         };
72 }
73 void main()
74 {
75     uchar table[256];
76     lbp59table(table);  //由256维降成59维
77     IplImage* src=cvLoadImage("lena.png",CV_LOAD_IMAGE_GRAYSCALE);
78     IplImage* result=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
79     uniformLBP(src,result,table);
80     cvShowImage("1",result);
81     cvWaitKey();
82     cvReleaseImage(&src);
83     cvReleaseImage(&result);
84 }

 

转载于:https://www.cnblogs.com/gzy-zju-edu/articles/4168021.html

图像特征LBP原理及C++实现 LBP的原理及代码实现 阅读详情

相关推荐

【计算机视觉】LBP纹理特征

LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen,和 D. Harwood 在1994年提出,用于纹理特征提取。而且,提取的特征是图像的局部的纹理特征。 从纹理分析的角度来看,图像上某个像素点的纹理特征,大多数情况下是指这个点和周围像素点的关系,即这个点和它的邻域内点的关系。从哪个角度对这种关系提取特征,就形成了不同种类的特征。有了特征,就能根据纹理进行分类

Jason Ding的专栏 4251

LBP算法及其改进算法

LBP指局部二值模式,英文全称:Local Binary Pattern,是一种用来描述图像局部特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点。 本文介绍了LBP算法以及其部分扩展算法

weixin_45184581的博客 1万+

告别Godot默认编辑器:手把手教你用VSCode配置C#开发环境(附中文注释避坑指南)

本文详细介绍了如何将VSCode配置为Godot引擎的C#开发环境,提升游戏开发效率。从环境准备、扩展配置到解决中文编码问题,提供完整的避坑指南和高级调试技巧,帮助开发者充分利用VSCode的智能补全和调试功能,打造高效工作流。

weixin_30596023的博客 168

图像处理之LBP特征(C++)

本文主要介绍了LBP、Circle LBPLBPH的C++实现和原理。

qq_45045175的博客 2551

LBP算法(人脸识别特征提取)

LBP(Local Binary Patterns,局部二值模式)是提取局部特征作为判别依据的。LBP方法显著的优点是对光照不敏感,但是依然没有解决姿态和表情的问题。不过相比于特征脸方法,LBP的识别率已经有了很大的提升。在[1]的文章里,有些人脸库的识别率已经达到了98%+。 1、LBP特征提取 最初的LBP是定义在像素3x3邻域内的,以邻域中心像素为阈值,将相邻的8个像素的灰度值与其...

qq_32172681的博客 8531

LBP简介

LBP简介

hggjgff的博客 363

LBP特征及其一些变种

说明:本文部分内容转载:http://blog.sina.com.cn/s/blog_631a4cc401013pkn.html 图像纹理是一种重要的视觉手段,是图像中普遍存在而又难以描述的特征。纹理分析技术一直是计算机视觉、图像处理、图像检索等的活跃研究领域。纹理特征提取的目标是:提取的纹理特征维数不大、鉴别能力强、稳健性好,提取过程计算量小,能够指导实际运用。  纹理的定义一直为人们所关注

tfg1025的专栏 8191

LBP纹理特征

本文纯属转载,由于原文图片无法直接显示,故转载过来加上原文图片 原文链接 LBP方法(Local binary patterns)是一个计算机视觉中用于图像特征分类的一个方法。LBP方法在1994年首先由T. Ojala, M.Pietikäinen, 和 D. Harwood 提出[43][44],用于纹理特征提取。后来LBP方法与HOG特征分类器联合使用,改

骑驴看唱本 1138

LBP算子简介

LBP的全称是Local Binary Pattern即局部二值模式,是局部信息提取中的一种方法。目前LBP有很多应用,如人脸识别,表情识别等。局部信息有很多,比如HOG,SIFT等等。那么我们为什么要提取局部特征呢?原因很简单,因为一幅图像的信息比较多,如灰度,边缘等等,计算机很难处理这种复杂的信息,所以就需要对这些信息进行处理。     LBP就是一种局部信息,它反应的内容是每个像素与周

万人往的专栏 3138

图像特征提取 — LBP算法

原创博客,转载请注明出处! LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算法;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen, 和D. Harwood 在1994年提出,用于纹理特征提取。而且,提取的特征是图像的局部的纹理特征;   1、LBP特征的描述        原始的LBP算子定...

kk123k的博客 1289

LBP特征

转载: http://blog.csdn.net/zouxy09/article/details/7929531 安微博: http://weibo.com/u/2044913903 *************************************************************************      LBP(Local Binary Pat

_menglan_Zi 1299

LBP特征直方图

经过LBP算子的计算后,图像上对应于每个像素都会有一个LBP特征值,如果LBP特征计算时采样点是8个的话,那么LBP特征值的范围也是0~255。也可以表示成一张图像。称之为LBP图谱。如下图所示: 上图中,上面一行是原图,下面一行是LBP图谱。可以看到LBP特征的一个优势,就是LBP对光照有很好的鲁棒性 但是,在实际应用中,并不使用LBP图谱做特征。 对于八采样点的LBP算子来说,特征值范围为0...

weixin_43862688的博客 1万+

LBP原理介绍以及算法实现

原文地址:http://blog.csdn.net/xpplearnc/article/details/40658211   没有看LBP之前觉得它很神秘,看完了之后也就那么回事,不过提出LBP的人确实很伟大!!   LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala,

holly的专栏 12万+

【学习笔记】LBP特征描述算子-人脸检测

2.1 简介   LBP指局部二值模式(Local Binary Pattern),是一种用来描述图像局部特征的算子,具有灰度不变性和旋转不变性等显著优点。由于该特征的简单易算性,虽然其总体效果不如Haar特征,但速度则快于Haar,所以也得到了广泛的使用。 2.2 学习目标 理解LBP算法相关原理 了解人脸检测相关流程 掌握基于Opencv的LBP算法实现 2.3 LBP算法理论介绍 2.3.1 LBP原理介绍   原始的LBP算子定义在像素3∗33*33∗3的邻域内,以邻域中心像素为阈值,相邻的8个

weixin_43869610的博客 939

LBP特征原理及代码实现

LBP特征原理及代码实现

SnailTyan 7万+

目标检测的图像特征提取之(二)LBP特征

目标检测的图像特征提取之(二)LBP特征 LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen,和 D. Harwood 在1994年提出,用于纹理特征提取。而且,提取的特征是图像的局部的纹理特征;   1、LBP特征的描述        原始...

m0_37692953的博客 1299

局部二值模式LBP

局部二值模式(Local Binary Patterns,LBP)是一种用于图像处理和计算机视觉中的特征描述符。它通过将每个像素与其周围像素进行比较,并将结果编码为二进制数来描述图像的纹理信息。LBP最初由芬兰奥卢大学的Timo Ojala、Matti Pietikainen和Topi Maenpaa于1994年在论文中提出。他们提出了一种用于纹理分析和识别的算法,并将其应用于人脸识别任务。

机器人视觉感知 4772

ComfyUI全自动换装工作流:从零到一的实战指南

本文提供了一份详细的ComfyUI全自动换装工作流实战指南。从环境配置、模型准备到核心工作流架构的逐步拆解,手把手教你搭建一条高效的AI换装流水线。文章深入解析了从输入、预处理、融合到输出的四步核心逻辑,并分享了关键参数调优与进阶技巧,旨在帮助电商从业者、内容创作者及AI爱好者轻松实现高质量、高效率的“一键换装”。

weixin_29198045的博客 788

(完整版)实验室安全教育(计算机类).ppt

(完整版)实验室安全教育(计算机类).ppt

上一篇: 提取元素的轮廓及形状描述子(以一种新的模式来做)(转载)
下一篇: PreTranslateMessage
Joanne0106
博客等级 码龄12年 1粉丝 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值