1. 程式人生 > 其它 >影象的特徵提取

影象的特徵提取

技術標籤:視覺演算法影象處理

特徵提取

特徵的評價標準

  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的呼叫。