旋转不变的LBP特征可视化+等价模式的LBP可视化

LBP

LBP原理参见其他博主博客,旋转不变性是通过寻找八位数的最小值实现的
窗口如下
(v-1,w-1)| (v-1,w) | (v-1,w+1)
(v,w-1) | (v,w) | (v,w+1)
(v+1,w-1)| (v+1,w) | (v+1,w+1)
直接上代码

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>

using namespace std;
using namespace cv;


//求最小的的特征值
int smallest(int a[])
{
	int temp = 256;
	int down_num;
	for (int j = 0; j < 8; j++)
	{
		int Lbp = 0,ii=0;
		for (int k = j; k < 8+j; k++,ii++)
		{
			down_num = k % 8;
			//for(int ii=0;ii<8;ii++)
			Lbp = a[down_num]*pow(2, ii) + Lbp;
		}
		if (temp > Lbp)
			temp = Lbp;
	}
	return temp;
}
//旋转不变圆形LBP,考虑到我只考虑了八个采样点的情况,这时圆形与3*3效果相当,此处用的是3*3的窗口
void rotation_invariant_LBP(Mat image,Mat output)
{
	//边缘置0
	for (int v = 0; v < output.rows; v++)
	{
		output.at<uchar>(v, 0) = 0;
		output.at<uchar>(v, output.cols - 1) = 0;
	}
	for (int w = 0; w < output.cols; w++)
	{
		output.at<uchar>(0, w) = 0;
		output.at<uchar>(output.rows - 1, w) = 0;
	}
	//进行窗口扫描
	for (int w = 1; w < output.cols - 1; w++)
	{
		for (int v = 1; v < output.rows - 1; v++)
		{
			int a[8] = { 1,1,1,1,1,1,1,1 };
			if (image.at<uchar>(v, w) > image.at<uchar>(v - 1, w - 1))
				a[0] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v - 1, w))
				a[1] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v - 1, w + 1))
				a[2] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v , w + 1))
				a[3] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v + 1, w + 1))
				a[4] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v + 1, w))
				a[5] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v + 1, w - 1))
				a[6] = 0;
			if (image.at<uchar>(v, w) > image.at<uchar>(v, w - 1))
				a[7] = 0;
			output.at<uchar>(v,w)=smallest(a);
		}
	}
}
//跳变次数获取
int getHopCount(uchar i)
{
	int a[8] = { 0 };
	int k = 7;
	int cnt = 0;
	while (i)
	{
		a[k] = i & 1;
		i >>= 1;
		--k;
	}
	for (int k = 0; k < 8; ++k)
	{
		if (a[k] != a[k + 1 == 8 ? 0 : k + 1])
		{
			++cnt;
		}
	}
	return cnt;
}
//59个等价模式
void lbp59table(uchar* table)
{
	memset(table, 0, 256);
	uchar temp = 1;
	for (int i = 0; i < 256; ++i)
	{
		if (getHopCount(i) <= 2)
		{
			table[i] = temp;
			temp++;
		}
		// printf("%d\n",table[i]);  
	}
}

void LBP_dengjia(Mat src, Mat dst)
{
	int width = src.rows;
	int height = src.cols;
	uchar table[256];
	lbp59table(table);
	for (int j = 1; j < width - 1; j++)
	{
		for (int i = 1; i < height - 1; i++)
		{
			uchar neighborhood[8] = { 0 };
			neighborhood[7] = src.at<uchar>(j, i - 1);
			neighborhood[6] = src.at<uchar>(j + 1, i - 1);
			neighborhood[5] = src.at<uchar>(j + 1, i);
			neighborhood[4] = src.at<uchar>(j + 1, i + 1);
			neighborhood[2] = src.at<uchar>(j - 1, i + 1);
			neighborhood[1] = src.at<uchar>(j - 1, i);
			neighborhood[0] = src.at<uchar>(j - 1, i - 1);
			uchar center = src.at<uchar>(j, i);
			uchar temp = 0;

			for (int k = 0; k < 8; k++)
			{
				temp += (neighborhood[k] >= center) << k;
			}
			dst.at<uchar>(j, i) = table[temp];
		}
	}
}
void main()
{
	Mat input = imread("D:a2.jpeg");
	Mat output1,output2;
	cvtColor(input, input,COLOR_RGB2GRAY);
	output1 = input.clone();
	output2 = input.clone();
	rotation_invariant_LBP(input, output1);
	LBP_dengjia(input, output2);
	namedWindow("1", 0);
	namedWindow("2", 0);
	namedWindow("3", 0);
	imshow("1", input);
	imshow("2", output1);
	imshow("3", output2);
	waitKey(0);
}

结果如下
原灰度图如下
在这里插入图片描述
旋转不变的结果
在这里插入图片描述
等价模式

在这里插入图片描述
等价模式与旋转不变的结果图不同的原因:比较准则不同,一个是大于则置1,一个是大于则置0,反映的内容是一样的

以下是MATLAB中旋转不变LBP特征提取的代码: ```matlab function lbp_feat = rotation_invariant_lbp(img, radius, neighbors) % img: 输入的图像 % radius: LBP算子半径 % neighbors: LBP算子采样点数 % lbp_feat: LBP特征 if nargin < 3 neighbors = 8; end if nargin < 2 radius = 1; end % 获取图像尺寸 [rows, cols] = size(img); % 初始化LBP特征lbp_feat_map = zeros(rows, cols); % 计算LBP特征图 for i = 1 : rows for j = 1 : cols lbp_feat_map(i,j) = get_lbp_pixel(img, i, j, radius, neighbors); end end % 计算旋转不变LBP特征 lbp_feat = zeros(1, 2^neighbors); for i = 0 : neighbors-1 % 将特征图沿着采样点方向旋转 lbp_feat_map_rotated = imrotate(lbp_feat_map, i*360/neighbors, 'nearest', 'crop'); % 计算LBP直方图 lbp_hist = histcounts(lbp_feat_map_rotated(:), 0:2^neighbors); % 更新LBP特征 lbp_feat = lbp_feat + lbp_hist; end % 归一化LBP特征 lbp_feat = lbp_feat / sum(lbp_feat); end function lbp_pixel = get_lbp_pixel(img, row, col, radius, neighbors) % img: 输入的图像 % row, col: 中心像素坐标 % radius: LBP算子半径 % neighbors: LBP算子采样点数 % lbp_pixel: LBP像素值 % 获取图像尺寸 [rows, cols] = size(img); % 初始化采样点坐标 sample_points = zeros(neighbors, 2); % 计算采样点坐标 for i = 1 : neighbors theta = 2*pi*(i-1)/neighbors; sample_points(i,1) = row + radius*cos(theta); sample_points(i,2) = col - radius*sin(theta); end % 处理采样点坐标越界的情况 sample_points(sample_points(:,1)<1 | sample_points(:,1)>rows | sample_points(:,2)<1 | sample_points(:,2)>cols, :) = []; % 计算LBP像素值 lbp_pixel = 0; for i = 1 : size(sample_points, 1) if img(round(sample_points(i,1)), round(sample_points(i,2))) >= img(row, col) lbp_pixel = lbp_pixel + 2^(i-1); end end end ``` 使用方法: ```matlab % 读取图像 img = imread('lena.png'); % 计算旋转不变LBP特征 lbp_feat = rotation_invariant_lbp(img, 1, 8); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值