基于MATLAB的简单手势识别

匆匆在看完了MOOC的《数字图像处理》,为了巩固所学,做了一个简单的手势识别(只能识别手势1、2、3)!

0、安装硬件支持包软硬件安装

0.1、MATLAB R2021b安装

软件包下载地址微信公众号:小白课代表

一开始我是用的MATLAB R2018b,但是在根据B站视频《10分钟学会matlab实现cnn图像分类》学习的过程中,发现没有办法生成代码,所以换成了MATLAB R2021b。我的笔记本运行R2021b太卡了,每次打开R2021b都要5分钟,而且运行的时候也经常碰到问题,有时候没法编辑.m文件,有时候按F1没有反应,我太难了。

0.2、安装硬件支持包基于MATLAB的简单手势识别_第1张图片

 一些经验:

1、工具包安装失败的解决方法:把防火墙、杀毒软件什么的都关了,然后重启MATLAB,多试几次就可以
2、摄像头画面值显示一个大红叉的解决方法:多重启MATLAB几次就可以

3、报错:Unable to allocate memory for an incoming image frame due to insufficient free physical memory.

解决方法:C盘要留出10G以上的大小

1、查看支持包信息

%%
close all;
clear all;
clc;

%%
disp(imaqhwinfo)%查看当前适配器

%%
info = imaqhwinfo('winvideo')%查看该适配器下所有设备

%%
disp(info.DeviceInfo)%通过DeviceInfo查看摄像头详细信息

%%
disp(info.DeviceInfo.SupportedFormats)%SupportedFormats是该摄像头支持的图像色彩与尺寸

%%
%解决错误:The device associated with device ID 1 is already in use.
clc; clear;
close all;
objects = imaqfind %find video input objects in memory
%%
stop(objects);
delete(objects) %delete a video input object from memory

2、获取截图(自己创建训练集)

%%
obj = videoinput('winvideo',1,'MJPG_640x480');
h = preview(obj);
start(obj)
tic%启动秒表计时器

% 手势1保存的路径:'D:\gao\Program\MATLAB\第一学期\数字图像处理\手势\finger_1\original\';
file_root='D:\gao\Program\MATLAB\第一学期\数字图像处理\手势\';

finger_num=1%手势表示的数值,也可以理解为标签
picture_num=40%每一种手势的截图个数
file_root=[file_root,'finger_',num2str(finger_num),'\original\'];

for i=1:picture_num
    i
    pause(1)%延迟1s
    frame = getsnapshot(obj);  % 获取帧
    file_name=[file_root,'finger_',num2str(finger_num),'_',num2str(i),'.bmp'];
    imwrite(frame,file_name);%手势1的第一张截图的名称:finger_1_1.bmp
end
toc%从秒表读取已用时间
stop(obj);
delete(obj)

 基于MATLAB的简单手势识别_第2张图片

基于MATLAB的简单手势识别_第3张图片

基于MATLAB的简单手势识别_第4张图片

报错:

The device associated with device ID 1 is already in use.

解决错误:

%%
clc; 
clear;
close all;
objects = imaqfind %find video input objects in memory
%%
stop(objects);
delete(objects) %delete a video input object from memory

3、 图像预处理

%% 读入图片
close all;
clear all;
clc;

quarter=16;%减采样倍数

p_store=1;%指向存储的位置
input=zeros(30,40,20*3);%图片大小:30*40,图片个数:3*20
finger_num=3
picture_num=40
for p_finger_num=1:finger_num
    file_root='D:\gao\Program\MATLAB\第一学期\数字图像处理\手势\';
    % 'D:\gao\Program\MATLAB\第一学期\数字图像处理\手势\finger_1\original\'
    file_root=[file_root,'finger_',num2str(p_finger_num),'\original\'];
    
    for p_picture_num=1:picture_num
        %'D:\gao\Program\MATLAB\第一学期\数字图像处理\手势\finger_1\original\finger_1_1.bmp'
        file_name=[file_root,'finger_',num2str(p_finger_num),'_',num2str(p_picture_num),'.bmp'];%
        I_rgb=imread(file_name); %用 imread 函数来读入图像,480*640*3        
        I_gray=rgb2gray(I_rgb);% 灰度,480*640        
        I_quarter=imresize(I_gray, 1/quarter);% 减采,30*40        
        T=graythresh(I_quarter);
        I_BW=im2bw(I_quarter,T); % 阈值分割        
        H=fspecial('average',[3,3]);%平滑滤波,创建预定义的2d过滤器
        I_filter=imfilter(I_BW,H);%I_gray        
        I_edge=edge(I_filter); % 边缘提取        
        input(:,:,p_store)=I_edge;
        p_store=p_store+1;%指向下一个存储的位置
    end
end

%% 随机查看输入图片是否正常
p=input(:,:,floor(rand*120));
figure('name','原始图片')
imshow(p); %用 imshow 函数来显示图像

%% 输出
output=ones(1,finger_num*picture_num);
for p_finger_num=1:finger_num
    output(1, (1:picture_num)+(p_finger_num-1)*picture_num )=p_finger_num*ones(1,picture_num);
end

%% 保存数据
save('data123_in30_40_out1_1.mat','input','output'); %将变量保存到当前文件夹中的文件

  

CSDN 上传图片取消自动加水印的方法

 

 

4、卷积神经网络

%% 装入数据
close all;
clearvars  % clear all;
clc;
load('data123_in30_40_out1_1.mat')

%% 读入训练数据和验证数据
XTrain =cat(3, input(:,:,1:30), input(:,:,41:70), input(:,:,81:110));%30*40*90
YTrain =cat(2, output(:,1:30), output(:,41:70), output(:,81:110))';%90*1
XValidation =cat(3, input(:,:,31:40), input(:,:,71:80), input(:,:,111:120));%30*40*30
YValidation =cat(2, output(:,31:40), output(:,71:80), output(:,111:120))';%30*1
YTrain = categorical(YTrain);
YValidation = categorical(YValidation);

%% 
XTrain=reshape(XTrain,[30,40 ,1,90]);
XValidation=reshape(XValidation,[30,40 ,1,30]);

%% 创建层组
layers = [
    imageInputLayer([30 40])
    
    convolution2dLayer(5,16,'Padding','same')
    batchNormalizationLayer
    reluLayer('Name','relu_1')
    
    convolution2dLayer(3,32,'Padding','same','Stride',2)
    batchNormalizationLayer
    reluLayer
    convolution2dLayer(3,32,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    additionLayer(2,'Name','add')
    
    averagePooling2dLayer(2,'Stride',2)
    fullyConnectedLayer(3)
    softmaxLayer
    classificationLayer];

%% 定义skipConv
skipConv = convolution2dLayer(1,32,'Stride',2,'Name','skipConv');


%% 连接skipConv
lgraph = connectLayers(lgraph,'relu_1','skipConv');
lgraph = connectLayers(lgraph,'skipConv','add/in2');
figure
plot(lgraph);

%% 训练
options = trainingOptions('sgdm', ...
    'MaxEpochs',38, ...
    'Shuffle','every-epoch', ...
    'ValidationData',{XValidation,YValidation}, ...
    'ValidationFrequency',30, ...
    'Verbose',false, ...
    'Plots','training-progress');
net = trainNetwork(XTrain,YTrain,lgraph,options);

%% 对验证图像进行分类并计算精度。这个网络非常准确。
YPredicted = classify(net,XValidation);
accuracy = mean(YPredicted == YValidation)

%% 保存当前网络
save('data_CNN_Network.mat','net')

基于MATLAB的简单手势识别_第5张图片

 5、随机测试一张图片

%%
close all;
clear all;
clc;

%% 读入图像
I_rgb=imread('finger_1_1.bmp'); 
figure('name','原始图片')
imshow(I_rgb); 
%% 灰度
I_gray=rgb2gray(I_rgb);
figure('name','灰度图片')
imshow(I_gray);
%% 减采
quarter=16;%减采倍数
I_quarter=imresize(I_gray, 1/quarter);
figure('name','减采样图片')
imshow(I_quarter); 
%% 阈值分割
figure('name','直方图')
imhist(I_quarter);
T=graythresh(I_quarter);
BW=im2bw(I_quarter,T);
figure('name','Otstu图片')
imshow(BW);
%% 平滑滤波
H=fspecial('average',[3,3]);%平滑滤波,创建预定义的2d过滤器
I_filter=imfilter(BW,H);%I_gray
figure('name','滤波图片')
imshow(I_filter);
%% 边缘提取
I_edge=edge(I_filter);%30*40
figure('name','边缘图片')
imshow(I_edge);

%% 分类
load('data_CNN_Network.mat')%加载训练好的CNN
% net(I_edge)
classify(net,I_edge)

6、实时检测

%%
%解决错误:The device associated with device ID 1 is already in use.
clc; clear;
close all;
objects = imaqfind %find video input objects in memory
if ~isempty(objects)
    stop(objects);
    delete(objects) %delete a video input object from memory
    disp('not empty' )
else
    disp(' empty' )
end


%%
close all;
clearvars ;
clc;

load('data_CNN_Network.mat')
quarter=16
%利用getsnapshot(obj) 即可导出图像,若想连续导出可通过以下方式
obj = videoinput('winvideo',1,'MJPG_640x480');%(adaptorname,deviceID,format)
h = preview(obj);%stoppreview//closepreview//delete(obj)停止/关掉预览
cycles=10;%循环的参数

start(obj)
tic%启动秒表计时器

I_rgb=zeros(480,640,3,cycles);%用来存储原始截图
I_edge=zeros(30,40,cycles);%用来存储边缘化后的截图
result=zeros(1,cycles);
f1=figure('name','原始图片');
f2=figure('name','边缘处理');

for i=1:cycles%ishandle(h)%测试h是否有效的图形或 Java 对象句柄
    i
    pause(1)%延迟
    disp('获取帧');
    i_rgb = getsnapshot(obj);  % 获取帧

    i_gray=rgb2gray(i_rgb);% 灰度
    i_quarter=imresize(i_gray, 1/quarter);% 减采
    T=graythresh(i_quarter);
    I_BW=im2bw(i_quarter,T); % 阈值分割
    H=fspecial('average',[3,3]);%平滑滤波,创建预定义的2d过滤器
    i_filter=imfilter(I_BW,H);%I_gray
    i_edge=edge(i_filter); % 边缘提取

    result(i)=uint8(classify(net,i_edge));
    result(i)
    pause(1)%延迟

    figure(f1);
    subplot(ceil(cycles/3),3,i)%ceil——Round toward positive infinity
    imshow(i_rgb);
    title([num2str(i) ':' num2str(result(i))]);
    I_rgb(:,:,:,i) = i_rgb;% 存储原始截图

    figure(f2);
    subplot(ceil(cycles/3),3,i)
    imshow(i_edge);
    title([num2str(i) ':' num2str(result(i))]);
    I_edge(:,:,i) = i_edge;% 存储边缘截图


end

toc%从秒表读取已用时间
stop(obj);
delete(obj)

 运行结果:

 

注意:

若结果报错:Unable to allocate memory for an incoming image frame due to insufficient free physical memory.

我的解决方法:

方法1:关闭当前.m文件,再重新打开

方法2:关闭MATLAB,再重新打开

方法3:关闭电脑,再重新打

基于MATLAB卷积神经网络的简单手势识别-精简-机器学习文档类资源-CSDN下载内容概要:通过简单手势识别,带着读者做一遍软件安装、数据集采集、图像处理、神经网络训练、网络的测试、更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_35629563/86248802
基于MATLAB的简单手势识别(包含全部调试资源)icon-default.png?t=M666https://download.csdn.net/download/qq_35629563/86248804

你可能感兴趣的:(MATLAB,matlab,图像处理,手势识别)