口罩佩戴检测(一):数据的获取与预处理
本篇文章开始,将为大家介绍口罩佩戴检测的实现方法,识别算法使用SVM算法,编程语言使用matlab。以下是本系列文章的目录安排。
一、问题的提出
2020年2月份中国开始爆发了新冠疫情,所有公共场合都要求所有人员必须佩戴口罩。但是在人群众多的场合,随时监督人群中每个人的口罩佩戴情况,无疑对在场工作人员的工作负荷是一个很大的挑战。所以我们想通过自己在模式识别课程上所学的知识,来建立一个解决这个问题的基本框架—通过建立分类器来识别人群中每个人是否佩戴口罩,甚至是否正确佩戴口罩。
二、数据获取和预处理
在武汉大学数据共享网站上分别下载了10000张佩戴口罩和10000张没有佩戴口罩的照片作为训练集,在各类样本中随机选取2000张佩戴口罩的人像照片和没有佩戴口罩的人像作为测试集。然后将这20000张照片转换成灰度图像,然后将照片的灰度值作为矩阵中元素的值,通过灰度图像得到100*100的矩阵,然后再转换为10000维的列向量。作为样本向量。
数据获取和预处理的实现:
2.1导入数据
1、将收集到的数据集由图片格式转换成matlab可处理的数据格式。(程序已封装成函数datas_import())
% 此函数实现的功能是将图像文件批量转换成数组并导入matlab可以处理的.mat文件
function datasImport
clear
% 分别导入10000张戴口罩和不戴口罩的图像数据
datas_import('masked_clean',10000,'face_dataset',10000,0.9)
end
函数的第一个参数是正样本(戴口罩)图片的路径
第二个参数是导入正样本的数量
第三个参数是负样本(不戴口罩)图片的路径
第四个参数是导入负样本的数量
第五个样本是划分样本训练数据和测试数据的划分比率
本次实例中,将导入正负类样本各10000张进行算法的学习与测试,学习数据和测试数据划分比率为0.9,即最终一共有18000张训练样本,2000张测试样本。
2、datas_import()函数的具体定义
% 数据集生成器,positive_path是正样本(戴口罩)图片路径
% negative_path是负样本(不戴口罩)图片路径
% ratio是训练集测试集划分比率,若ratio=0.9,则90%的训练集,10%的测试集
% positive_num和negative_num决定导入多少图像文件
function datas_import(positive_path,positive_num,negative_path,negative_num,ratio)
fprintf('开始导入未戴口罩的数据\n');
negative_datas=imageDatas_import(negative_path,negative_num);
negative_num=size(negative_datas,1);%确定负类样本数量
test_index=randperm(negative_num,round(negative_num*(1-ratio)));
% 确定负类测试样本
test_negative=negative_datas(test_index,:,:);
% 确定负类训练样本
train_negative=negative_datas;
train_negative(test_index,:,:)=[];
save('dataset.mat','test_negative','train_negative','negative_datas');
fprintf('开始导入戴口罩的数据\n');
positive_datas=imageDatas_import(positive_path,positive_num);
positive_num=size(positive_datas,1);%确定负类样本数量
test_index=randperm(positive_num,round(positive_num*0.1));
% 确定正类测试样本
test_positive=positive_datas(test_index,:,:);
% 确定正类训练样本
train_positive=positive_datas;
train_positive(test_index,:,:)=[];
save('dataset.mat','test_positive','train_positive','positive_datas','-append');
end
第一步:首先导入一定数量的负样本(已封装成函数imageDatas_import())
第二步:使用randperm(n,x)函数从n个样本中随机抽取x各样本,这x各样本作为负类测试集
第三步:将a-x个样本作为负类的训练集。
第四步:将训练集和测试集保存至dataset.mat文件中,供程序的下一步操作
正类样本的导入同以上四个步骤。
3、imageDatas_import()函数具体定义
% 导入图象数据,转换成灰度图,并统一尺寸
function images=imageDatas_import(file_path,import_num)
import_index=1;
is_import_finished=0;
file_list=dir(file_path);
file_num=length(file_list);
if file_num==0
fprintf('文件夹为空\n');
else
fprintf('找到%d个文件\n',file_num);
for i=1:file_num%list中的前两个数据分别代表
% 如果需要的文件数量已经导够,则停止导入
if is_import_finished==1
fprintf('%d个图像文件已经导入完成\n',import_index);
break;
end
file_name=file_list(i).name;
% 跳过"."和".."路径,从该目录下的文件开始搜索
if strcmp(file_name,'.')==1 || strcmp(file_name,'..')==1
continue;
end
image_list=dir(fullfile(file_path,file_name,'*.jpg'));%列出path路径下所有后缀为.jpg的文件
image_num=length(image_list);%获取图片数量
if image_num==0
fprintf('在第%d个文件夹中未找到任何图像\n',i-2);
else
fprintf('在第%d个文件夹中已找到%d张图像\n',i-2,image_num);
for j=1:image_num
image_name=image_list(j).name;%获取每一张图片名称
image=imread(fullfile(file_path,file_name,image_name));
image=imresize(image,[100,100]);%统一图片尺寸
image=rgb2gray(image);%转为灰度图
images(import_index,:,:)=image;
if import_index==import_num%如果图片导够了
is_import_finished=1;
break;
end
import_index=import_index+1;
end
end
end
end
end
该函数作用是从指定路径中导入指定数量的图片,并将图片尺寸统一为100X100的大小,然后转换为灰度图的数据矩阵,最终转换成matlab可以处理的数据矩阵。
综上所述,数据集由图片转换成100*100维的数据矩阵(即10000维的数据样本),并保存到dataset.mat文件中。
数据导入部分完整代码:
% 此函数实现的功能是将图像文件批量转换成数组并导入matlab可以处理的.mat文件
function datasImport
clear
% 分别导入10000张戴口罩和不戴口罩的图像数据
datas_import('masked_clean',10000,'face_dataset',10000,0.9)
end
% 数据集生成器,positive_path是正样本(戴口罩)图片路径
% negative_path是负样本(不戴口罩)图片路径
% ratio是训练集测试集划分比率,若ratio=0.9,则90%的训练集,10%的测试集
% positive_num和negative_num决定导入多少图像文件
function datas_import(positive_path,positive_num,negative_path,negative_num,ratio)
fprintf('开始导入未戴口罩的数据\n');
negative_datas=imageDatas_import(negative_path,negative_num);
negative_num=size(negative_datas,1);%确定负类样本数量
test_index=randperm(negative_num,round(negative_num*(1-ratio)));
% 确定负类测试样本
test_negative=negative_datas(test_index,:,:);
% 确定负类训练样本
train_negative=negative_datas;
train_negative(test_index,:,:)=[];
save('dataset.mat','test_negative','train_negative','negative_datas');
fprintf('开始导入戴口罩的数据\n');
positive_datas=imageDatas_import(positive_path,positive_num);
positive_num=size(positive_datas,1);%确定负类样本数量
test_index=randperm(positive_num,round(positive_num*0.1));
% 确定正类测试样本
test_positive=positive_datas(test_index,:,:);
% 确定正类训练样本
train_positive=positive_datas;
train_positive(test_index,:,:)=[];
save('dataset.mat','test_positive','train_positive','positive_datas','-append');
end
% 导入图象数据,转换成灰度图,并统一尺寸
function images=imageDatas_import(file_path,import_num)
import_index=1;
is_import_finished=0;
file_list=dir(file_path);
file_num=length(file_list);
if file_num==0
fprintf('文件夹为空\n');
else
fprintf('找到%d个文件\n',file_num);
for i=1:file_num%list中的前两个数据分别代表
% 如果需要的文件数量已经导够,则停止导入
if is_import_finished==1
fprintf('%d个图像文件已经导入完成\n',import_index);
break;
end
file_name=file_list(i).name;
% 跳过"."和".."路径,从该目录下的文件开始搜索
if strcmp(file_name,'.')==1 || strcmp(file_name,'..')==1
continue;
end
image_list=dir(fullfile(file_path,file_name,'*.jpg'));%列出path路径下所有后缀为.jpg的文件
image_num=length(image_list);%获取图片数量
if image_num==0
fprintf('在第%d个文件夹中未找到任何图像\n',i-2);
else
fprintf('在第%d个文件夹中已找到%d张图像\n',i-2,image_num);
for j=1:image_num
image_name=image_list(j).name;%获取每一张图片名称
image=imread(fullfile(file_path,file_name,image_name));
image=imresize(image,[100,100]);%统一图片尺寸
image=rgb2gray(image);%转为灰度图
images(import_index,:,:)=image;
if import_index==import_num%如果图片导够了
is_import_finished=1;
break;
end
import_index=import_index+1;
end
end
end
end
end
2.2数据处理
仅仅将图像转换为数据矩阵是不够的,还需要进一步对数据进行处理,以作为我们分类器的输入。
1、制作测试数据,将100100的样本转换为100001的样本。因为我们的分类器输入要求数据是dim1的形式。一共有2000个测试样本,最终测试样本数据大小为100002000
clear
load('dataset.mat')
test_num_n=size(test_negative,1);% 测试数据数量 负样本
test_num_p=size(test_positive,1);% 测试数据数量,正样本
train_num_n=size(train_negative,1);% 训练数据数量,负样本
train_num_p=size(train_positive,1);% 训练数据数量,正样本
dim=size(test_negative,2)*size(test_negative,3);
% 制作测试数据
test1=reshape(test_negative,test_num_n,dim);
test2=reshape(test_positive,test_num_p,dim);
Testing=[test1;test2];
Testing=Testing';
2、制作测试数据标签,负类(不戴口罩)为0,正类为1。
% 制作测试数据标签
Testing_label1=zeros(1,test_num_n);
Testing_label2=ones(1,test_num_p);
Testing_label=[Testing_label1,Testing_label2];
3、训练数据及标签的制作同以上2个步骤
% 训练数据
train1=reshape(train_negative,train_num_n,dim);
train2=reshape(train_positive,train_num_p,dim);
Training=[train1;train2];
Training=Training';
% 制作训练数据标签
Training_label1=zeros(1,train_num_n);
Training_label2=ones(1,train_num_p);
Training_label=[Training_label1,Training_label2];
4、将数据类型转换成适合分类器处理的double型并保存。
% 类型转换并保存处理后的数据
Training=double(Training);
Training_label=double(Training_label);
Testing=double(Testing);
Testing_label=double(Testing_label);
save('dataset_processed.mat','Training','Training_label','Testing','Testing_label');
数据处理部分完整代码如下:
clear
load('dataset.mat')
test_num_n=size(test_negative,1);% 测试数据数量 负样本
test_num_p=size(test_positive,1);% 测试数据数量,正样本
train_num_n=size(train_negative,1);% 训练数据数量,负样本
train_num_p=size(train_positive,1);% 训练数据数量,正样本
dim=size(test_negative,2)*size(test_negative,3);
% 制作测试数据
test1=reshape(test_negative,test_num_n,dim);
test2=reshape(test_positive,test_num_p,dim);
Testing=[test1;test2];
Testing=Testing';
% 制作测试数据标签
Testing_label1=zeros(1,test_num_n);
Testing_label2=ones(1,test_num_p);
Testing_label=[Testing_label1,Testing_label2];
% 训练数据
train1=reshape(train_negative,train_num_n,dim);
train2=reshape(train_positive,train_num_p,dim);
Training=[train1;train2];
Training=Training';
% 制作训练数据标签
Training_label1=zeros(1,train_num_n);
Training_label2=ones(1,train_num_p);
Training_label=[Training_label1,Training_label2];
% 类型转换并保存处理后的数据
Training=double(Training);
Training_label=double(Training_label);
Testing=double(Testing);
Testing_label=double(Testing_label);
save('dataset_processed.mat','Training','Training_label','Testing','Testing_label');
综上,数据经二次处理后,统一转换成dim*n的格式,并附有标签。在经过类型转换后保存至dataset_processed.mat文件中。
- 分享
- 举报
-
浏览量:6222次2021-01-08 02:27:20
-
浏览量:229次2023-08-03 15:44:04
-
浏览量:6949次2021-01-08 02:45:30
-
浏览量:15765次2020-12-19 14:41:57
-
浏览量:5383次2021-01-08 03:12:37
-
浏览量:20644次2020-12-21 18:30:47
-
浏览量:630次2024-02-18 14:24:39
-
2023-01-13 11:33:00
-
浏览量:1021次2023-01-29 11:28:01
-
浏览量:5869次2021-07-09 11:16:51
-
浏览量:2078次2020-07-03 14:08:01
-
浏览量:1111次2024-03-01 16:56:38
-
浏览量:10595次2021-04-27 00:28:09
-
浏览量:4508次2021-04-27 00:05:09
-
浏览量:1987次2020-02-24 10:20:48
-
浏览量:27578次2021-01-08 11:33:04
-
浏览量:32747次2020-12-18 00:01:24
-
浏览量:423次2023-09-25 14:19:19
-
浏览量:8957次2020-07-17 12:21:58
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
技术凯
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明