目录
1.算法仿真效果
matlab2022a仿真结果如下:
TOF数据库如下:
2.算法涉及理论知识概要
1、HOG特征:
方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功。需要提醒的是,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很多行人检测算法不断提出,但基本都是以HOG+SVM的思路为主。
(1)主要思想:
在一副图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。(本质:梯度的统计信息,而梯度主要存在于边缘的地方)。
(2)具体的实现方法是:
首先将图像分成小的连通区域,我们把它叫细胞单元。然后采集细胞单元中各像素点的梯度的或边缘的方向直方图。最后把这些直方图组合起来就可以构成特征描述器。
(3)提高性能:
把这些局部直方图在图像的更大的范围内(我们把它叫区间或block)进行对比度归一化(contrast-normalized),所采用的方法是:先计算各直方图在这个区间(block)中的密度,然后根据这个密度对区间中的各个细胞单元做归一化。通过这个归一化后,能对光照变化和阴影获得更好的效果。
(4)优点:
与其他的特征描述方法相比,HOG有很多优点。首先,由于HOG是在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性,这两种形变只会出现在更大的空间领域上。其次,在粗的空域抽样、精细的方向抽样以及较强的局部光学归一化等条件下,只要行人大体上能够保持直立的姿势,可以容许行人有一些细微的肢体动作,这些细微的动作可以被忽略而不影响检测效果。因此HOG特征是特别适合于做图像中的人体检测的。
2、HOG特征提取算法的实现过程:
大概过程:
HOG特征提取方法就是将一个image(你要检测的目标或者扫描窗口):
1)灰度化(将图像看做一个x,y,z(灰度)的三维图像);
2)采用Gamma校正法对输入图像进行颜色空间的标准化(归一化);目的是调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰;
3)计算图像每个像素的梯度(包括大小和方向);主要是为了捕获轮廓信息,同时进一步弱化光照的干扰。
4)将图像划分成小cells(例如6*6像素/cell);
5)统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor;
6)将每几个cell组成一个block(例如3*3个cell/block),一个block内所有cell的特征descriptor串联起来便得到该block的HOG特征descriptor。
7)将图像image内的所有block的HOG特征descriptor串联起来就可以得到该image(你要检测的目标)的HOG特征descriptor了。这个就是最终的可供分类使用的特征向量了。
(1)标准化gamma空间和颜色空间
为了减少光照因素的影响,首先需要将整个图像进行规范化(归一化)。在图像的纹理强度中,局部的表层曝光贡献的比重较大,所以,这种压缩处理能够有效地降低图像局部的阴影和光照变化。因为颜色信息作用不大,通常先转化为灰度图;
Gamma压缩公式:
比如可以取Gamma=1/2;
(2)计算图像梯度
计算图像横坐标和纵坐标方向的梯度,并据此计算每个像素位置的梯度方向值;求导操作不仅能够捕获轮廓,人影和一些纹理信息,还能进一步弱化光照的影响。
图像中像素点(x,y)的梯度为:
最常用的方法是:首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向(水平方向,以向右为正方向)的梯度分量gradscalx,然后用[1,0,-1]T梯度算子对原图像做卷积运算,得到y方向(竖直方向,以向上为正方向)的梯度分量gradscaly。然后再用以上公式计算该像素点的梯度大小和方向。
GRNN广义回归神经网络的理论基础是非线性核回归分析,非独立变量y相对于独立变量x的回归分析实际上是计算具有最大概率值的y。设随机变量x和y的联合概率密度函数为f (x ,y),已知x的观测值为X,则y相对于X的回归,即条件均值为:
GRNN通常被用来进行函数逼近。它具有一个径向基隐含层和一个特殊的线性层。第一层和第二层的神经元数目都与输入的样本向量对的数目相等。GRNN结构如图2-3所示,整个网络包括四层神经元:输入层、模式层、求和层与输出层。
输入层的神经元数目与学习样本中输入向量的维数m相等,每个神经元都是一个简单的分布单元,这些神经元直接将输入变量传递到隐含层中。
3.MATLAB核心程序
..................................................
load grnn.mat
NAME = 'cam';
p0 = ['Imges\',NAME];
dt = dir(p0);
p = [dt.name];
correct = 0;
for k = 1:length(dt)-3
path = dt(k+3,1).name;
path = dt(k+3,1).name
%这个部分,我们基于cam0这个图像集合,进行库的建立和训练
%这个部分,我们基于cam0这个图像集合,进行库的建立和训练
Ks = 1/2;
I0 = imread([ 'Imges\',NAME,'\',path]);
[R,C,K] = size(I0);
if K == 1
I1 = I0;
else
I1 = rgb2gray(I0);
end
I1 = imresize(I1,Ks);
[R1,C1,K] = size(I1);
figure(1);
subplot(221);
imshow(I1);
title('原始图像');
%% 预处理:
%第一步由于采集到的深度图有的地方的深度值为零,首先用最邻近差值算法将为零的深度值用其周围的点代替
I2 = func_nearest_Interpolation(I1);
subplot(222);
imshow(uint8(I2));
title('最邻近差值图像');
%第二步:用中值滤波算法对上一步骤获得的图像进行处理,去噪声;
L = 5;
I3 = uint8(medfilt2(I2,[L,L]));
subplot(223);
imshow(I3);
title('中值滤波');
%第三步:获得二值图
I4(1:floor(5*R1/7),:) = im2bw(I3(1:floor(5*R1/7),:) , 0.9*graythresh(I3(1:floor(5*R1/7),:)));
I4(1+floor(5*R1/7):R1,:) = im2bw(I3(1+floor(5*R1/7):R1,:),1.25*graythresh(I3(1+floor(5*R1/7):R1,:)));
subplot(224);
imshow(I4);
title('二值图');
%第四步:边缘图
I5 = edge(I4,'canny');
%第五步:distance map
I6 = func_distancemap(I5);
I6 = 255-uint8(255*I6);
figure(2);
subplot(221);
imshow(I6);
title('distance图');
%第六步:提取上半身
[Is,Is_edge,indy] = func_bodycatch(I4,I6);
Is2 = bwareaopen(Is,4000);
subplot(222);
imshow(Is);
title('提取上半身');
subplot(223);
imshow(Is2);
title('提取上半身边缘');
%人体的提取
ff = uint8(255*Is2);
[rows,cols] = size(ff);
[Ls,n] = bwlabel(ff);
X1 = [];
X2 = [];
Y1 = [];
Y2 = [];
flag = 0;
L1 = zeros(R,C,3);
S = [];
for i=1:n
[r,c] = find(Ls==i);
a1(i) = max(r);
a2(i) = min(r);
b1(i) = max(c);
b2(i) = min(c);
w(i) = b1(i)-b2(i);
h(i) = a1(i)-a2(i);
S(i) = w(i)*h(i);
X1 = [X1,a2(i)];
X2 = [X2,a1(i)];
Y1 = [Y1,b2(i)];
Y2 = [Y2,b1(i)];
L1(a2(i):a2(i)+2,b2(i):b1(i),1) = 0;
L1(a2(i):a2(i)+2,b2(i):b1(i),2) = 0;
L1(a2(i):a2(i)+2,b2(i):b1(i),3) = 255;
L1(1.2*a1(i)-2:1.2*a1(i),b2(i):b1(i),1) = 0;
L1(1.2*a1(i)-2:1.2*a1(i),b2(i):b1(i),2) = 0;
L1(1.2*a1(i)-2:1.2*a1(i),b2(i):b1(i),3) = 255;
L1(a2(i):1.2*a1(i),b1(i)-2:b1(i),1) = 0;
L1(a2(i):1.2*a1(i),b1(i)-2:b1(i),2) = 0;
L1(a2(i):1.2*a1(i),b1(i)-2:b1(i),3) = 255;
L1(a2(i):1.2*a1(i),b2(i):b2(i)+2,1) = 0;
L1(a2(i):1.2*a1(i),b2(i):b2(i)+2,2) = 0;
L1(a2(i):1.2*a1(i),b2(i):b2(i)+2,3) = 255;
end
if length(S) > 1
LL = L1;
[V,I] = sort(S);
inds = I(end-1:end);
[RR,CC] = size(Is2);
IF = zeros(RR,CC);
for i = 1:RR
for j = 1:CC
if Is2(i,j) == 1
IF(i,j) = I1(i,j);
else
IF(i,j) = 0;
end
end
end
if X1(inds(1)) < X1(inds(2))
IF1 = IF(X1(inds(1)):X2(inds(1)),Y1(inds(1)):Y2(inds(1)));
XC1 = Y2(inds(1));
YC1 = X1(inds(1));
IF2 = IF(X1(inds(2)):X2(inds(2)),Y1(inds(2)):Y2(inds(2)));
XC2 = Y2(inds(2));
YC2 = X1(inds(2));
else
IF2 = IF(X1(inds(1)):X2(inds(1)),Y1(inds(1)):Y2(inds(1)));
XC2 = Y2(inds(1));
YC2 = X1(inds(1));
IF1 = IF(X1(inds(2)):X2(inds(2)),Y1(inds(2)):Y2(inds(2)));
XC1 = Y2(inds(2));
YC1 = X1(inds(2));
end
end
if length(S) == 1
[IF1,IF2,CUT,IFS,L1] = func_body_fenge(Is2,X1,X2,Y1,Y2);
LL = L1;
XC1 = Y2-30;
YC1 = X1;
XC2 = CUT-30;
YC2 = X1;
end
figure(3);
subplot(131);
imshow(IF,[]);
title('提取上半身边缘');
subplot(132);
imshow(IF1,[]);
title('提取上半身边缘1');
subplot(133);
imshow(IF2,[]);
title('提取上半身边缘2');
%特征提取
Hog_Dat1 = func_feature(IF1);
Hog_Dat2 = func_feature(IF2);
FF1 = sim(net,Hog_Dat1);
FF2 = sim(net,Hog_Dat2);
I0 = imresize(I0,Ks);
I_final = I0;
for i = 1:R1
for j = 1:C1
if LL(i,j,3) == 255
I_final(i,j,1) = 0;
I_final(i,j,2) = 0;
I_final(i,j,3) = 255;
end
end
end
figure(4);
imshow(I_final);
title('姿态识别效果');
if round(FF1) == 1
correct = correct+1;
text(XC2,YC2,'跳舞','color',[0,1,0],'fontsize',24);
else
text(XC2,YC2,'站立','color',[0,1,0],'fontsize',24);
end
if round(FF2) == 2
correct = correct+1;
text(XC1,YC1,'站立','color',[0,1,0],'fontsize',24);
else
text(XC1,YC1,'跳舞','color',[0,1,0],'fontsize',24);
end
pause(0.01);
end
%计算正确率
corrects = correct/2/(length(dt)-3);
disp('正确率:');
100*corrects
09_043_m
4.完整算法代码文件
V