本文硬件环境是:win7 64位;MATLAB R2018a;
由于第一次接触目标检测,很多东西只是照猫画虎,不甚了解,将自己成功的测试流程记录如下,方便和自己有同样需求的人拿来就用,减少学习过程中的不必要的困难。 主要参照资料1和4中的方法,进行网络的生成与测试。
本文的目标是实现在图片中对温湿度计的目标检测,效果类似于下面的图。
在生成网络前,需要对数据进行处理,即在图像中标注出温湿度计的位置。
打开MATLAB R2018a,输入命令trainingImageLabeler,使用matlab自带的trainingImageLabeler来对图片进行标注。
在matlab命令框处,输入:imageLabeler 打开Image Labeler对话框。
打开Image Labeler 后,点击Load—>Add images from folder,选中所有要标注的图片,点击确定。
本次选择51张图片标注,标注方法如上图所示,也可以参照资料1,4对数据进行标注。如果之前已经有标注好的文件,可以点击“Import Labels——>From File” 导入。这里只说两点要注意的,一是选择图像的时候,可以选择所有照片;二是标注完成后,电机工具栏右侧的“Export Labels”将文本导出,导出过程中选择文件类型,这里选的是“table”。
文件标注完毕后,可以选择“Save ”保存本次标过程文件,方便下次修改(注意:标注的结果,需要用Export Labels)。
导出的文件,格式为‘.mat’。若选择导出到工作区,变量名默认选择默认即可,格式,选择table。
如果用保存到工作区的标注结果用来训练,这部分可以忽略。
图片标注好后,我们可以得到训练图片的地址,和图片上表示温湿度计位置的数组。在训练前,需要将标注的温湿度计提取出来,更改成 227 × 227 227\times 227 227×227大小,按顺序保存下来,效果如下:
这里每张图片的分辨率都是 227 × 227 227\times 227 227×227,用来进行训练的。
图片的更改函数为:extractpeople(matpath,savepath),extractpeople这个名字来自于参考资料1,文件是识别人物的,所以是extractpeople
其中,matpath为原图片地址路径;savepath为图像处理完成后的保存路径;
function extractpeople(matpath,savepath)
%batch change image size
load(matpath);
%get image
[length b]=size(gTruth.DataSource.Source);
%get the number of image
for i=1:length
img=imread(gTruth.DataSource.Source{i});
str=zeros(1,4);
% 这里的1,2,3,4分别是标注框的坐标
% 坐标提取形式应该与你保存的数据格式(就是Image Labeler中“Export Labels”的数据格式)相对应。
% 我存下来的是cell形式,所以用{i}(j)的形式
str(1)=gTruth.LabelData.clock{i}(1);
str(2)=gTruth.LabelData.clock{i}(2);
str(3)=gTruth.LabelData.clock{i}(3);
str(4)=gTruth.LabelData.clock{i}(4);
rect=str;
I=imcrop(img,rect);
I=imresize(I,[227 227]);
imwrite(I,[savepath,'\',num2str(i),'.jpg']);
%resize image
end
end
%% Step 1: 设置网络参数
% options = trainingOptions('sgdm', ...
% 'MiniBatchSize', 4, ... %Faster-RCNN中的minibatch只能设置成1
% 'InitialLearnRate', 1e-4, ... %学习率,设置大的话训练速度快但效果比较差,甚至会发散,设置小了训练速度会较慢
% 'LearnRateSchedule', 'piecewise', ...
% 'LearnRateDropFactor', 0.1, ...
% 'LearnRateDropPeriod', 100, ...
% 'MaxEpochs', 20, ...
% 'CheckpointPath', tempdir, ...
% 'Verbose', true);
%% Step 2: 生成网络
% detector = trainFasterRCNNObjectDetector(gTruth,alexnet,options);
trainingOptions 用来设置网络训练的一些参数选项;
trainFasterRCNNObjectDetector 用来生成网络,gTruth 是对目标标注的结果;alexnet 是选择的主干网络;options 为trainingOptions设定结果。
参考资料4中,说 ‘MiniBatchSize’, 4, … %Faster-RCNN中的minibatch只能设置成1 但是我在运行过程中报错,说这里最低设成4。
用save命令可以保存训练好的网络,load用来载入保存的网络。
save(‘FasterRCNN_net_20190825.mat’, detector) #保存训练网络
load(‘FasterRCNN_net_20190825.mat’);
save和load还有其他运行格式,另外,可以在工作区网络变处,右键单击,选择另存为。我这里训练好的网络保存后,大概有1.2G数据,不知道是不是正常。
选择一张图像进行测试。在测试过程中,我发现测试图像的大小对结果影响较大。最开始我测试图像的分辨率是 4608 × 2112 4608\times 2112 4608×2112,最后测试出的结果并不准确,如下图,在图像中找到了三个疑似目标,都是圆形的部分。
将测试图像的尺寸更改后,得到效果如下:
我做了一个测试,改变图像的尺寸后在进行目标检测,结果如下:
测试总共用了12张图片。每一列表示相同的图片在不同尺寸下目标检测得分,每一行表示一次测试过程中,不同图像检测结果得分。如果没有检测到目标,填入0,如果检测到多个目标,则填入检测到的目标数量。
从表中可以看到,图像尺寸对检测结果存在影响,很难说尺寸越小检测越准确。但是如果我们检测到多个目标,或未检测到目标时,可以试着改变图像尺寸再进行检测。
测试代码如下:
img = imread('E:\DL\test\w_20190824082731.jpg');
img=imresize(img,[528 1152]);%跟图像尺寸有关系,尺寸太大,不准了,可能出现找不到,或者找到更多的问题
[bbox, score, label] = detect(detector, img);
detectedImg = insertShape(img, 'Rectangle', bbox);
figure
imshow(detectedImg)
title('检测目标')
在网络生成过程中,会产生几十G的缓存文件,很占C盘位置,所以结束后一定要对这部分文件进行清理。我找到的办法,就是用360安全卫士清理电脑。
最开始的时候没有装GPU的驱动,用CPU产生网络,速度真的很慢。所以建议安装GPU支持,能够极大的缩短网络训练时间。
安装GPU支持,需要2步。
去官网找到支持电脑显卡的驱动,并进行安装。
首先检查你电脑支持哪个版本的CUDA。
1>首先打开控制面板,在控制面板进行搜索。
2>然后,双击NVIDIA控制面板,打开如下的控制面板
3> 单击帮助按钮,选择系统信息,然后打开如下面板
4>选择组件,然后会看到红色框的内容,箭头所指的CUDA版本,就是你电脑支持的CUDA版本。
cuda历史各个版本下载链接
https://developer.nvidia.com/cuda-toolkit-archive
安装CUDA的时候,默认安装即可,一路下一步。