二、圆形LBP算子的matlab代码
原始LBP特征只能通过固定范围内的像素点的灰度值求解纹理特征图像的编码值,若一个图像,需要转换成不同尺度的图像进行处理时(比如进行放大缩小操作),纹理特征图像的编码值将会随着尺寸大小的变化而发生变换,图像的纹理细节将不能准确的反映出来,这显然不能满足生产需求的要求。设计利用MATLAB实现的圆形改进的LBP算法,是在原始LBP算子的基础上进行改进的一个算法。为了达到处理不同尺寸大小的纹理特征的要求,能够更好的处理大尺度图像,该算法将原先的3x3区域扩充到任意区域,邻域个数、区域半径都可以根据用户的选取来自行确定最佳的参数。其中心思想就是通过参数设定,设置不同的半径,不同的邻域来对中心像素进行编码。圆形LBP算子的计算公式如式2-3所示。
其中,n表示圆形区域中总计P个采样点中的第n个采样点,I(c)表示中心像素点的灰度值,I(n)表示圆形邻域像素点中的第n个像素点的灰度值。圆形边界上的像素点灰度值计算公式如式2-4所示。
看一眼圆形LBP算子的伪代码:
Algorithm 2:R_LBP | ||
Input:文件后缀为tif、jpg、png的图像文件image if image.model !=灰度图像 then 采用系数精度为16位的灰度计算公式,转灰度图像imgG; else imgG=image; [height,width]=size(imgG); img_lbp=int32(zeros([height width])); 通过用户输入获取半径(R)和圆形邻域个数(neighbors); for n=1:neighbors rx = R * cos(2 *pi* n / neighbors); ry = -R * sin(2.0 * pi * n / neighbors); x1 = ceil(rx); y1 = ceil(ry); 根据坐标偏移量求圆形邻域所在位置对应的权重w1、w2、w3、w4; for i=1:height for j=1:width 根据双线性插值法、邻域所在方格imgG值及相应权重求出邻域对应 的灰度值point_G; if point_G > center then label = 1; else label = 0; %bitor:按位与函数 bitshift:按位左移函数 img_lbp(i,j)=bitor(img_lbp(i,j),bitshift(img_lbp(i,j),neighbors-n)); if 2的neighbors次方!=256 then %归一化 standard=power(2,neighbors)-1; imglbp(i,j)=255*imglbp(i,j)/standard; Output:无符号的8位精度整形矩阵(img_lbp) |
再看其matlab代码。
function [R_lbp_image] = R_LBP(image)
%UNTITLED4 此处显示有关此函数的摘要
% 此处显示详细说明
h = findobj('Tag','edit4');
edit4_string = get(h,'String');
radius = str2double(edit4_string);
h = findobj('Tag','edit5');
edit5_string = get(h,'String');
neighbors = str2double(edit5_string);
%figure;imshow(image);
[h,w,model] = size(image);
imgG=uint8(zeros([h w]));
if model == 3
%imgG = rgb2gray(image);
for i = 1:w %宽度
for j = 1:h %长度(高度)
r=int32(image(j,i,1)); %红色分量
g=int32(image(j,i,2)); %绿色分量
b=int32(image(j,i,3)); %蓝色分量
%彩色转灰度,通过设置二值化的位数可以提高二值化的精度,使二值化的效果更加清晰
%CenterValue=bitshift((r*38+g*75+b*15),-7);
imgG(j,i)=bitshift((r*19595+g*38469+b*7472),-16);
end
end
else
imgG = image;
end
[rows, cols] = size(imgG);
rows=int16(rows);
cols=int16(cols);
imglbp = int32(zeros(rows, cols));%不一致,问题出在这里
for i=1:rows %高度减半径
for j=1:cols %宽度减半径
center = imgG(i, j); %先高再宽
for k=0:neighbors-1
% 计算采样点对于中心点坐标的偏移量rx,ry
rx = radius * cos(2.0 * pi * k / neighbors);
ry = -radius * sin(2.0 * pi * k / neighbors); %顺时针
% 对采样点偏移量分别进行上下取整
x1 = floor(rx);
x2 = ceil(rx);%向上取整
y1 = floor(ry);
y2 = ceil(ry);
% 将坐标偏移量映射到0-1之间
tx = rx - x1;
ty = ry - y1;
% 根据0-1之间的x,y的权重计算公式计算权重,权重与坐标具体位置无关,与坐标间的差值有关
w1 = (1-tx) * (1-ty);
w2 = tx * (1-ty);
w3 = (1-tx) * ty;
w4 = tx * ty;
% 根据双线性插值公式计算第k个采样点的灰度值
if (0<i+x1 && i+x1<rows) && (0<j+y1 && j+y1<cols) && (0<i+x2 && i+x2<rows) && (0<j+y2 && j+y2<cols)
point_G = imgG(i+x1, j+y1)*w1 + imgG(i+x1, j+y2)*w2 + imgG(i+x2, j+y1)*w3 + imgG(i+x2, j+y2)*w4;
else
point_G=center;
end
% LBP特征图像的每个邻居的LBP值累加,累加通过与操作完成,对应的LBP值通过移位取得
if point_G > center %等于center的领域我们认为没有纹理改变,编码为0
label = 1;
else
label = 0;
end
imglbp(i, j) = bitor(imglbp(i, j), bitshift(label, neighbors-k-1));%按位与,按位左移
end
%归一化
%if neighbors>8
standard=power(2,neighbors)-1;
imglbp(i,j)=255*imglbp(i,j)/standard;
%end
end
end
R_lbp_image=uint8(imglbp);
%imshow(imglbp);
figure;imshow(R_lbp_image);
end
注释已经讲得挺明白了,不清楚的地方可以调试看一下中间过程。双线性插值,是在单线性插值的基础上进行延伸的,就是从一个方向到需要考虑两个方向的变化,按照距离来定权重。
还需要注意一点就是,matlab中图像的坐标起点在左上角,往下是x,往右是y轴,跟我们人看的不一样。矩阵则跟我们人看的一样。