Hog特征的简单实现
针对Hog特征不做过多的解释;
可参考其他博主的原理介绍。
本文是matlab版本的实现。
该版本的hog特征将图像resize为64*128
首先将RGB转灰度图
再进行伽马校正
对伽马校正后的图像做归一化处理
(为什么这样做,请参看其他博主具体的原理介绍)
伽马校正使用的是
opencv中的normalize函数
NORM_MINMAX:(AK不属于{max(Ai)},min(Ai),当AK等于max(Ai)时p=1,等于min(Ai)时p=0)
公式如下
具体参见:https://blog.csdn.net/cosmispower/article/details/64457406
接下来计算梯度和方向。
再归一化。
最终统计直方图。
这里有一个小问题,梯度的归一化没有用到,这个需要做测试
验证归一化后再统计的识别结果好还是未归一化后的结果好?
角度用的是0-180
针对统计结果在做L2的归一化。
这里的统计直接统计88的块,且没有叠加。因此特征量小。
特征量是168*9=1152
由于该算法硬件加速,未作更复杂的统计。
function His_Gra_all=hog_matlab(I)
img=I;
img=imresize(img,[128 64]);
[m n]=size(img(:,:,1));
%转灰度图
%img=rgb2gray(img);
img=img(:,:,1)*0.3+img(:,:,2)*0.59+img(:,:,3)*0.11;
%figure;imshow(uint8(img))
%T伽马校正
img=sqrt(double(img));
%img1=int8(img);
%%伽马校正归一化
Max=max(max(img));
Min=min(min(img));
temp=0;
for i=1:m
for j=1:n
if(img(i,j)==Max)
temp=1;
end
if(img(i,j)==Min)
temp=0;
end
if(img(i,j)~=Min&&img(i,j)~=Max)
temp=img(i,j)/(Max-Min);
end
img_n1(i,j)=temp*255;
end
end
aaa=uint8(img_n1);
%figure;
%imshow(uint8(img_n1));
%%计算梯度
Gimg_D=zeros(m,n);
Gimg_M=zeros(m,n);
for i=2:m-1
for j=2:n-1
Gx=img_n1(i,j+1)-img_n1(i,j-1);
Gy=img_n1(i+1,j)-img_n1(i-1,j);
Gxy=int16(sqrt(Gx*Gx+Gy*Gy));
theta=abs((atan2(Gy,Gx)*180)/pi);
%theta=atan2d(double(Gy),double(Gx));
Gimg_D(i,j)=theta;
Gimg_M(i,j)=Gxy;
end
end
% figure;
% imshow(uint8(Gimg_D));
% figure;
% imshow(uint8(Gimg_M));
%%梯度归一化
Max1=max(max(Gimg_D));
Min1=min(min(Gimg_D));
for i=1:m
for j=1:n
temp=((Gimg_D(i,j)-Min1)*255)/(Max1-Min1);
if(temp>255)
temp=255;
end
img_n2(i,j)=temp;
end
end
% figure;
% imshow(uint8(img_n2));
%%统计直方图
Gimg_D=double(Gimg_D);
Gimg_M=double(Gimg_M);
step=8;%步长为8 网格大小为8*8
cell_size=8;
His_Num=9;
His_Gra=zeros(1,9);
His_Gra_all=[];
G_t=1;
G_sum=0;
%先判断属于0-180的哪个区间 再按照比例分配幅值
for i=1:m/step
for j=1:n/step
Gd=Gimg_D((i-1)*8+1:i*8,((j-1)*8+1):j*8);
Gm=Gimg_M((i-1)*8+1:i*8,((j-1)*8+1):j*8);
for i1=1:cell_size
for j1=1:cell_size
H_d=Gd(i1,j1);
H_d0=H_d/20;
H_d1=double(floor(H_d0));%向下取整
H_d2=double(ceil(H_d0));%向上取整
if(H_d1==0)
H_d1=1;
end
if(H_d2==0)
H_d2=1;
end
H_m=Gm(i1,j1);
H_m1=((H_d2*20-H_d)/20)*H_m;
H_m2=(1-(H_d2*20-H_d)/20)*H_m;
His_Gra(H_d1)= His_Gra(H_d1)+H_m1;
His_Gra(H_d2)=His_Gra(H_d2)+H_m2;
end
end
for i=1:9
G_sum=G_sum+His_Gra(i)*His_Gra(i);
end
His_Gra=His_Gra/sqrt(G_sum);
His_Gra_all=[His_Gra_all,His_Gra];
His_Gra=zeros(1,9);
G_sum=0;
end
end
end