本文原创,转载请引用https://blog.csdn.net/baidu_38306313/article/details/104310931
代码已上传到GitHub:https://github.com/yufeifeiyu/Matlab-Deep-Learning-Toolbox-CNN-Water-image-recognition
本文是基于matlab深度学习工具箱来设计卷积神经网络用来对图像上的水体部分进行识别,并生成水体陆地二值化图像。采用的是9层卷积神经网络用来对图像进行特征提取和分类,水体识别的准确率可以达到96%以上。
1 引言卷积神经网络是近些年非常流行的深度学习网络结构,也是非常好用的网络模型,优点我就不多说了,大家应该都知道,直接来干货。现有的大多卷积神经网络的文章都是基于python的TensorFlow,torch,Keras等比较流行的库来实现的,很少有用matlab的深度学习工具箱来实现的(matlab的大佬们都喜欢自己撸代码),这篇文章的目的呢,就是向刚刚接触卷积神经网络,或者比较熟悉matlab的同学们使用这个比较简单使用的神经网络工具实现一个较复杂的实例。
2 数据集本文采用的数据可以是一张任意通道的水体图像,使用前,要将图像进行处理,方法是使用labelme工具对图片进行标记,具体方法就是用多边形将所有水体部分圈起来命名为water,并保存文件(json格式)。labelme的安装使用教程。
3 网络模型本文用的是一个9层的卷积神经网络模型,具体网络结构如下:
网咯层数 | 类型 | 参数 |
---|---|---|
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个神经元。 |
任意取一张水体图像,使用labelme工具对图像中的水体部分进行划分标记,labelme的安装使用教程。
如图所示将图片中的水体部分圈出来,标记为water,并点击save保存json格式的文件。
原始图片
将水体用多边形标记
将图片保存后会生成一个json格式的文件,这个文件后面的数据标记要用到。
4.2 数据标记用刚刚得到的json文件和我们原始的图片文件,就可以生成一个由水体和陆地组成的二值图,具体过程如下。
创建一张与原图大小相同的图像,默认为黑色,读取json文件中的多边形顶点数据,并把多边形内区域填充为白色,这样就可以得到一张白色表示水体,黑色代表陆地的图片。
原始图像和生成的二值化图像对比
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 m4096
m=4096;
end
if n4096
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%的输入和输出数据作为测试集数据。
实验使用的图片尺寸是550x333 RGB图像,为了保证训练效果,将其resize为1024x1024 RGB图像,之后在显示时将其转换回500x333像素。从上图中可以看出预测的图像可以很好的反映水体的范围,边缘部分也很明显,比之前人为划分的图像精度还要高。
总结:本次实验是基于卷积神经网络的图像上的水体识别,使用matlab 深度学习神经网络工具箱设计代码,实现CNN模型的创建,并使用labelme工具对图像进行划分,采用将图像分割为16x16大小的窗口的方法将图像分割并标记,生成训练集和测试集工具,最终完成本次实验,实验的水体识别准确率可以达到96%以上。实验的本次实验CNN的设计和数据集的生成是参考浙大硕士毕业论文《基于卷积神经网络的高分辨率遥感图像上的水体识别技术》一文的方法,对其进行复现。
缺点和不足:由于实验方法是参考《基于卷积神经网络的高分辨率遥感图像上的水体识别技术》一文的方法复现的,该方法是对一张图像进行训练和测试的,针对遥感图像这种类型单一的图像的的识别效果会很好,但是 仅对一张或同类型图像进行训练会对网络的泛化能力有很大影响,针对不同地域不同光照条件,不同季节和气候的水体图像识别效果就会变差很多,同一网络只适合识别一种类型的水体图像。
展望:在下一步工作中,可以收集多种类型的水体图像放入网络中进行训练,提升网络的泛化性。
【1】基于卷积神经网络的高分辨率遥感图像上的水体识别技术