图像处理作业——HOG特征提取

在网上看了几个博客上的代码,发现基本写得都是一样的,有些地方感觉写的不是很对,自己尝试了一下。
步骤如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
懒得打字了,从老师的课件上截的图。

下面是代码:

clear all; close all; clc;

img=double(imread('lena.png'));
%imshow(img,[]);
[m n]=size(img);

%sobel算子计算区域内的梯度
hx = [-1,0,1;-2,0,2;-1,0,1];          %定义竖直模板
hy = [1,2,1;0,0,0;-1,-2,-1];          %定义水平模板
gradx = filter2(hx,img);              %计算竖直方向的梯度          
grady = filter2(hy,img);              %计算水平方向的梯度
grad = sqrt(gradx.^2+grady.^2);       %计算梯度的大小
grad_angle = atan(grady./gradx);      %计算梯度的方向(弧度-pi/2,pi/2)

%将区域划分为若干个cell,并统计每个cell的梯度方向直方图
step=16;                %step*step个像素作为一个cell
orient=9;               %方向直方图的方向个数
angle=180/orient;       %每个方向包含的角度数

Cell=cell(1,1);              %所有的角度直方图,cell是可以动态增加的,所以先设了一个
ii=1;                      
jj=1;
for i=1:step:m  
    jj = 1;                                                  %从每行第一列开始计算cell
    for j=1:step:n                                           
        tmp_angle = grad_angle(i:i+step-1,j:j+step-1);       %cell中的梯度方向
        tmp_grad = grad(i:i+step-1,j:j+step-1);              %cell中的梯度大小
        tmp_angle = tmp_angle*180/pi;                        %将梯度方向从弧度转为角度       
        Hist = zeros(1,orient);                              %定义一个矩阵用来存放后续的梯度直方图
        for p = 1:step
            for q = 1:step
                if isnan(tmp_angle(p,q)) == 1                %如果gradx=0则梯度方向不是一个数,避免计算错误,将其归为0
                    tmp_angle(p,q) = 0;
                end
                if tmp_angle(p,q) < 0;                       %将梯度量化都放到(0°,180°)中进行
                    tmp_angle(p,q) = tmp_angle(p,q) + 180;   %因为atan函数的输出结果范围在一四象限,将第四象限的数转到第二象限即(90°,180°)
                end
                if tmp_angle(p,q) == 0;
                    tmp_angle(p,q) = 0.1;                    %避免后续出现Hist索引错误
                end
                tmp_angle(p,q) = ceil(tmp_angle(p,q)/angle); %将梯度方向除以区间大小后取整再加一
                Hist(tmp_angle(p,q)) = Hist(tmp_angle(p,q)) + tmp_grad(p,q);  %统计每个cell的梯度方向直方图
            end
        end
        Cell{ii,jj} = Hist;      
        jj = jj + 1;             %针对Cell的y坐标循环变量
    end
     ii = ii + 1;                %针对Cell的x坐标循环变量
end
       
%以cell为单位组成block,并对block中的梯度方向直 方图做归一化                 
clear m n i j p q;
[m n]=size(Cell);
s = 4;                                      %block由s*s个cell组成
feature=[];                                 %用来存放特征  
for i = 1:m-s+1                             %注意索引范围
    for j = 1:n-s+1
        block=[];                           %每一个循环存放一个block
        for p = 1:s                         %将同一个block中的cell并列存放到一个block中
            for q = 1:s
                block = [block;Cell{i+p-1,j+q-1}(:)];
            end
        end 
        block = block./sum(block);          %对block中的梯度方向直方图做归一化
        feature = [feature;block];          %将所有block级联
    end
end

figure
hist(feature);

我感觉收获最大的地方就是量化方向那一块,之前还一直想着一个一个用条件if balabala ,还有就是调试过程中积累了一些调试经验,当调试出结果的时候是真的很开心。
参考博客:
添加链接描述
添加链接描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页