MATLAB环境下用DeepLabV3+实现语义分割(完整流程)

之前这篇文章介绍了MATLAB环境构建DeepLabV3+进行云层分割。但数据来源有完整标签,因此少了人工标注过程,在泛化到自己的数据集时可能会遇到障碍。

1.数据集构建

因此在MATLAB中找了自带的数据E:\MATLAB2020b\toolbox\vision\visiondata\stopSignImages (我用的2020b版本)。将这个文件夹中的图片复制出来,在根目录下建一个新的文件夹 E:\stopsignresize 并将图片放入文件夹中。

之后写一个更改图片尺寸的函数:

imagePath = 'E:\stopsignresize\';   
imageFiles = dir(imagePath); %%读取目录文件下的所有图片文件  
numFiles = length(imageFiles);%%获取图片的数量  
parfor i=3:numFiles   %%matlab 并行 其实和for一个用法               
    j = i-2;  
    disp(j); %%disp() 函数直接将内容输出在Matlab命令窗口中  
    imageFile = strcat(imagePath,imageFiles(i).name); %%strcat()函数经常出现在批量处理的时候,这个时候我们需要用到for循环,然后这个函数能够让变量和路径产生一些关系,这个时候我们就可以对其进行批量处理。
    A = imread(imageFile); %%读入图片  
    B = imresize(A,[395 700]); %%修改图片尺寸  
    imwrite(B,imageFile); %%保存图片 。           
end 

运行这段代码,将原来1630*920的图片改成700*395,否则训练检测器的时候回显示图片太大显存不足。

之后打开MATLAB自带的标注工具,在命令行输入:

或者点这里

打开标注工具:

之后,加载MATLAB视觉工具箱中自带的stopsign图片数据(图片路径:E:\stopsignresize)

 

得到如下界面:

 

这次在ROI Labels里选中Pixel label像素标签,并给背景类起名为Back

同理给StopSign类起名:

之后就可以开始标注了,语义分割的标注和目标检测的标注完全不是一个量级的,遇到复杂的样本,单张图像的标注都是以分钟来计算的。接下来咱们开始第一张图像的标注:

记得首先标注背景,再标StopSign(顺序不可颠倒)

背景按照多边形标注,标4个点形成一个矩形,然后拉一下各个顶点充满屏幕再。。。算了直接来动图吧......

都标注好后,导出到工作区(这里注意,是将所有图片标注好后统一输出一个gTruth到工作区):

导出gTruth格式:

确定后会生成gTruth,同时在文件夹里生成PixelLabelData标签:

之后运行:

 

%% 制作数据集
% 导入图片
imgDir = fullfile('E:\stopsignresize');
imds = imageDatastore(imgDir);
% 显示一张图片
I = readimage(imds,1);
I = histeq(I);
imshow(I)
% 导入并制作像素标签
classes = [
    "StopSign"
    "Background"
           ];    %定义类别名称
pxds = pixelLabelDatastore(gTruth);%制作像素类别标签

% 显示其中一张图片并叠加标注信息
C = readimage(pxds,1);
cmap = ColorMap;
B = labeloverlay(I,C,'ColorMap',cmap);
imshow(B)
pixelLabelColorbar(cmap,classes);
function cmap = ColorMap()
% Define the colormap used by CamVid dataset.

cmap = [
    255 000 000   % Back
    000 000 000   % St
        ];

% Normalize between [0 1].
cmap = cmap ./ 255;
end
function pixelLabelColorbar(cmap, classNames)
% Add a colorbar to the current axis. The colorbar is formatted
% to display the class names with the color.

colormap(gca,cmap)

% Add colorbar to current figure.
c = colorbar('peer', gca);

% Use class names for tick marks.
c.TickLabels = classNames;
numClasses = size(cmap,1);

% Center tick labels.
c.Ticks = 1/(numClasses*2):1/numClasses:1;

% Remove tick mark.
c.TickLength = 0;
end

看一下我们的标注结果:

之后进行数据分析,查看一下背景像素数量和目标像素数量比:

%% 数据分析
tbl = countEachLabel(pxds);

frequency = tbl.PixelCount/sum(tbl.PixelCount);
bar(1:numel(classes),frequency)
xticks(1:numel(classes)) 
xticklabels(tbl.Name)
xtickangle(45)
ylabel('Frequency')

很明显,大部分像素是背景,小部分像素是目标,这个比值要留着,后面构建网络的时候,输出层要加上这个权重,否则不利于训练收敛。

2.构建DeepLabV3+

%% 制作语义分割网络DeeplabV3+
% 定义网络输入大小,与图像大小相等.
imageSize = [385 700 3];

% 定义类别数量.
numClasses = numel(classes);

%构建deeplabV3+.
lgraph = deeplabv3plusLayers(imageSize, numClasses, "mobilenetv2");
% lgraph = load('Deep-MbV2.mat');
% lgraph = lgraph.mb53;%mobilenet-512分辨率-3类

% 设置类别权重
imageFreq = tbl.PixelCount ./ tbl.ImagePixelCount;
classWeights = median(imageFreq) ./ imageFreq
% 修改输出层
pxLayer = pixelClassificationLayer('Name','labels','Classes',tbl.Name,'ClassWeights',classWeights);
lgraph = replaceLayer(lgraph,"classification",pxLayer);

3.设置训练参数,训练网络

%% 设置训练参数
options = trainingOptions('adam', ...
    'LearnRateSchedule','piecewise',...
    'LearnRateDropPeriod',10,...
    'LearnRateDropFactor',0.4,...
    'InitialLearnRate',1e-4, ...
    'L2Regularization',0.005, ...
    'MaxEpochs',20, ...  
    'MiniBatchSize',8, ...
    'Shuffle','every-epoch', ...
    'VerboseFrequency',2,...
    'Plots','training-progress');
% 图像增强,
augmenter = imageDataAugmenter('RandXReflection',true,...
    'RandXTranslation',[-10 10],'RandYTranslation',[-10 10]);
pximds = pixelLabelImageDatastore(imds,pxds, ...
    'DataAugmentation',augmenter);
% 训练网络
[net, info] = trainNetwork(pximds,lgraph,options);

训练过程如下:

训练集上精度很高

4.模型性能验证

在训练集上的效果展示,路径切换至E://stopsignresize:

%% 动态演示
imagePath=pwd;
imageFiles = dir(imagePath); %%读取目录文件下的所有图片文件  
numFiles = length(imageFiles);%%获取图片的数量 
for i = 3:numFiles
    j = i-2; 
    subplot(1,2,1)
    imageFile = strcat(imagePath,'\',imageFiles(i).name);
    I = imread(imageFile);
    %I=imresize(I,[395 700]);
    imshow(I,[],'parent',gca)
    subplot(1,2,2)
    C = semanticseg(I, net);
    B = labeloverlay(I,C,'Colormap',cmap,'Transparency',0.4);
    imshow(B,[],'parent',gca)
%     pixelLabelColorbar(cmap, classes);
    pause(1)
end

从网上下几个图放在testimg文件夹下验证下泛化能力:

%% 动态演示
imagePath=pwd;
imageFiles = dir(imagePath); %%读取目录文件下的所有图片文件  
numFiles = length(imageFiles);%%获取图片的数量 
for i = 3:numFiles
    j = i-2; 
    subplot(1,2,1)
    imageFile = strcat(imagePath,'\',imageFiles(i).name);
    I = imread(imageFile);
    I=imresize(I,[395 700]);
    imshow(I,[],'parent',gca)
    subplot(1,2,2)
    C = semanticseg(I, net);
    B = labeloverlay(I,C,'Colormap',cmap,'Transparency',0.4);
    imshow(B,[],'parent',gca)
%     pixelLabelColorbar(cmap, classes);
    pause(1)
end

运行结果:

由于训练样本比较少,在网图上识别成这样的效果已经不错了,先写到这里。

感兴趣可以加q交流:2501896344

 

 

 

 

 

 

 

  • 36
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Le0virg0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值