基于Matlab Deep Learning Toolbox的卷积神经网络实现在图像上的水体识别任务

本文原创,转载请引用https://blog.csdn.net/baidu_38306313/article/details/104310931

代码已上传到GitHub:https://github.com/yufeifeiyu/Matlab-Deep-Learning-Toolbox-CNN-Water-image-recognition
也可在CSDN中下载:https://download.csdn.net/download/baidu_38306313/12584271

摘要

本文是基于matlab深度学习工具箱来设计卷积神经网络用来对图像上的水体部分进行识别,并生成水体陆地二值化图像。采用的是9层卷积神经网络用来对图像进行特征提取和分类,水体识别的准确率可以达到96%以上。补充说明一下,本次实验是在MATLAB2017b版本下完成的,其他版本可能会有报错。

1 引言

卷积神经网络是近些年非常流行的深度学习网络结构,也是非常好用的网络模型,优点我就不多说了,大家应该都知道,直接来干货。现有的大多卷积神经网络的文章都是基于python的TensorFlow,torch,Keras等比较流行的库来实现的,很少有用matlab的深度学习工具箱来实现的(matlab的大佬们都喜欢自己撸代码),这篇文章的目的呢,就是向刚刚接触卷积神经网络,或者比较熟悉matlab的同学们使用这个比较简单使用的神经网络工具实现一个较复杂的实例。

2 数据集

本文采用的数据可以是一张任意通道的水体图像,使用前,要将图像进行处理,方法是使用labelme工具对图片进行标记,具体方法就是用多边形将所有水体部分圈起来命名为water,并保存文件(json格式)。labelme的安装使用教程。

3 网络模型

本文用的是一个9层的卷积神经网络模型,具体网络结构如下:
表3.1 网络模型参数表

网咯层数类型参数
1输入层数据大小16x16xk,k为图像通道数。
2卷积层16个3*3大小的卷积核,步长为1,对边界补0。
3池化层使用2*2的核,步长为2。
4卷积层32个3*3大小的卷积核,步长为1,对边界补0。
5池化层使用2*2的核,步长为2。
6卷积层64个3*3大小的卷积核,步长为1,对边界补0。
7池化层使用2*2的核,步长为2。
8全连接层30个神经元。
9全连接层2个神经元。

4 实验流程

4.1 数据预处理

任意取一张水体图像,使用labelme工具对图像中的水体部分进行划分标记,labelme的安装使用教程。

如图所示将图片中的水体部分圈出来,标记为water,并点击save保存json格式的文件。原始图片
图4.1 原始图片
将水体用多边形标记
图4.2 将水体用多边形标记的图片

将图片保存后会生成一个json格式的文件,这个文件后面的数据标记要用到。

4.2 数据标记

用刚刚得到的json文件和我们原始的图片文件,就可以生成一个由水体和陆地组成的二值图,具体过程如下。

创建一张与原图大小相同的图像,默认为黑色,读取json文件中的多边形顶点数据,并把多边形内区域填充为白色,这样就可以得到一张白色表示水体,黑色代表陆地的图片。
在这里插入图片描述
图4.3 原始图像和生成的二值化图像对比图

DataMark.m


fname='image.json'; %待读取的文件名称
image_name='image.jpg';%待读取的图片名称
addpath('jsonlab\jsonlab'); %jsonlab库文件存放路径
jsonData=loadjson(fname);
image=imread(image_name);
[m,n,k]=size(image);
m=ceil(m/16)*16;`在这里插入代码片`
n=ceil(n/16)*16;

%根据labelme的划分生成划分图像
I=zeros(m,n);
label=I;
subplot(1,2,1),imshow(image),title('original');
[i,j]=size(jsonData.shapes);
for i=1:j
    c = jsonData.shapes{1, i}.points(:,1);
    r =  jsonData.shapes{1, i}.points(:,2);
    BW = roipoly(zeros(m,n),c,r);
    label = label+BW;
end
subplot(1,2,2),imshow(label),title('Water display');
%调整图像的大小
if m<1024
    m=1024;
elseif m>4096
    m=4096;
end
if n<1024
    n=1024;
elseif n>4096
    n=4096;
end
label=imresize(label,[m,n]);


save('image_label.mat','label','image_name','m','n','k')

4.3 训练集和测试集的生成

1.按照16x16的窗口大小对原图像进行分割,也就是生成16,16,k,m/16乘n/16的4D-array作为输入数据。
2.按照16x16的窗口大小对生成的标记二值化图像进行分割,比较每个窗口的白色像素点和黑色像素点的数量,如果白色像素点数量大于黑色像素点数量,则代表该窗口表示水体,标记为1,反之表示陆地,标记0。得到一个大小为m/16乘n/16的向量作为输出数据。
3.取80%的输入和输出数据作为训练集数据,取20%的输入和输出数据作为测试集数据。

5 实验结果

在这里插入图片描述
图5.1 原始图像、标机图像、识别图像对比图
实验使用的图片尺寸是550x333 RGB图像,为了保证训练效果,将其resize为1024x1024 RGB图像,之后在显示时将其转换回500x333像素。从上图中可以看出预测的图像可以很好的反映水体的范围,边缘部分也很明显,比之前人为划分的图像精度还要高。

6 总结和展望

总结:本次实验是基于卷积神经网络的图像上的水体识别,使用matlab 深度学习神经网络工具箱设计代码,实现CNN模型的创建,并使用labelme工具对图像进行划分,采用将图像分割为16x16大小的窗口的方法将图像分割并标记,生成训练集和测试集工具,最终完成本次实验,实验的水体识别准确率可以达到96%以上。实验的本次实验CNN的设计和数据集的生成是参考浙大硕士毕业论文《基于卷积神经网络的高分辨率遥感图像上的水体识别技术》一文的方法,对其进行复现。
缺点和不足:由于实验方法是参考《基于卷积神经网络的高分辨率遥感图像上的水体识别技术》一文的方法复现的,该方法是对一张图像进行训练和测试的,针对遥感图像这种类型单一的图像的的识别效果会很好,但是 仅对一张或同类型图像进行训练会对网络的泛化能力有很大影响,针对不同地域不同光照条件,不同季节和气候的水体图像识别效果就会变差很多,同一网络只适合识别一种类型的水体图像。
展望:在下一步工作中,可以收集多种类型的水体图像放入网络中进行训练,提升网络的泛化性。

7 参考文献

【1】基于卷积神经网络的高分辨率遥感图像上的水体识别技术

8 问题补充

问题1:

错误使用 nnet.cnn.layer.Convolution2DLayer.parseInputArguments (line 252) ‘Padding’ 的值无效。它必须满足函数:iIsNaturalNumberScalarOrRowVectorOfTwo。
出错 convolution2dLayer(line73)args=nnet.cnn.layer.Convolution2DLayer.parseInputArguments(varargin{:});
出错main(line67)convolution2dLayer(3,16,‘Padding’,‘same’)3*3
这个是由于使用的matlab版本不同,导致的函数不支持,建议重装对应版本,但也不排除有其他解决问题的方法。

问题2:

在这里插入图片描述
这个是由于CUDA没有设置好,可以参考这个方法解决。

  • 11
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值