Advertisement

目标图像特征提取算子(HOG)

阅读量:

1、简介

HOG(Histograms of Oriented Gradients,方向梯度直方图)最初是在2005年的CVPR会议上由法国研究员Dala提出来的,主要用来进行行人检测。目前HOG+SVM已经被广泛应用到目标检测和分类等领域。博主主要用HOG+SVM方法进行手势分类,原文请参考:“Histograms of Oriented Gradients for Human Detection“。

2、算法实现 核心思想:

①将图像检测窗口分成许多空间区域单元(cells),在每一个cell中计算一维梯度方向或者边缘方向直方图;

②若干个cells组成一个block,一个block中的梯度方向直方图是由这若干个cells的梯度方向直方图组成,为了

对光照、阴影等鲁棒,需要对block进行对比度归一化处理;

③实际上所有的block之间是有重叠的(重叠的区域为一个cell,后面会具体讲道),将检测窗口的所有blocks的

梯度直方图连接起来就形成了整个检测窗口的梯度方向直方图(HOG)描述子。

具体过程:

(1)Gamma/Colour Normalization

Gamma校正方式为 I(x,y) = [ I(x,y) ] ^Gamma 。基于人眼处理图像的方式,一般取Gamma=0.5。此过程主要是为了调节图像对比度、减少光照影响、抑制噪声干扰。

原文提到:在灰度图像、RGB图像和LAB色彩空间进行的Gamma校正对结果只有少许的影响,是因为在后续阶段对block进行了归一化处理。对每一个颜色通道进行的颜色归一化处理结果并不理想,所以一般对灰度图像进行Gamma校正即可。

(2)Gradient Computation

为了降低灰度图像的早点,线采用离散高斯平滑模板进行平滑,高斯函数在不同平滑的尺度下进行对灰度图像进行平滑操作,然后采用[-1 ,0 ,1]的差分模板进行梯度计算。求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。水平和垂直方向上梯度计算公式如下:

原文提到:人体检测效果最佳(即不做高斯平滑),使得错误率缩小了约一倍。不做平滑操作,可能原因:图像是基于边缘的,平滑会降低边缘信息的对比度,从而减少图像中的信号信息。对于彩色图像,分别计算每个颜色通道的梯度,然后选择最大范数的梯度作为该像素的梯度向量。

(3)Spatial / Orientation Binning

**** 每个像素计算出一个权重投票,局部空间区域(cells)中投票权重累积到各个方向条(bins)上,权重计算公式为:

方向角范围可以为[0° 180°],也可以为[0° 360°],方向角计算公式为:

原文提到:权重计算可以为幅值本身,幅值平方,幅值平方根和二值边缘表述。文中实验结果显示为梯度幅值本身时效果最好(然而在实际使用中与采用上式的权重计算公式并没有卵的差别)。为了减少走样,相邻的bins的投票在方向和位置上采取双线性插值方法。而且方向角为[0° 180°]是效果最好。

那么将180°分为多少个bins时效果最好呢?

实验表明:将180°分为9个bins时效果最好,也就是说每个bin包括20°的角度范围。

原文提到:对于行人检测来说,由于衣服和背景的颜色变化范围较大,可能会导致[0° 360°]的效果差些。或许在目标任务识别(轿车,摩托车)等方面,[0° 360°]范围的效果较好。

**(4)**Normalization and Descriptor Blocks

由于局部光照和前后景的对比,梯度强度变化范围会很大,所以有效的对比度归一化可以提高效果。选取的block之间有重叠,所以每一个标量cell响应都会对最终的描述子向量有所贡献,不同的blocks需要归一化。

block的选取哪种方式好呢?

原文提到:选取正方形的cell结果较好,而且当每个cell包含6×68×8,每个bolck包含2×23×3时效果最好。

bolck该选择什么方式归一化呢?

常见的归一化形式有:

该算子的关键在于行人轮廓与背景之间的对比,而不是内部边缘或者轮廓与前景的对比,所以行人穿着或者姿势变化时对该算子影响不大。

测试代码如下:

复制代码
 im = imread('1(1).jpg');

    
 if size(im,3) == 3
    
     im = rgb2gray(im);
    
 end
    
 im = double(im);
    
 rows = size(im,1);
    
 cols = size(im,2);
    
 %h = fspecial('gaussian');
    
 %im = imfilter(im,h);
    
 %figure,imshow(im,[]);
    
 im = im.^0.5;   % gamma calibration
    
 %figure,imshow(im,[]);
    
 Ix = im;
    
 Iy = im;
    
 for i = 1:rows-2   % Calculate the gradient in X and Y direction
    
     Iy(i,:) = im(i+2,:)-im(i,:);
    
 end
    
     Iy(rows-1,:) = Iy(rows-2,:);
    
     Iy(rows,:) = Iy(rows-2,:);
    
 for j = 1:cols-2
    
     Ix(:,j) = im(:,j+2)-im(:,j);
    
 end
    
     Ix(:,cols-1) = Ix(:,cols-2);
    
     Ix(:,cols) = Ix(:,cols-2);
    
 angle = atand(Iy./Ix);% Calculate the angle and magnitude of 
    
 angle = imadd(angle,90);
    
 magtu = sqrt(Ix.^2+Iy.^2);
    
 angle(isnan(angle)) = 0;% Remove NaN
    
 magtu(isnan(magtu)) = 0;
    
 %figure,imshow(angle,[]);
    
 %figure,imshow(magtu,[]);
    
 hog_feature = [];
    
 %Find every block
    
 for i = 1:rows/8-1
    
     for j = 1:cols/8-1
    
     angle_block = angle((i-1)*8+1:(i-1)*8+16,(j-1)*8+1:(j-1)*8+16);
    
     magtu_block = magtu((i-1)*8+1:(i-1)*8+16,(j-1)*8+1:(j-1)*8+16);
    
     %magtu_block = imfilter(mag_block,gaussian);
    
     block_feature = [];
    
     %Find every cell in a block
    
     for ii = 1:2
    
         for jj = 1:2
    
             angle_cell = angle_block((ii-1)*8+1:(ii-1)*8+8,(jj-1)*8+1:(jj-1)*8+8);
    
             magtu_cell = magtu_block((ii-1)*8+1:(ii-1)*8+8,(jj-1)*8+1:(jj-1)*8+8);
    
             %Find every pixel's belonged bins
    
             hist_cell = zeros(1,9);
    
             for p = 1:8
    
                 for q = 1:8
    
                     % Bi_linear Interpolation
    
                     if angle_cell(p,q)>10 && angle_cell(p,q)<=30
    
                         hist_cell(1)=hist_cell(1)+magtu_cell(p,q)*(30-angle_cell(p,q))/20;
    
                         hist_cell(2)=hist_cell(2)+magtu_cell(p,q)*(angle_cell(p,q)-10)/20;
    
                     elseif angle_cell(p,q)>30 && angle_cell(p,q)<=50
    
                         hist_cell(2)=hist_cell(2)+magtu_cell(p,q)*(50-angle_cell(p,q))/20;
    
                         hist_cell(3)=hist_cell(3)+magtu_cell(p,q)*(angle_cell(p,q)-30)/20;
    
                     elseif angle_cell(p,q)>50 && angle_cell(p,q)<=70
    
                         hist_cell(3)=hist_cell(3)+magtu_cell(p,q)*(70-angle_cell(p,q))/20;
    
                         hist_cell(4)=hist_cell(4)+magtu_cell(p,q)*(angle_cell(p,q)-50)/20;
    
                     elseif angle_cell(p,q)>70 && angle_cell(p,q)<=90
    
                         hist_cell(4)=hist_cell(4)+magtu_cell(p,q)*(90-angle_cell(p,q))/20;
    
                         hist_cell(5)=hist_cell(5)+magtu_cell(p,q)*(angle_cell(p,q)-70)/20;
    
                     elseif angle_cell(p,q)>90 && angle_cell(p,q)<=110
    
                         hist_cell(5)=hist_cell(5)+magtu_cell(p,q)*(110-angle_cell(p,q))/20;
    
                         hist_cell(6)=hist_cell(6)+magtu_cell(p,q)*(angle_cell(p,q)-90)/20;
    
                     elseif angle_cell(p,q)>110 && angle_cell(p,q)<=130
    
                         hist_cell(6)=hist_cell(6)+magtu_cell(p,q)*(130-angle_cell(p,q))/20;
    
                         hist_cell(7)=hist_cell(7)+magtu_cell(p,q)*(angle_cell(p,q)-110)/20;
    
                     elseif angle_cell(p,q)>130 && angle_cell(p,q)<=150
    
                         hist_cell(7)=hist_cell(7)+magtu_cell(p,q)*(150-angle_cell(p,q))/20;
    
                         hist_cell(8)=hist_cell(8)+magtu_cell(p,q)*(angle_cell(p,q)-130)/20;
    
                     elseif angle_cell(p,q)>150 && angle_cell(p,q)<=170
    
                         hist_cell(8)=hist_cell(8)+magtu_cell(p,q)*(170-angle_cell(p,q))/20;
    
                         hist_cell(9)=hist_cell(9)+magtu_cell(p,q)*(angle_cell(p,q)-150)/20;
    
                     elseif angle_cell(p,q)>170 && angle_cell(p,q)<=180
    
                         hist_cell(9)=hist_cell(9)+magtu_cell(p,q)*(190-angle_cell(p,q))/20;
    
                         hist_cell(1)=hist_cell(1)+magtu_cell(p,q)*(angle_cell(p,q)-170)/20;
    
                     elseif angle_cell(p,q)>0 && angle_cell(p,q)<=10
    
                         hist_cell(1)=hist_cell(1)+magtu_cell(p,q)*(angle_cell(p,q)+10)/20;
    
                         hist_cell(9)=hist_cell(9)+magtu_cell(p,q)*(10-angle_cell(p,q))/20;
    
                     end
    
                 end
    
             end
    
             block_feature = [block_feature hist_cell];
    
         end
    
     end
    
             % Normalize block_feature using L2-norm
    
             block_feature = block_feature/sqrt(norm(block_feature)^2+0.00001);
    
             hog_feature = [hog_feature block_feature];
    
     end 
    
 end
    
 hog_feature(isnan(hog_feature)) = 0;
    
 %Normalize the hog_feature using L2-Hys
    
 hog_feature = hog_feature/sqrt(norm(hog_feature)^2+0.00001);
    
 for z = 1:length(hog_feature)
    
     if hog_feature(z)>0.2
    
     hog_feature(z)=0.2
    
     end
    
 end
    
 hog_feature = hog_feature/sqrt(norm(hog_feature)^2+0.00001);

全部评论 (0)

还没有任何评论哟~