本文主要是介绍LBP特征计算程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
http://blog.csdn.net/hujingshuang/article/details/47292721
简介:
局部二值模式(Local Binary Pattern, LBP)是一种有效的纹理描述算子,它具有旋转不变性和灰度不变性的显著的有点。已经广泛的应用于纹理分类、纹理分割、人脸图像分析等领域。本文就LBP算法做简单的讲解,并在OpenCV中加以实现。
基本的LBP算子
局部二值模式是一种灰度范围内的纹理描述方式。算法的思想是利用结构化思想提取窗口特征,再利用统计化做最终整体特征的提取。
最初的LBP描述子算法步骤如下:
1、对图像中的所有点,以该点为中心,取3x3的邻域窗口;
2、将8-邻域像素值与中心点像素值进行比较,大于或等于中心像素标记为1,否则标记为0;
3、将周围0-1序列,以一定的顺序排列,成一个8位的无符号的二进制数,转化成整数;
4、这个整数就是表征这个窗口的LBP值。

以上,便是最基本的LBP算子。由于直接利用的灰度比较,所以其具有灰度不变性;但是,有两个很明显的缺点:
1、产生的二进制模式多;
2、不具有旋转不变性。
为解决这两个问题,后人对LBP算法做了改进,后面会有介绍。
当然,上面的8-邻域并不是最好的,但是最基本的,在后面出现了诸如下图所示的邻域,1,2指的是半径,8,16指的是采样点数。

改进的LBP算子
LBP等价模式
考察LBP算子的定义可知,一个LBP算子可以产生多种二进制模式(p个采样点)如:3x3邻域有p=8个采样点,则可得到2^8=256种二进制模式;5x5邻域有p=24个采样点,则可得到2^24=16777216种二进制模式,以此类推......。显然,过多的二进制模式无论对于纹理的提取还是纹理的识别、分类及信息存取都是不利的,在实际应用中不仅要求采用的算子尽量简单,同时也要考虑到计算速度、存储量大小等问题。因此需要对原始的LBP模式进行降维。
Ojala提出一种“等价模式”(Uniform Pattern)来对LBP算子进行降维,Ojala等认为图像中,某个局部二进制模式所对应的循环二进制数从0—>1或从1—>0,最多有两次跳变,该局部二进制模式所对应的二进制就成为一个等价模式。如00000000,00111000,10001111,11111111等都是等价模式类。判断一个二进制模式是否为等价模式最简单的办法就是将LBP值与其循环移动一位后的值进行按位相与,计算得到的二进制数中1的个数,若个数小于或等于2,则是等价模式;否则,不是。出了等价模式以外的模式都归一一类,称为混合模式类。
通过这种改进,二进制模式的种类大大减少,而不会丢失任何信息,模式种类由原来的2^p减少为p*(p-1)+2种。
但等价模式代表了图像的边缘、斑点、角点等关键模式,等价模式占了总模式中的绝大多数,所以极大的降低了特征维度。利用这些等价模式和混合模式类直方图,能够更好地提取图像的本质特征。

(降维而不丢失了图像主要的信息,精华的部分!)
旋转不变的LBP算子
由于LBP的二进制模式是以一定的方向、顺序进行编码的,所以当图像发生旋转时,按这种编码的话,LBP值会发生改变,因此是不具有旋转不变性的。Maenpaa等人提出了具有旋转不变性的LBP算子。
解决办法是:不断旋转邻域得到一系列的LBP值,取其中最小值作为该邻域的LBP值。旋转过程实质上就是对二进制模式进行循环移位的过程。

通过引入旋转不变的定义,使LBP算子更具鲁棒性。但这也是LBP算子丢失了方向信息。在很多场合,方向信息非常重要;然而,在纹理图像分析中,LBP依然被证明是有效的。
实验
opencv代码
通过定义model_rotation与model_equivalent来进行等价模式和旋转不变性的实现。
-
-
-
-
-
-
-
-
-
-
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include "intrins.h"
-
- using namespace cv;
- using namespace std;
-
- #define model_rotation
- #define model_equivalent
-
- int main()
- {
- Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
- Mat pic = Mat::zeros(img.rows, img.cols, img.type());
- imshow("src", img);
-
-
-
- for (int i = 1; i < img.rows - 1; i++)
- {
- for (int j = 1; j < img.cols - 1; j++)
- {
- uchar p[9];
-
- p[0] = img.at<uchar>(i, j);
- p[1] = img.at<uchar>(i - 1, j - 1);
- p[2] = img.at<uchar>(i - 1, j);
- p[3] = img.at<uchar>(i - 1, j + 1);
- p[4] = img.at<uchar>(i, j + 1);
- p[5] = img.at<uchar>(i + 1, j + 1);
- p[6] = img.at<uchar>(i + 1, j);
- p[7] = img.at<uchar>(i + 1, j - 1);
- p[8] = img.at<uchar>(i, j - 1);
-
- uchar value = 0;
- for (int k = 1; k <= 8; k++)
- {
- value += (p[k] >= p[0]) << (8 - k);
- }
-
- #ifdef model_equivalent
- uchar temp = _cror(value, 1);
- if(_mm_popcnt_u32(temp & value) > 2)
- {
- pic.at<uchar>(i, j) = value;
- }
- #else
- pic.at<uchar>(i, j) = value;
- #endif
-
- #ifdef model_rotation
- uchar rot[8];
- _rota(value, rot);
- pic.at<uchar>(i, j) = _min(rot);
- #endif
- }
- }
- imshow("LBP_equ_rot", pic);
- waitKey();
-
-
- return 0;
- }
其中intrins.h与intrins.cpp是循环移位及查找最小值的源代码。
intrins.h
-
-
-
-
-
-
-
-
-
-
- #ifndef __INTRINS_H__
- #define __INTRINS_H__
-
- #include <cv.h>
-
- using namespace std;
-
- uchar _crol(uchar tmp, uchar n);
- uchar _crol_bit(uchar tmp);
- uchar _cror(uchar tmp, uchar n);
- uchar _cror_bit(uchar tmp);
- void _rota(uchar tmp, uchar *temp);
- uchar _min(uchar *tmp);
-
- #endif
intrins.cpp
-
-
-
-
-
-
-
-
-
-
- #include "intrins.h"
-
-
- uchar _crol(uchar tmp, uchar n)
- {
- while(n--)
- {
- tmp = _crol_bit(tmp);
- }
- return tmp;
- }
-
- uchar _crol_bit(uchar tmp)
- {
- return (tmp << 1) | (tmp >> 7);
- }
-
- uchar _cror(uchar tmp, uchar n)
- {
- while(n--)
- {
- tmp = _cror_bit(tmp);
- }
- return tmp;
- }
-
- uchar _cror_bit(uchar tmp)
- {
- return (tmp >> 1) | (tmp << 7);
- }
-
- void _rota(uchar tmp, uchar *temp)
- {
- for (int i = 0; i < 8; i++)
- {
- *temp = _cror(tmp, i);
- temp++;
- }
- }
-
- uchar _min(uchar *tmp)
- {
- uchar min = *tmp;
- for (int i = 0; i < 8; i++)
- {
- tmp++;
- if (min > *tmp)
- {
- min = *tmp;
- }
- }
- return min;
- }
结果:
依次是:原图、等价模式、旋转不变、等价+旋转不变(注:此处等价模式未进行任何的等价处理)
参考文献:
1、黄菲菲,基于LBP的人脸识别研究[M],2009.
2、程雪峰,基于LBP特征的人脸识别算法研究[M],2014.
这篇关于LBP特征计算程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!