目录
1.算法整体概述
步态识别属于生物特征识别领域,依靠人体行走过程中肢体周期性运动形成的时空特征实现身份辨识,相较于人脸、指纹等接触式识别方式,步态可在远距离、低分辨率、非配合场景下完成采集,在智能安防、视频监控、人员追踪等场景具备极强应用价值。传统单一特征步态识别存在光照干扰、视角偏移、衣着遮挡、携带物品等鲁棒性缺陷,仅依靠手工特征容易丢失深层非线性运动信息,单纯CNN端到端训练又会忽略步态先验运动规律,易受背景噪声干扰。
本文所提算法将步态能量图(GEI)作为步态时序信息的归一化表征载体,先对步态时序剪影序列做GEI映射完成时空维度压缩,通过方向梯度直方图(HOG)提取GEI图像的局部空间纹理与边缘运动特征,得到手工精细化浅层特征,再将HOG特征图送入卷积神经网络(CNN)完成深层抽象特征挖掘,融合手工先验特征与深度学习高维特征,最终通过分类器实现人员身份识别。
2.步态能量图GEI提取
步态能量图是步态识别中经典的时序剪影特征表征方式,核心思想是将单人一个完整行走周期内所有二值步态剪影图像做像素级时间维度均值运算,把连续的二维时空步态序列压缩为单张二维灰度特征图,消除单帧剪影的瞬时姿态噪声,保留一个行走周期内肢体所有运动区域的出现概率分布,像素灰度值越高代表该位置肢体运动出现频次越高,完整刻画人体行走的周期运动轮廓规律。

w0、h0分别为原始人体外接矩形的宽与高,x'、y'为归一化后像素坐标,保证所有GEI输入图像尺度统一,避免尺度差异干扰后续特征提取。
3.HOG局部方向梯度特征提取
HOG特征核心是通过统计图像局部单元格内梯度方向的分布直方图,刻画人体轮廓边缘、肢体形变、步态空间纹理信息,对轻微视角偏移、局部遮挡、光照变化具备极强鲁棒性,能够从GEI灰度图中精细化提取肢体边缘运动的空间分布特征。
图像像素梯度幅值与梯度方向计算

单元格梯度方向直方图统计
将GEI图像均匀划分为若干尺寸为cell×cell的互不重叠单元格,遍历单元格内所有像素,将各像素梯度幅值累加至对应梯度方向的直方图区间,单个单元格第i个梯度区间的统计值计算公式:

δ为克罗内克函数,当梯度方向量化后区间编号等于i时函数取值为1,其余情况为0,最终每个单元格生成维度为k的一维梯度方向直方图特征向量。
块归一化消除光照局部明暗干扰
相邻多个单元格组成一个重叠块,对块内所有单元格的直方图特征做L2归一化处理,抑制局部光照突变带来的梯度幅值偏差,归一化公式:

H为块内拼接后的原始HOG特征向量,∥H∥2为向量L2范数,ε为极小常数,防止分母为0造成计算异常。遍历所有重叠块完成滑动窗口特征提取,最终拼接所有块归一化特征得到GEI图像对应的全局HOG手工特征向量,该向量既保留人体行走轮廓的边缘空间分布,又具备极强抗形变能力。
4.CNN训练和识别
搭建轻量化卷积神经网络,网络结构依次为卷积层、ReLU激活层、最大池化层循环堆叠,将HOG二维特征图作为网络输入,初始化卷积核、全连接层权重参数,采用交叉熵损失函数作为模型优化目标,损失函数计算公式:

M为单次训练批次样本数量,yij为样本真实类别独热标签,pij为模型Softmax预测类别概率。采用小批量随机梯度下降算法反向传播更新网络所有权重参数,迭代训练至验证集识别准确率趋于稳定,保存最优训练模型,提取网络深层卷积特征。
网络结构如下图所示:

训练结果如下:

他的识别率为88.89%。
5.MATLAB程序
部分核心代码如下:
clc;
clear;
close all;
warning off;
addpath 'subfunc\'
rng(1);
digitDatasetPath = ['步态能量图\'];
imds = imageDatastore(digitDatasetPath,'IncludeSubfolders', true, 'LabelSource', 'foldernames');
%划分数据为训练集合验证集,训练集中每个类别包含1张图像,验证集包含其余图像的标签
numTrainFiles = 1;%设置每个类别的训练个数
[imdsTrain, imdsValidation] = splitEachLabel(imds, numTrainFiles, 'randomize');
%定义卷积神经网络的基础结构
layers = [
imageInputLayer([400 150 1]);%注意,400,150为能量图的大小,不能改
%第1个卷积层
convolution2dLayer(3, 8, 'Padding', 'same');%第一个卷积层
batchNormalizationLayer;
%第1个激励层
reluLayer;
%第1个池化层
maxPooling2dLayer(2, 'Stride', 2);
%第2个卷积层
convolution2dLayer(3, 8, 'padding', 'same');
batchNormalizationLayer;
%第2个激励层
reluLayer;
%第2个池化层
maxPooling2dLayer(2, 'Stride', 2);
%第3个卷积层
convolution2dLayer(3, 16, 'Padding', 'same');
batchNormalizationLayer;
%第3个激励层
reluLayer;
%第3个池化层
maxPooling2dLayer(2, 'Stride', 2);
%全连接层1
fullyConnectedLayer(5);
%softmax
softmaxLayer;
%输出分类结果
classificationLayer;];
%设置训练参数
Num = 10; %搜索数量
Iters = 10; %迭代次数
D = 1; %搜索空间维数
woa_idx = zeros(1,D);
woa_get = inf;
%初始化种群的个体
%初始化种群的个体
Xmin = 0;
Xmax = 1;
xwoa=rand(Num,D);
for t=1:Iters
t
for i=1:Num
%目标函数更新
[pa(i)] = fitness(xwoa(i,:),imdsTrain, imdsValidation,layers);
Fitout = pa(i);
%更新
if Fitout < woa_get
woa_get = Fitout;
woa_idx = xwoa(i,:);
end
end
%调整参数
c1 = 2-t*((1)/Iters);
c2 =-1+t*((-1)/Iters);
% w = 0.1+0.8*(cos(std(pa)));
%位置更新
for i=1:Num
rng(i);
r1 = rand();
r2 = rand();
K1 = 2*c1*r1-c1;
K2 = 2*r2;
l =(c2-1)*rand + 1;
rand_flag = rand();
if rand_flag<0.5
if abs(K1)>=1
RLidx = floor(Num*rand()+1);
X_rand = xwoa(RLidx, :);
D_X_rand = abs(K2*X_rand(1:D)-xwoa(i,1:D));
xwoa(i,1:D)= X_rand(1:D)-K1*D_X_rand;
else
D_Leader = abs(K2*woa_idx(1:D)-xwoa(i,1:D));
xwoa(i,1:D)= woa_idx(1:D)-K1*D_Leader;
end
else
distLeader = abs(woa_idx(1:D)-xwoa(i,1:D));
xwoa(i,1:D) = distLeader*exp(l).*cos(l.*2*pi)+woa_idx(1:D);
end
end
[pb] = fitness(woa_idx,imdsTrain, imdsValidation,layers);
end
rng(1);
options = trainingOptions('sgdm', ...
'InitialLearnRate', abs(woa_idx/5), ...
'MaxEpochs', 200, ...
'Shuffle', 'every-epoch', ...
'ValidationData', imdsValidation, ...
'ValidationFrequency', 10, ...
'Verbose', false, ...
'Plots', 'training-progress');
%使用训练集训练网络
net = trainNetwork(imdsTrain, layers, options);
%对验证图像进行分类并计算精度
YPred = classify(net, imdsValidation);
YValidation = imdsValidation.Labels;
accuracy = sum(YPred == YValidation) / numel(YValidation);
accuracy
运行结果如下:

209

被折叠的 条评论
为什么被折叠?



