匆匆在看完了MOOC的《数字图像处理》,为了巩固所学,做了一个简单的手势识别(只能识别手势1、2、3)!
软件包下载地址微信公众号:小白课代表
一开始我是用的MATLAB R2018b,但是在根据B站视频《10分钟学会matlab实现cnn图像分类》学习的过程中,发现没有办法生成代码,所以换成了MATLAB R2021b。我的笔记本运行R2021b太卡了,每次打开R2021b都要5分钟,而且运行的时候也经常碰到问题,有时候没法编辑.m文件,有时候按F1没有反应,我太难了。
一些经验:
1、工具包安装失败的解决方法:把防火墙、杀毒软件什么的都关了,然后重启MATLAB,多试几次就可以
2、摄像头画面值显示一个大红叉的解决方法:多重启MATLAB几次就可以3、报错:Unable to allocate memory for an incoming image frame due to insufficient free physical memory.
解决方法:C盘要留出10G以上的大小
%%
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
%%
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)
报错:
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
%% 读入图片
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'); %将变量保存到当前文件夹中的文件
%% 装入数据
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')
%%
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)
%%
%解决错误: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的简单手势识别(包含全部调试资源)https://download.csdn.net/download/qq_35629563/86248804