1. 程式人生 > >HOG matlab 程式碼

HOG matlab 程式碼

Histograms of Oriented Gradients (HOG)的matlab原始碼

2011年4月21日 | 分類: 科研 | 標籤: HOG, matlab, 特徵描述子

最近想把一些常用的演算法實驗一下。一來可以加深理解,畢竟實驗結果更加直觀;二來也想練習下matlab,還是寫的少,需要後面的實驗做準備。

昨天把HOG descriptor實現了一下,參考了TimeHandle's Blog的原始碼。儘量地使程式碼更加簡潔,也更容易理解,不過對完整的HOG演算法做了一點簡化(將RGB影象直接轉換為灰度影象,省略了三線性差值的步驟)。具體的程式碼如下:

function HOGFeature = ImgHOGFeature( imgPathName, cell_size, nblock,...,
    overlap, angle, bin_num)
% 計算輸入影象的特徵描述子
% imgPathName:圖片路徑
% cell_size: cell的長寬
% nblock: block的width、height包括的cell的個數
% overlap: block重疊的比例
% angle: 180\360
% bin_num: 方向bin的數目
 
if nargin<2
    % default parameter
cell_size=8; nblock=2; overlap=0.5; angle=180; bin_num=9; elseif nargin<6 error('Input parameters are not enough.'); end   Img = imread(imgPathName); if size(Img,3) == 3 % 簡化計算,直接轉換成灰度影象 G = rgb2gray(Img); else G = Img; end   [height, width] = size(G);   % 計算x、y方向的梯度
hx = [-1,0,1]; hy = -hx'; grad_x = imfilter(double(G),hx); grad_y = imfilter(double(G),hy);   % 計算梯度的模長 grad_mag=sqrt(grad_x.^2+grad_y.^2);   % 計算梯度的方向 index= grad_x==0; grad_x(index)=1e-5; YX=grad_y./grad_x; if angle==180 grad_angle= ((atan(YX)+(pi/2))*180)./pi; elseif angle==360 grad_angle= ((atan2(grad_y,grad_x)+pi).*180)./pi; end   % orient bin bin_angle=angle/bin_num; grad_orient=ceil(grad_angle./bin_angle);   % 計算block的個數 block_size=cell_size*nblock; skip_step=block_size*overlap; x_step_num=floor((width-block_size)/skip_step+1); y_step_num=floor((height-block_size)/skip_step+1);   % 初始化hog特徵描述子 feat_dim=bin_num*nblock^2; HOGFeature=zeros(feat_dim,x_step_num*y_step_num);   for k=1:y_step_num for j=1:x_step_num % block的左上角座標 x_off = (j-1)*skip_step+1; y_off = (k-1)*skip_step+1;   % 取得block的梯度大小和方向 b_mag=grad_mag(y_off:y_off+block_size-1,x_off:x_off+block_size-1); b_orient=grad_orient(y_off:y_off+block_size-1,x_off:x_off+block_size-1);   % 當前block的hog直方圖 currFeat = BinHOGFeature(b_mag, b_orient, cell_size,nblock, bin_num, false); HOGFeature(:, (k-1)*x_step_num+j) = currFeat;   end end   end
function blockfeat = BinHOGFeature( b_mag,b_orient,cell_size,nblock,...
    bin_num, weight_vote)
% 計算1個block的hog
% weight_vote: 是否進行高斯加權投票
 
% block的HOG直方圖
blockfeat=zeros(bin_num*nblock^2,1);
 
% 高斯權重
gaussian_weight=fspecial('gaussian',cell_size*nblock,0.5*cell_size*nblock);
 
% 分割block
for n=1:nblock
    for m=1:nblock
        % cell的左上角座標
        x_off = (m-1)*cell_size+1;
        y_off = (n-1)*cell_size+1;
 
        % cell的梯度大小和方向
        c_mag=b_mag(y_off:y_off+cell_size-1,x_off:x_off+cell_size-1);
        c_orient=b_orient(y_off:y_off+cell_size-1,x_off:x_off+cell_size-1);
 
        % cell的hog直方圖
        c_feat=zeros(bin_num,1);
        for i=1:bin_num
            % 是否進行高斯加權 投票
            if weight_vote==false
                c_feat(i)=sum(c_mag(c_orient==i));
            else
                c_feat(i)=sum(c_mag(c_orient==i).*gaussian_weight(c_orient==i));
            end
        end
 
        % 合併到block的HOG直方圖中
        count=(n-1)*nblock+m;
        blockfeat((count-1)*bin_num+1:count*bin_num,1)=c_feat;
    end
end
 
% 歸一化 L2-norm
sump=sum(blockfeat.^2);
blockfeat = blockfeat./sqrt(sump+eps^2);