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。

均匀模式就是一个二进制序列从01或是从10的变过不超过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:

void LBP(Mat &image, Mat &result)
{
	for(int y = 1; y < image.rows-1; y ++)
	{
		for(int x = 1; x < image.cols-1; x++)
		{
			uchar neighbor[8] = {0};
			neighbor[0] = image.at<uchar>(y-1, x-1);
			neighbor[1] = image.at<uchar>(y-1, x);
			neighbor[2] = image.at<uchar>(y-1, x+1);
			neighbor[3] = image.at<uchar>(y, x+1);
			neighbor[4] = image.at<uchar>(y+1, x+1);
			neighbor[5] = image.at<uchar>(y+1, x);
			neighbor[6] = image.at<uchar>(y+1, x-1);
			neighbor[7] = image.at<uchar>(y, x-1);
			uchar center = image.at<uchar>(y, x);
			uchar temp = 0;
			for(int k = 0; k < 8; k++)
			{
				temp += (neighbor[k] >= center)* (1<<k);  // 计算LBP的值
			}
			result.at<uchar>(y,x) = temp;	
		}
	}
}

int main()
{
	Mat image = imread("F:\\lena.png", 0);
	if(!image.data)
	{
		cout << "Fail to load image" << endl;
		return 0;
	}
	Mat result;
	result.create(Size(image.cols, image.rows), image.type());
	LBP(image, result);
	namedWindow("result", 0);
	imshow("result", result);
	waitKey(0);
	return 0;
}
uniform LBP:

// 计算跳变次数
int getHopCount(int i)
{
	int a[8] = {0};
	int cnt = 0;
	int k = 7;
	while(i)
	{
		a[k] = i&1;
		i = i >> 1;
		--k;
	}
	for(k = 0; k < 7; k++)
	{
		if(a[k] != a[k+1])
		{
			++cnt;
		}
	}
	if(a[0] != a[7])
	{
		++cnt;
	}
	return cnt;
}

// 降维数组 由256->59
void lbp59table(uchar *table)
{
	memset(table, 0, 256);
	uchar temp = 1;
	for(int i = 0; i < 256; i++)
	{
		if(getHopCount(i) <= 2)    // 跳变次数<=2 的为非0值
		{
			table[i] = temp;
			temp ++;
		}
	}
}

void uniformLBP(Mat &image, Mat &result, uchar *table)
{
	for(int y = 1; y < image.rows-1; y ++)
	{
		for(int x = 1; x < image.cols-1; x++)
		{
			uchar neighbor[8] = {0};
			neighbor[0] = image.at<uchar>(y-1, x-1);
			neighbor[1] = image.at<uchar>(y-1, x);
			neighbor[2] = image.at<uchar>(y-1, x+1);
			neighbor[3] = image.at<uchar>(y, x+1);
			neighbor[4] = image.at<uchar>(y+1, x+1);
			neighbor[5] = image.at<uchar>(y+1, x);
			neighbor[6] = image.at<uchar>(y+1, x-1);
			neighbor[7] = image.at<uchar>(y, x-1);
			uchar center = image.at<uchar>(y, x);
			uchar temp = 0;
			for(int k = 0; k < 8; k++)
			{
				temp += (neighbor[k] >= center)* (1<<k);  // 计算LBP的值
			}
			result.at<uchar>(y,x) = table[temp];	 //  降为59维空间
		}
	}
}

int main()
{
	uchar table[256];
	lbp59table(table);
	Mat image = imread("F:\\lena.png", 0);
	if(!image.data)
	{
		cout << "Fail to load image" << endl;
		return 0;
	}
	Mat result;
	result.create(Size(image.cols, image.rows), image.type());
	uniformLBP(image, result, table);

	namedWindow("uniformResult", 0);
	imshow("uniformResult", result);

	waitKey(0);
	return 0;
	
}

Result:

原图:

原始LBP:


uniform LBP:


参考文献:文章:Multiresolution Gray-Scale and Rotation Invariant Texture Classificationwith Local Binary Patterns 

作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值