一、算法原理

1、原理概述

  LBP是局部二值模式(Local Binary Pattern)的简称,由芬兰奥卢大学的TimoOjala等人提出,是一种基于灰度,描述图像局部纹理特征的算子。其基本思想是利用中心值与邻域值的关系量化表达图像的局部纹理特征。
该算子是对多种纹理算子分析的基础上产生的,相比于其它同类别算子, LBP具有以下优点:
(1)原理深刻,容易理解,拓展和改进容易;
(2)灰度尺度的鲁棒性好,即光照影响较弱;
(3)运算方便,在局部邻域内计算,对于在复杂的情况下实时分析图像提供了可能。
  基于以上优势,LBP被广泛用于图像处理和模式识别等领域,如纹理分类、人脸或表情识别、行人和汽车等物体检测、行为辨别,以及遥感图像分类等。
  基本的LBP以 3 × 3 3\times3 3×3格网为窗口,窗口内有九个像素,数值为灰度值。以中心像素值为阈值,与邻域像素值进行比较,若邻域像素值大于等于中心像素值,则该像素的阈值为1,否则为0,产生的8位二进制数转换为十进制数即为中心单元的LBP值。邻域阈值计算公式如下:
s i = { 1 , p i − p c ≥ 0 0 , p i − p c < 0 (1) s_i= \begin{cases} 1,\quad p_i-p_c\geq 0\\ 0, \quad p_i-p_c<0 \end{cases} \tag{1} si={1,pipc00,pipc<0(1)
  式中, s i s_i si为窗口内邻域像素的阈值, p c p_c pc为中心像素的灰度值, p t p_t pt为邻域像素的灰度值。
LBP值计算过程如图1所示,中心像素值为6,按照顺时针方向排列,从左上角开始,邻域像素值分别为6、5、2、1、7、3、9、7,邻域阈值分别为1、0、0、0、1、0、1、1,LBP的二进制为110110001,转为十进制即可得到中心像素的LBP值为209。
OpenCV——基本LBP的计算方法-LMLPHP

2、参考文献

二、代码实现

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
// 基本LBP的计算方法
cv::Mat LocalBinaryPattern(cv::Mat& orignImg)
{
	cv::Mat grayImg;
	cvtColor(orignImg, grayImg, cv::COLOR_BGR2GRAY);

	int width = orignImg.cols - 2;
	int hight = orignImg.rows - 2;

	cv::Mat lbpImg = cv::Mat::zeros(hight, width, CV_8UC1);
	for (int row = 1; row < orignImg.rows - 1; row++)
	{
		for (int col = 1; col < orignImg.cols - 1; col++)
		{
			uchar c = grayImg.at<uchar>(row, col);
			uchar code = 0;
			code |= (grayImg.at<uchar>(row - 1, col - 1) > c) << 7;
			code |= (grayImg.at<uchar>(row - 1, col) > c) << 6;
			code |= (grayImg.at<uchar>(row - 1, col + 1) > c) << 5;
			code |= (grayImg.at<uchar>(row, col + 1) > c) << 4;
			code |= (grayImg.at<uchar>(row + 1, col + 1) > c) << 3;
			code |= (grayImg.at<uchar>(row + 1, col) > c) << 2;
			code |= (grayImg.at<uchar>(row + 1, col - 1) > c) << 1;
			code |= (grayImg.at<uchar>(row, col) > c) << 0;
			lbpImg.at<uchar>(row - 1, col - 1) = code;

		}
	}
	return lbpImg;
};


int main(int argc, char** argv)
{
	cv::Mat img = cv::imread("luna.png");
	//cv::Mat img;
	//resize(img, img, cv::Size(800, 500), 0, 0, cv::INTER_AREA);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	imshow("img", img);
	// 基本LBP
	cv::Mat lbpImg = LocalBinaryPattern(img);

	imshow("LBP", lbpImg);
	cv::waitKey(0);

	return 0;

}

三、结果展示

  可以看出,LBP算子可以较好地保留建筑轮廓、眼睛、鼻子、嘴巴和帽子羽毛等细节部分。

OpenCV——基本LBP的计算方法-LMLPHP

06-01 10:53