人脸纹理特征提取ELBP之OpenCV实现

1、前言

传统 LBP 特征通过比较重心局部窗口区域中心像素点灰度值与其它像素点的灰度关系来进行二值编码,因而极易受噪点影响。在非均匀光照、噪声及遮挡等情况下对图像纹理特征的描述能力不足。

ELBP 在对图形进行二值特征时,不仅考虑中心像素点灰度值与其它像素点的灰度大小关系,还对其灰度差异值的绝对值进行编码,以增加图像纹理的细节信息。本文旨在介绍 ELBP 特征提取方式实现思路。

2、实现原理

传统 LBP 算子,仅对相邻像素间的符号差异进行编码来描述图像纹理信息是不够的,因为忽略了保留在灰度值差异中的一些重要信息。当图像领域灰度都小于图像中心灰度值时,不同图像同一位置的将得到 LBP 特征。这里人脸图像举例说,如下图:
不同人脸鼻尖位置的LBP特征
统计分析发现,LBP 提取半径 R = 2 时,超过 93% 的领域点深度差异值小于 7。因此额外添加三个二进制单位来编码中心点灰度与其相邻灰度之间的会灰度差值。

新加的三个二进制单元 {i2i3i4} 可以对应灰度差 (DD) 的绝对值:0 ~ 7。|DD| ≥ 7,则设置为 7。像原来的 LBP 一样,用 0, 1 表示的差值符号组合作为头二进制单元(i1)。DD 的二值编码方式:
灰度差绝对值编译方式
四个二进制单元被分成四层。每一层的二进制单位按顺时针方向排列。最后,将在每个像素点上得到四个十进制数字:P1、P2、P3、具体的灰度差绝对值编码方式可以参考下图:
在这里插入图片描述

3、程序设计实现

// Converts decimal number to binary
int dec2bin(int number) {
	
	int bin = 0;
	int i = 1;
	while (number > 0) {
		bin += (number % 2) * i;
		number = number / 2;
		i *= 10;
	}

	return bin;
}

int ELBP(Mat depth_image, Mat dst)
{

//Determine if the input image is empty
	if (depth_image.empty())
	{
		cout << "depth_image is empty" << endl;
		return -1;
	}

	// Initialize Matrices that will store the 4 LBP code numbers.
	Mat LBP1(depth_image.rows, depth_image.cols, CV_8UC1);
	Mat LBP2(depth_image.rows, depth_image.cols, CV_8UC1);
	Mat LBP3(depth_image.rows, depth_image.cols, CV_8UC1);
	Mat LBP4(depth_image.rows, depth_image.cols, CV_8UC1);
	
	// LBP Indexes to be visited
	int index_x[8] = { 1, 2, 3, 2, 0, -2, -3, -2 };
	int index_y[8] = { 3, 2, 0, -2, -3, -2, 0, 2 };

	// 8 Neighbors values
	int neigh =0;
	
	// Values of Neighbor - central pixel
	uchar subtraction = 0;

	//  LBP values
	int i1 = 0;
	int i2 = 0;
	int i3 = 0;
	int i4 = 0;

	// Variables needed
	int subtract;
	int temporary_bin = 0;
	int i22 = 0, i33 = 0, i44 = 0;

	// For all pixels in image performs 3DLBP
	for (int i = 0; i < depth_image.rows; i++) {
		for (int j = 0; j < depth_image.cols; j++) {

			// 8 Neighbors visited
			for (int k = 0; k < 8; k++) {
				// Tests if goes out of image borders
				if (i + index_x[k] < 0 || i + index_x[k] >= depth_image.rows || j + index_y[k] < 0 || j + index_y[k] >= depth_image.cols) {
					neigh =0;
				}
				else {
					neigh = depth_image.at<uchar>(i + index_x[k], j + index_y[k]);
				}

				subtract = (neigh - depth_image.at<uchar>(i, j));

				if (subtract > 7) {
					subtraction = 7;
				}

				else if (subtract < -7) {
					subtraction = -7;
				}

				else {
					subtraction = subtract;
				}
	
				int i11 = ((subtract> 0) || (std::abs(subtract) < std::numeric_limits<float>::epsilon()));

				i1 = i1 + (i11 << k);
					
				temporary_bin = dec2bin(int(abs(subtraction)));

				i22 = temporary_bin / 100 % 10;
				i33 = temporary_bin / 10 % 10;
				i44 = temporary_bin / 1 % 10;

				//Shift implements for Binary coding
				i2 = i2 + (i22 << k);
				i3 = i3 + (i33 << k);
				i4 = i4 + (i44 << k);

				// Reset Parameters;
				i22 = 0;
				i33 = 0;
				i44 = 0;
			}

			
			LBP1.at<uchar>(i, j) = static_cast<uchar>(i1);
			LBP2.at<uchar>(i, j) = static_cast<uchar>(i2);
			LBP3.at<uchar>(i, j) = static_cast<uchar>(i3);
			LBP4.at<uchar>(i, j) = static_cast<uchar>(i4);
			// Reset Parameters;
			i1 = 0;
			i2 = 0;
			i3 = 0;
			i4 = 0;
		
		}
	}

	hconcat(LBP1, LBP2,dst);

	hconcat(dst, LBP3, dst);

	hconcat(dst, LBP4, dst);

	return 0;
}

4、实现结果

4.1 输入图像

输入人脸图像

4.2 提取结果

ELPB人脸特征
上图依次提取的四个层次的 ELBP 特征,从中可以发现四个层次 ELBP 描述人脸不同的细节纹理信息。

5、参考文献

[1] Huang D, Wang Y, Wang Y. A robust method for near infrared face recognition based on extended local binary pattern[C]//International Symposium on Visual Computing. Springer, Berlin, Heidelberg, 2007: 437-446.
[2] Huang Y, Wang Y, Tan T. Combining Statistics of Geometrical and Correlative Features for 3D Face Recognition[C]//BMVC. 2006: 879-888.


长按按识别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值