OpenCv-C++-LBP特征检测

什么是LBP?它是一种用来描述图像局部纹理特征的算子,英文叫做“Local Binary Pattern”,局部二值模式

它具有旋转不变性,灰度不变性和光照强度不变性等优点。特别是光照强度不变性这一点,如果一张图片在光照很强的画面里特征物体根本无法识别,LBP就能很好的检测到物体。这一点我觉得很实用。

部分原理的话其实参考这篇文章就好,很详细,也很能懂。
参考文章:https://blog.csdn.net/heli200482128/article/details/79204008

我主要是以代码应用为主:
下面放上代码:

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

using namespace cv;
using namespace std;
int current_radius = 3;
int max_count = 20;
void Expand_LBP_demo(int, void*);


Mat src,gray_src;
int main(int argc, char** argv)
{
	src = imread("D:/test/girl.png");
	if (!src.data)
	{
		cout << "图片未找到" << endl;
		return -1;
	}
	imshow("input title", src);
	cvtColor(src, gray_src, CV_BGR2GRAY);

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

	//基本LBP演示
	Mat lbpImg = Mat::zeros(hight, width, CV_8UC1);

	for (int row = 1; row < src.rows - 1; row++)
	{
		for (int col = 1; col < src.cols - 1; col++)
		{
			uchar c = gray_src.at<uchar>(row, col);
			uchar code = 0;
			code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7;
			code |= (gray_src.at<uchar>(row - 1, col ) > c) << 6;
			code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5;
			code |= (gray_src.at<uchar>(row, col + 1) > c) << 4;
			code |= (gray_src.at<uchar>(row + 1, col +1) > c) << 3;
			code |= (gray_src.at<uchar>(row + 1, col ) > c) << 2;
			code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1;
			code |= (gray_src.at<uchar>(row , col ) > c) << 0;
			lbpImg.at<uchar>(row-1, col-1) = code;

		}
	}
	imshow("LBP", lbpImg);
	namedWindow("Expand LBP", CV_WINDOW_AUTOSIZE);
	createTrackbar("current_radius", "Expand LBP", &current_radius, max_count,Expand_LBP_demo);
	Expand_LBP_demo(0, 0);
	waitKey(0);
	return 0;


}
//扩展LBP demo
void Expand_LBP_demo(int, void *)
{
	int offset = current_radius * 2;
	Mat elbpImg = Mat::zeros(gray_src.rows-offset, gray_src.cols-offset, CV_8UC1);
	int numNeighbor = 8;
	for (int n = 0; n < numNeighbor; n++)
	{
		float x = current_radius * cos((2 * CV_PI*n) / numNeighbor);
		float y = current_radius * (-sin((2 * CV_PI*n) / numNeighbor));

		int fx = static_cast<int>(floor(x)); //向下取整,它返回的是小于或等于函数参数,并且与之最接近的整数
		int fy = static_cast<int>(floor(y));
		int cx = static_cast<int>(ceil(x)); //向上取整,它返回的是大于或等于函数参数,并且与之最接近的整数
		int cy = static_cast<int>(ceil(y));

		float ty = y - fy;
		float tx = x = fx;

		float w1 = (1 - tx)*(1 - ty);
		float w2 = (tx)*(1 - ty);
		float w3 = (1-tx)*(ty);
		float w4 = (tx)*(ty);

		for (int row = current_radius; row < (gray_src.rows-current_radius); row++)
		{
			for (int col = current_radius; col < (gray_src.cols- current_radius); col++)
			{
				float t = w1 * gray_src.at<uchar>(row + fy, col + fx) + w2 * gray_src.at<uchar>(row + fy, col + cx) +
					w3 * gray_src.at<uchar>(row + cy, col + fx) + w4 * gray_src.at<uchar>(row + cy, col + cx);
				elbpImg.at<uchar>(row - current_radius, col - current_radius) +=
					((t > gray_src.at<uchar>(row, col)) && (abs(t - gray_src.at<uchar>(row, col)) > std::numeric_limits<float>::epsilon())) << n;

			}
		}
		imshow("Expand LBP", elbpImg);
	}


}

运行结果:
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Daker_Huang/article/details/84980724