欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

图像的特征提取

程序员文章站 2022-03-31 11:30:07
...

特征提取

特征的评价标准

  1. 特征应当容易提取
  2. 选取的特征应对噪声和不相关转换不敏感
  3. 应试图寻找最具有区分能力的特征

简单的区域描绘子及其MATLAB实现

在经过图像分割得到的各种感兴趣的区域之后,可以利用下面介绍的一些简单的区域描绘子作为代表该区域的特征。

MATLAB中,函数regionprops()是用于计算区域描绘子的有力工具,语法如下:

stats = regionprops(BW,properties)
stats = regionprops(CC,properties)
stats = regionprops(L,properties)
stats = regionprops(___,I,properties)
stats = regionprops(output,___)
  1. L是一个标记矩阵,通过前面介绍的连通区标注函数bwlabel()得到。
  2. 返回值D是一个长度为max(L( : ))的结构数组,该结构的域表示每个区域的不同度量,具体取决于properties指定要提取的度量类型。

‘Area’ 图像各个区域中像素总个数
‘BoundingBox’ 包含相应区域的最小矩形
‘Centroid’ 每个区域的质心(重心)
‘MajorAxisLength’ 与区域具有相同标准二阶中心矩的椭圆的长轴长度(像素意义下)
‘MinorAxisLength’ 与区域具有相同标准二阶中心矩的椭圆的短轴长度(像素意义下)
‘Eccentricity’ 与区域具有相同标准二阶中心矩的椭圆的离心率(可作为特征)
‘Orientation’ 与区域具有相同标准二阶中心矩的椭圆的长轴与x轴的交角(度)
‘Image’ 与某区域具有相同大小的逻辑矩阵
‘FilledImage’ 与某区域具有相同大小的填充逻辑矩阵
‘FilledArea’ 填充区域图像中的on像素个数
‘ConvexHull’ 包含某区域的最小凸多边形
‘ConvexImage’ 画出上述区域最小凸多边形
‘ConvexArea’ 填充区域凸多边形图像中的on像素个数
‘EulerNumber’ 几何拓扑中的一个拓扑不变量——欧拉数
‘Extrema’ 八方向区域极值点
‘EquivDiameter’ 与区域具有相同面积的圆的直径
‘Solidity’ 同时在区域和其最小凸多边形中的像素比例
‘Extent’ 同时在区域和其最小边界矩形中的像素比例
‘PixelIdxList’ 存储区域像素的索引下标
‘PixelList’ 存储上述索引对应的像素坐标

直方图及其统计特征

直方图常用统计特征包括以下几种:

  1. 均值:纹理平均亮度的度量
  2. 标准方差:纹理平均对比度的度量
  3. 平滑度:纹理亮度的相对平滑度度量,对于灰度一致的区域,平滑度R等于1,对于灰度级的值有着较大差异的区域,R等于零。
  4. 三阶矩:直方图偏斜性的度量
  5. 一致性:当区域中所有灰度值相等时该度量最大并由此处开始减小
  6. 熵:随机性的度量。熵越大表明随机性越大,信息量也就越大;反之确定性越大,已经都确定当然信息量就越小。

特征降维

PCA的MATLAB实现

coeff = pca(X)
coeff = pca(X,Name,Value)
[coeff,score,latent] = pca(___)
[coeff,score,latent,tsquared] = pca(___)
[coeff,score,latent,tsquared,explained,mu] = pca(___)

参数说明;

  1. X为原始样本组成n*d的矩阵,其每一行是一个样本特征向量,每一列表示样本特征向量的一维,如X是一个8乘2的样本矩阵,总共又8个样本,每个样本2维。
  2. COEFF:主成分分量,即变换空间的那些基向量,也是样本协方差矩阵的本征向量。
  3. SCORE:主成分,X的低维表示,即X中的数据在主成分分量上的投影
  4. latent:一个包含着样本协方差矩阵本征值的向量

快速PCA及其实现

PCA的计算中最主要的工作量是计算样本协方差矩阵的本征值和本征向量,但是当矩阵很大的时候,就会导致MATLAB出现内存耗尽的错误,即使内存足够的话,也会花费很多时间的。

MATLAB实现:

function [pcaA V] = fastPCA( A, k )  
% 快速PCA  
% 输入:A --- 样本矩阵,每行为一个样本  
%      k --- 降维至 k 维  
% 输出:pcaA --- 降维后的 k 维样本特征向量组成的矩阵,每行一个样本,列数 k 为降维后的样本特征维数  
%      V --- 主成分向量  
[r c] = size(A);  
% 样本均值  
meanVec = mean(A);  
% 计算协方差矩阵的转置 covMatT  
Z = (A-repmat(meanVec, r, 1));  
covMatT = Z * Z';  
% 计算 covMatT 的前 k 个本征值和本征向量  
[V D] = eigs(covMatT, k);  
% 得到协方差矩阵 (covMatT)' 的本征向量  
V = Z' * V;  
% 本征向量归一化为单位本征向量  
for i=1:k  
    V(:,i)=V(:,i)/norm(V(:,i));  
end  
% 线性变换(投影)降维至 k 维  
pcaA = Z * V;  
% 保存变换矩阵 V 和变换原点 meanVec  
save('mat.m','V','meanVec');

局部二进制模式

局部二进制模式(Local Binary Patterns,LBP)最早作为一种有效的纹理描述算子提出的,由于其对图像局部纹理特征的卓越描绘能力而获得十分广泛的应用。LBP特征具有很强的分类能力(Highly Discriminative),较高的计算效率并且对于单调的灰度变化具有不变性。

基本LBP

在整个逐行扫描过程结束后,会得到一个LBP响应图像,这个响应图像的直方图被称为LBP统计直方图,或LBP直方图,它常常被最为后续识别工作的特征,因此也被成为LBP特征。

LBP的主要思想是以某一点与其领域像素的相对灰度作为响应,正是这种相对机制使得LBP算子对于单带哦的灰度变化具有不变性,

圆形邻域的LBP算子

基本LBP算子可以被进一步推广为使用不同大小和形状的领域,采用圆形的邻域并结合双线性插值运算使操作者能够获得任意半径和任意数目的领域像素点,一个半径为2的8领域像素的圆形邻域,对于正好处于方格中心的邻域点(左,上,右,下)四个点,直接以该点所在方格的i像素值作为它的值;对于不在像素中心位置的邻域点(倾斜45度的四个黑点),通过双线性插值确定其值。

统一化LBP算子

由于LBP直方图大多是针对图像中的各个分区分别计算的,对于一个普通大小的分区区域,对于一个普通大小的分块区域,标准LBP算子得到的二进制模式数目(LBP直方图收集箱数目)较多,而实际的位于该分块区域的像素数目却相对的较少,这将会得到一个过于稀疏的直方图,从而使直方图失去统计意义。因此应该设法减少一些冗余的LBP模式,同时保留足够的具有重要意义描绘能力的模式。

LBP算子具有一定的半径,类似于模板操作,这里同样要注意LBP算子应用过程的边界问题。由于一般关心的是LBP统计直方图,而不是响应图像的本身,因此实现中一般不需要向外填充边界,而是直接在计算中不包括图像的边界部分。

应用LBP(u2)(8,2)算子到某个分块图像并获得直方图的实现程序如下:

%getLBPFea.m  
function [histLBP, MatLBP] = getLBPFea(I)  
% 计算分区图像 I 的LBP特征,(8,2),uniform  
%  
% 输入:I --- 分区图像  
%  
% 返回值: MatLBP --- LBP响应矩阵  
%               histLBP --- 1维行向量,LBP直方图  
  
% 获得分块图像I的大小  
[m n] = size(I);  
rad = 2;  
if (m <= 2*rad) || (n <= 2*rad)  
    error('I is too small to compute LBP feature!');  
end  
  
MatLBP = zeros(m-2*rad, n-2*rad);  
  
% 读入 LBP 映射(像素灰度与直方图收集箱索引的映射)  
load MatLBPMap.mat;  
  
for ii = 1+rad : m-rad  
    for jj = 1+rad : n-rad  
        nCnt = 1;  
          
          
        % 计算(8,2)邻域的像素值,不在像素中心的点通过双线性插值获得其值  
        nbPT(nCnt) = I(ii, jj-rad);  
        nCnt = nCnt + 1;  
          
        horInterp1 = I(ii-2, jj-2) + 0.5858*( I(ii-2, jj-1) - I(ii-2, jj-2) ); % 水平方向插值  
        horInterp2 = I(ii-1, jj-2) + 0.5858*( I(ii-1, jj-1) - I(ii-1, jj-2) ); % 水平方向插值  
        verInterp = horInterp1 + 0.5858*( horInterp2 - horInterp1 ); % 竖直方向插值  
        nbPT(nCnt) = verInterp;  
        nCnt = nCnt + 1;  
          
        nbPT(nCnt) = I(ii-2, jj);  
        nCnt = nCnt + 1;  
          
        horInterp1 = I(ii-2, jj+1) + 0.4142*( I(ii-2, jj+2) - I(ii-2, jj+1) );  
        horInterp2 = I(ii-1, jj+1) + 0.4142*( I(ii-1, jj+2) - I(ii-1, jj+1) );  
        verInterp = horInterp1 + 0.5858*( horInterp2 - horInterp1 );  
        nbPT(nCnt) = verInterp;  
        nCnt = nCnt + 1;  
          
        nbPT(nCnt) = I(ii, jj+2);  
        nCnt = nCnt + 1;  
          
        horInterp1 = I(ii+1, jj+1) + 0.4142*( I(ii+1, jj+2) - I(ii+1, jj+1) );  
        horInterp2 = I(ii+2, jj+1) + 0.4142*( I(ii+2, jj+2) - I(ii+2, jj+1) );  
        verInterp = horInterp1 + 0.4142*( horInterp2 - horInterp1 );  
        nbPT(nCnt) = verInterp;  
        nCnt = nCnt + 1;  
          
        nbPT(nCnt) = I(ii+2, jj);  
        nCnt = nCnt + 1;  
          
        horInterp1 = I(ii+1, jj-2) + 0.5858*( I(ii+1, jj-1) - I(ii+1, jj-2) );  
        horInterp2 = I(ii+2, jj-2) + 0.5858*( I(ii+2, jj-1) - I(ii+2, jj-1) );  
        verInterp = horInterp1 + 0.4142*( horInterp2 - horInterp1 );  
        nbPT(nCnt) = verInterp;  
                  
          
        for iCnt = 1:nCnt  
            if( nbPT(iCnt) >= I(ii, jj) )  
                MatLBP(ii-rad, jj-rad) = MatLBP(ii-rad, jj-rad) + 2^(nCnt-iCnt);  
            end  
        end  
    end  
end  
 
% 计算LBP直方图  
histLBP = zeros(1, 59); % 对于(8,2)的uniform直方图共有59个收集箱  
  
for ii = 1:m-2*rad  
    for jj = 1:n-2*rad  
        histLBP( vecLBPMap( MatLBP(ii, jj)+1 ) ) = histLBP( vecLBPMap( MatLBP(ii, jj)+1 ) ) + 1;  
    end  
end  

上述算法中围绕每一个中心点,从左侧开始,按照顺时针的顺序访问8个邻域,形成二进制模式位串。在计算直方图时借助vecLBPMap映射表将响应图像MatLBP中的像素灰度映射到其对应的收集箱编号。如灰度为gray(0<=gray<=255)的像素应落入第vecLBPMap(gray+1)号收集箱中。通过下面的函数makeLBPMap来获得映射表vecLBPMap。

function vecLBPMap = makeLBPMap  
% 生成(8,2)临域uniform LBP直方图的映射关系,即将256个灰度值映射到59个收集箱中,  
% 所有的非 uniform 放入一个收集箱中  
  
vecLBPMap = zeros(1, 256); %初始化映射表  
  
bits = zeros(1, 8); %8位二进模式串  
  
nCurBin = 1;  
  
for ii = 0:255  
    num = ii;  
      
    nCnt = 0;  
      
    % 获得灰度num的二进制表示bits  
    while (num)  
        bits(8-nCnt) = mod(num, 2);  
        num = floor( num / 2 );  
        nCnt = nCnt + 1;  
    end  
      
    if IsUniform(bits) % 判断bits是不是uniform模式  
        vecLBPMap(ii+1) = nCurBin;% 每个uniform模式分配一个收集箱  
        nCurBin = nCurBin + 1;  
    else  
        vecLBPMap(ii+1) = 59;%所有非uniform模式都放入第59号收集箱          
    end  
      
end  
  
% 保存映射表  
save('MatLBPMap.mat', 'vecLBPMap');

函数makeLBPMap中调用了IsUniform(bits)方法来检查二进制模式串bits是否是统一化模式(Uniform Patterns),IsUniform方法的实现如下:

function bUni = IsUniform(bits)  
% 判断某一个位串模式 bits 是否是 uniform 模式  
%  
% 输入:bits --- 二进制LBP模式串  
%  
% 返回值:bUni --- =1,if bits 是uniform模式串;=2,if bits 不是uniform模式串  
  
n = length(bits);  
  
nJmp = 0; % 位跳变数(0->1 or 1->0)  
for ii = 1 : (n-1)  
    if( bits(ii) ~= bits(ii+1) )  
        nJmp = nJmp+1;  
    end  
end  
if bits(n) ~= bits(1)  
    nJmp = nJmp+1;  
end  
  
if nJmp > 2  
    bUni = false;  
else  
    bUni = true;  
end  

MB-LBP及其MATLAB实现

理论基础

前述的基于像素相对灰度比较的LBP算子可以很精细地描述图像局部地纹理信息。然而,也正是由于这种特征地局部化特点,使它容易受到噪声的干扰而不够强壮,缺乏对图像整体信息的粗粒度把握。因此MB-LBP被提出以弥补传统LBP的这一不足。起初MB-LBP被作为标准3*3LBP扩展而引入,随后也被用于与LBP算子结合使用。在MB-LBP的计算中,传统LBP算子像素之间的比较被像素块之间的平均灰度的比较所代替,不同的像素块大小代表着不同的观察和分析粒度。

MATLAB实现

算法getMBLBPFea()的输入blocksize为块的大小,其默认值为1,即一块仅为一个像素,对应传统的LBP算子。为了求得I中各个像素块的值,首先计算像素块中像素的平均灰度,而后以此灰度平均值作为灰度值,求得了I的低分辨率表示I_MB,此后的阈值化操作只需要对I_MB进行,阈值化的过程和getLMBFeature()中类似。

function [histLBP, MatLBP, MatLBP_MB] = getMBLBPFea(I, blockSize) 
% 计算分块区域I的LBP特征,(8,2),uniform 
% 
% 输入:I --- 分区图像
%       blockSize --- MBLBP 中的分块大小,默认值为1 
% 
% 返回值: MatLBP --- LBP 响应矩阵
%        histLBP --- 行向量LBP直方图
%        MatLBP_MB --- MBLBP的像素块低分辨率显示
 
if nargin < 2 
    blockSize = 1; 
end 
 
%获得分块图像I的大小
[m n] = size(I); 
 
%将原始图像依据blockSize分块,计算每块的平均灰度值,对应保存在映射矩阵I_MB中
mSub = floor(m / blockSize); 
nSub = floor(n / blockSize); 
 
mRem = mod(m, blockSize); 
nRem = mod(n, blockSize); 
mRem = round(mRem / 2); 
nRem = round(nRem / 2); 
 
I_MB = zeros(mSub, nSub); 
 
for ii = 1:mSub 
    for jj = 1:nSub 
        I_center = I( 1+mRem:mRem+mSub*blockSize, 1+nRem:nRem+nSub*blockSize ); % 取中心区域,不够分出整块的留在两边
        SubRgn = I_center( (ii-1)*blockSize+1 : ii*blockSize, (jj-1)*blockSize+1 : jj*blockSize ); 
        I_MB(ii, jj) = mean( SubRgn(:) ); 
    end 
end 
 
 
 
% 剩下的任务就是对分块矩阵的映射I_MB计算blockSize = 1的uniform (8, 2) LBP特征了 
rad = 2; 
if (mSub <= 2*rad) || (nSub <= 2*rad) 
    error('I is too small to compute LBP feature!'); 
end 
 
MatLBP_MB = zeros(mSub-2*rad, nSub-2*rad); 
 
% 读入LBP映射(像素灰度与直方图收集箱索引的映射) 
load Mat/LBPMap.mat; 
 
for ii = 1+rad : mSub-rad 
    for jj = 1+rad : nSub-rad 
        nCnt = 1; 
         
         
        % 计算(8,2)邻域的像素值,不在像素中心的点通过双线性插值获得其值
        nbPT(nCnt) = I_MB(ii, jj-rad); 
        nCnt = nCnt + 1; 
         
        horInterp1 = I_MB(ii-2, jj-2) + 0.5858*( I_MB(ii-2, jj-1) - I_MB(ii-2, jj-2) ); % 水平方向插值
        horInterp2 = I_MB(ii-1, jj-2) + 0.5858*( I_MB(ii-1, jj-1) - I_MB(ii-1, jj-2) ); % 水平方向插值
        verInterp = horInterp1 + 0.5858*( horInterp2 - horInterp1 ); % 竖直方向插值
        nbPT(nCnt) = verInterp; 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii-2, jj); 
        nCnt = nCnt + 1; 
         
        horInterp1 = I_MB(ii-2, jj+1) + 0.4142*( I_MB(ii-2, jj+2) - I_MB(ii-2, jj+1) ); 
        horInterp2 = I_MB(ii-1, jj+1) + 0.4142*( I_MB(ii-1, jj+2) - I_MB(ii-1, jj+1) ); 
        verInterp = horInterp1 + 0.5858*( horInterp2 - horInterp1 ); 
        nbPT(nCnt) = verInterp; 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii, jj+2); 
        nCnt = nCnt + 1; 
         
        horInterp1 = I_MB(ii+1, jj+1) + 0.4142*( I_MB(ii+1, jj+2) - I_MB(ii+1, jj+1) ); 
        horInterp2 = I_MB(ii+2, jj+1) + 0.4142*( I_MB(ii+2, jj+2) - I_MB(ii+2, jj+1) ); 
        verInterp = horInterp1 + 0.4142*( horInterp2 - horInterp1 ); 
        nbPT(nCnt) = verInterp; 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii+2, jj); 
        nCnt = nCnt + 1; 
         
        horInterp1 = I_MB(ii+1, jj-2) + 0.5858*( I_MB(ii+1, jj-1) - I_MB(ii+1, jj-2) ); 
        horInterp2 = I_MB(ii+2, jj-2) + 0.5858*( I_MB(ii+2, jj-1) - I_MB(ii+2, jj-1) ); 
        verInterp = horInterp1 + 0.4142*( horInterp2 - horInterp1 ); 
        nbPT(nCnt) = verInterp; 
                 
         
        for iCnt = 1:nCnt 
            if( nbPT(iCnt) >= I_MB(ii, jj) ) 
                MatLBP_MB(ii-rad, jj-rad) = MatLBP_MB(ii-rad, jj-rad) + 2^(nCnt-iCnt); 
            end 
        end 
    end 
end 
 
% 还原MatLBP_MB 
MatLBP = zeros(m-2*rad*blockSize, n-2*rad*blockSize); 
for ii = 1:mSub-2*rad 
    for jj = 1:nSub-2*rad 
        MatLBP( mRem+(ii-1)*blockSize+1 : mRem+ii*blockSize, nRem+(jj-1)*blockSize+1 : nRem+jj*blockSize ) = MatLBP_MB(ii, jj); 
    end 
end 
 
 
% 计算LBP直方图
histLBP = zeros(1, 59); % 对(8,2)的uniform直方图共有59个收集箱 
 
for ii = 1:mSub-2*rad 
    for jj = 1:nSub-2*rad 
        histLBP( vecLBPMap( MatLBP_MB(ii, jj)+1 ) ) = histLBP( vecLBPMap( MatLBP_MB(ii, jj)+1 ) ) + 1; 
    end 
end 

提取MB-LMP特征

function [histLBP, MatLBP, MatLBP_MB] = getMBLBPFea_33(I, blockSize) 
% 计算分区图像 I 的LBP特征,3*3,uniform 
% return value: MatLBP --- LBP 响应矩阵 
%               histLBP --- 行向量,LBP直方图 
%               blockSize --- MBLBP中的分块大小,默认值为1
% 
% 输入:I --- 分区图像 
%       blockSize --- 块的大小
% 
% 返回值: MatLBP --- LBP 响应矩阵 
%        histLBP --- 行向量,LBP直方图 
%        MatLBP_MB --- MBLBP的像素块低分辨率表示 
 
if nargin < 2 
    blockSize = 1; 
end 
 
% 获得分块图像I的大小
[m n] = size(I); 
 
 
%将原始图像依据blockSize分块,计算每块的平均灰度值,对应保存在映射矩阵I_MB中
mSub = floor(m / blockSize); 
nSub = floor(n / blockSize); 
 
mRem = mod(m, blockSize); 
nRem = mod(n, blockSize); 
mRem = round(mRem / 2); 
nRem = round(nRem / 2); 
 
I_MB = zeros(mSub, nSub); 
 
for ii = 1:mSub 
    for jj = 1:nSub 
        I_center = I( 1+mRem:mRem+mSub*blockSize, 1+nRem:nRem+nSub*blockSize ); % 取中心区域,不够分出整块的留在两边
        SubRgn = I_center( (ii-1)*blockSize+1 : ii*blockSize, (jj-1)*blockSize+1 : jj*blockSize ); 
        I_MB(ii, jj) = mean( SubRgn(:) ); 
    end 
end 
 
 
 
% 剩下的任务就是对分块矩阵的映射I_MB计算blockSize = 1的uniform 3*3 LBP特征了 
rad = 1; 
if (mSub <= 2*rad) || (nSub <= 2*rad) 
    error('I is too small to compute LBP feature!'); 
end 
 
MatLBP_MB = zeros(mSub-2*rad, nSub-2*rad); 
 
% 读入LBP映射(像素灰度与直方图收集箱索引的映射) 
load Mat/LBPMap.mat; 
 
for ii = 1+rad : mSub-rad 
    for jj = 1+rad : nSub-rad 
        nCnt = 1; 
         
         
        % 计算3*3邻域的像素值
        nbPT(nCnt) = I_MB(ii-rad, jj-rad); 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii-rad, jj); 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii-rad, jj+rad); 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii, jj+rad); 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii+rad, jj+rad); 
        nCnt = nCnt + 1; 
         
        nbPT(nCnt) = I_MB(ii+rad, jj); 
        nCnt = nCnt + 1; 
 
        nbPT(nCnt) = I_MB(ii+rad, jj-rad); 
        nCnt = nCnt + 1; 
 
        nbPT(nCnt) = I_MB(ii, jj-rad); 
 
                 
         
        for iCnt = 1:nCnt 
            if( nbPT(iCnt) >= I_MB(ii, jj) ) 
                MatLBP_MB(ii-rad, jj-rad) = MatLBP_MB(ii-rad, jj-rad) + 2^(nCnt-iCnt); 
            end 
        end 
    end 
end 
 
% 还原MatLBP_MB 
MatLBP = zeros(m-2*rad*blockSize, n-2*rad*blockSize); 
for ii = 1:mSub-2*rad 
    for jj = 1:nSub-2*rad 
        MatLBP( mRem+(ii-1)*blockSize+1 : mRem+ii*blockSize, nRem+(jj-1)*blockSize+1 : nRem+jj*blockSize ) = MatLBP_MB(ii, jj); 
    end 
end 
 
 
% 计算LBP直方图 
histLBP = zeros(1, 59); % 对于(8,2)的uniform直方图共有59个收集箱 
 
for ii = 1:mSub-2*rad 
    for jj = 1:nSub-2*rad 
        histLBP( vecLBPMap( MatLBP_MB(ii, jj)+1 ) ) = histLBP( vecLBPMap( MatLBP_MB(ii, jj)+1 ) ) + 1; 
    end 
end 

图像分区以及MATLAB实现

直方图无法描述图像的结构信息,而图像的各个区域的局部特征往往差异较大,如果仅对整个图像生成一个LBP直方图,这些局部差异信息就会丢失。分区LBP特征可有效解决这一问题。

具体的方法是将一幅图适当的划分为P*Q个分区,然后分别计算每个图像分区的直方图特征,最后再将所有块的直方图特征连接成一个复合的特征向量作为代表整个图像的LBP直方图特征。

编写的函数用来提取图像I的分区LBP特征。其输入r和c分别代表的是分区的行数和列数,nMB给出MB-LBP像素块的大小。函数返回一个向量,它是图像I的复合LBP特征。

function histLBP = getLBPHist(I, r, c, nMB) 
% 取得I的分区LBP直方图 
% 
% 输入:r,c --- r*c个分区
%       nMB --- MB-LBP 中块的大小
% 
% 返回值:histLBP ---  连接 I 的各个分块LBP直方图而形成的代表 I 的LBP复合特征向量 
 
[m n] = size(I); 
 
% 计算分区的大小
mPartitionSize = floor(m / r); 
nPartitionSize = floor(n / c); 
 
for ii = 1:r-1 
    for jj = 1:c-1 
        Sub = I( (ii-1)*mPartitionSize+1:ii*mPartitionSize, (jj-1)*nPartitionSize+1:jj*nPartitionSize ); 
%        hist{ii}{jj} = getMBLBPFea( Sub, nMB );  %如需提取3*3LBP,请注释此行
        hist{ii}{jj} = getMBLBPFea_33( Sub, nMB );   %如需提取3*3LBP,请打开此注释
    end 
end 
 
 
% 处理最后一行和最后一列
clear Sub 
for ii = 1:r-1 
    Sub = I( (ii-1)*mPartitionSize+1:ii*mPartitionSize, (c-1)*nPartitionSize+1:n ); 
%    hist{ii}{c} = getMBLBPFea(Sub, nMB); 
    hist{ii}{c} = getMBLBPFea_33( Sub, nMB ); 
end 
clear Sub 
 
for jj = 1:c-1 
    Sub = I( (r-1)*mPartitionSize+1:m, (jj-1)*nPartitionSize+1:jj*nPartitionSize ); 
%    hist{r}{jj} = getMBLBPFea(Sub, nMB); 
    hist{r}{jj} = getMBLBPFea_33( Sub, nMB ); 
end 
clear Sub 
 
Sub = I((r-1)*mPartitionSize+1:m, (c-1)*nPartitionSize+1:n); 
%hist{r}{c} = getMBLBPFea(Sub, nMB); 
hist{r}{c} = getMBLBPFea_33( Sub, nMB ); 
 
 
% 连接各个分块的LBP直方图形成复合特征向量
histLBP = zeros(1, 0); 
for ii = 1:r 
    for jj = 1:c 
        histLBP = [histLBP hist{ii}{jj}]; 
    end 
end 

在默认的情况下函数getLBPHist()提取(8,2)圆形邻域的LBP特征。如果需要提取3*3的LBP特征,可以将代码中的getMBLBPFea的调用替换为getMBLBPFea_33的调用。