FCN全卷积网络模型——高分辨率遥感影像地物识别

article/2025/8/19 4:49:47

FCN全卷积网络模型——高分辨率遥感影像地物识别

这是一篇操作日记

win10与ubuntu的caffe安装过程独立,只是两次不同系统下的演习,真正实验在ubuntu下完成。

操作空间

win10
1:Anaconda 2.0
2:Visual Studio 2013
3:caffe
4:python2.7
Ubuntu 16.04
cuda8.0
cudnn5.1
caffe

win10 python接口配置

本人之前未曾进行过相关学习,搜索到https://blog.csdn.net/zb1165048017/article/details/52980102这篇blog,其中配置步骤十分详细。
经测试而知,anaconda安装完成。
1.生成pycaffe
在vs2013里生成pycaffe后发生错误如下:

  错误	110	error LNK1104: 无法打开文件“python27.lib”	D:\caffe\caffe-master\windows\caffe\LINK	caffe错误	111	error C2220: 警告被视为错误 - 没有生成“object”文件	C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include\cuda_fp16.h	1	1	pycaffe修正办法:将Anaconda 3.0卸载改为2.0(别忘记修改CommonSettings里的版本),重新编译Pycaffe,任然出现错误:错误	35	error C2220: 警告被视为错误 - 没有生成“object”文件	C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include\cuda_fp16.h	1	1	pycaffe
突然想起来,pycaffe的属性没有改变c/c++的   “将警告视为错误”没有改为“否”。改正后运行成功。
![pycaffe生成成功](https://img-blog.csdnimg.cn/20190128215849483.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTM2NTUx,size_16,color_FFFFFF,t_70)

2.import caffe
使用win+R 打开命令行,输入cmd回车。有很多不懂的错误…

开学后重拾FCN配置工作,在另一篇博主那里发现,其实应该是在anaconda里打开对应的python exe,然后>>>import caffe。
结果,当然是一堆错误啦(死亡警告~)

Traceback (most recent call last):File "<stdin>", line 1, in <module>File "D:\Anaconda2\lib\site-packages\caffe\__init__.py", line 1, in <module>from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver, AdamSolverFile "D:\Anaconda2\lib\site-packages\caffe\pycaffe.py", line 15, in <module>import caffe.ioFile "D:\Anaconda2\lib\site-packages\caffe\io.py", line 8, in <module>from caffe.proto import caffe_pb2File "D:\Anaconda2\lib\site-packages\caffe\proto\caffe_pb2.py", line 6, in <module>from google.protobuf.internal import enum_type_wrapper
**ImportError**: No module named google.protobuf.internal

出现这个错误,就直接打开dos,输入 C:\windows\system32>*conda install protobuf*
它提示我 :
“‘conda’ 不是内部或外部命令,也不是可运行的程序或批处理文件。”
这应该是Anaconda没有装好的错误。
在重装了Anaconda2.0后,一切变得快又方便,所以安装这一步真的很重要,版本信息是否和其他软件匹配也必须注意!(之前装的cudnn版本太高,还没降,瑟瑟发抖…)
import caffe后不成功,便第一时间想到是没有装protobuf 在dos端(有的博主说要转到Anaconda Scripts目录下执行)直接 使用conda install protobuf(有博主说这个不行切换为pip install protobuf也可以,但是我这里试了后发现不行,就两个都装了)
conda install protobuf
在Proceed那里,突然暂停了,等了好久也没反应,按了回车才出现的。
回到Anaconda2里的python.exe,执行import caffe 没有报错,也没有其他信息提供给我,算是成功了?
![import caffe(https://img-blog.csdnimg.cn/20190308132356230.png)
接下来下载FCN放在caffe目录下,测试一张图片,识别率0.92.
分割后融合
上面只是在ubuntu正式训练之前的预热,因为那时候导师还没有给我台式机的使用权~~。

win10安装双系统ubuntu16.04

安装过程直接百度,需要准备一个可格式化的U盘,至少20G吧。
安装ubuntu的电脑是办公室台式服务器,只有它才带的动我的模型啊~~~
按照教程下载Ubuntu16.04LTS、U盘制作软件rufus、设置系统启动模式的EasyBCD,需要可留言,网盘似乎有存档。
分割磁盘大概需要200-300G(前提是内存有那么大),如果只是拿来玩玩100G也够,这里分盘需要记住每个盘大概多大,不行就截个图,后面EasyBCD启动需要用到。
重启后疯狂点击某个键(不同电脑打开方式不同,有F8,F1,F2等)打开bios,设置从U盘启动。
and,第一次一定要设置语言为English,不然后面安装caffe时第一步禁用nouveau会乱码,不习惯英文,安装完caffe之后再切换也没关系的。

ubuntu下配置caffe

大致包括这几个步骤:安装依赖包 、禁用 nouveau 、配置环境变量 、下载 CUDA 8.0
、安装 CUDA 8.0 、验证 CUDA 8.0 是否安装成功 、安装 cudnn 、安装 opencv3.1 、安装 caffe
大致参考的https://blog.csdn.net/yhaolpz/article/details/71375762这篇文章,其中会有报错,一个个解决就Ok。
ps…open cv、pycaffe notebook 可以不装,相应地,Makefile.config 里的屏蔽也可以不取消。

caffe中配置FCN

将下载的FCN模型放置在caffe目录下,个人习惯备份一份原始代码在硬盘上。

labelme影像贴图

贴图之前要将影像裁剪为一样大小(128x128或256x256或512x512),本人使用的arcGIS的splitRaster工具,将影像裁为256x256的jpg格式图像。
数据集按照3:7分为验证集和训练集,使用rename.py对图像全部重命名,注意:python中不允许有中文字符出现,即使是注释也不行!

#coding:utf-8
import os
path = "...\Users\Administrator\Desktop\train"     #替换为自己的目录
filelist = os.listdir(path) 
count=0              #从0开始  
for file in filelist:   Olddir=os.path.join(path,file)  if os.path.isdir(Olddir):  continuefilename=os.path.splitext(file)[0]   filetype=os.path.splitext(file)[1]  Newdir=os.path.join(path,'train_'+str(count).zfill(4)+filetype)     #输出目录+文件名+filetype文件类型os.rename(Olddir,Newdir)print('train_'+str(count).zfill(4))                             #这里记得把print出来的文件名全部复制到一个txt文件中去,后面fcn模型中train和test需要用到!count+=1
input()

输出结果为“train_0000.jpg”、“train_0001.jpg”…
本人下载的label是最简单版本的,安装过程与https://www.cnblogs.com/wangxiaocvpr/p/9997690.html大致相同,为了方便操作,该插件是在本人笔记本上安装的,直接使用命令端调用labelme,具体安装过程请移步百度。
贴图完成后会生成json文件,我一般打开labelme后就会把output_dir和input_dir设置好,点击自动保存按钮,因为有时候贴图超过图片所在范围labelme就会崩掉,下一次打开记录仍然在,且直接点击next就可以切换到下一张。
json_to_dataset.exe,原本的代码是一个个转的,这里贴出本人的批量转换代码:

import argparse
import base64
import json
import os
import os.path as ospimport PIL.Image
import yamlfrom labelme.logger import logger
from labelme import utilsdef main():logger.warning('This script is aimed to demonstrate how to convert the''JSON file to a single image dataset, and not to handle''multiple JSON files to generate a real-use dataset.')parser = argparse.ArgumentParser()     parser.add_argument('File')parser.add_argument('-o', '--out', default=None)args = parser.parse_args()files = os.listdir(args.File)for i in range(0,len(files)):print(files[i])json_file = os.path.join(args.File,files[i])if args.out is None:out_dir = osp.basename(json_file).replace('.', '_')out_dir = osp.join(osp.dirname(json_file), out_dir)else:out_dir = args.outif not osp.exists(out_dir):os.mkdir(out_dir)data = json.load(open(json_file))if data['imageData']:imageData = data['imageData']else:imagePath = os.path.join(os.path.dirname(json_file), data['imagePath'])with open(imagePath, 'rb') as f:imageData = f.read()imageData = base64.b64encode(imageData).decode('utf-8')img = utils.img_b64_to_arr(imageData)label_name_to_value = {'_background_': 0}for shape in sorted(data['shapes'], key=lambda x: x['label']):label_name = shape['label']if label_name in label_name_to_value:label_value = label_name_to_value[label_name]else:label_value = len(label_name_to_value)label_name_to_value[label_name] = label_valuelbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)label_names = [None] * (max(label_name_to_value.values()) + 1)for name, value in label_name_to_value.items():label_names[value] = namelbl_viz = utils.draw_label(lbl, img, label_names)num=os.path.splitext(files[i])[0]                   ###split the file  count[i] --> 0030.json to 0030 and .jsonPIL.Image.fromarray(img).save(osp.join(out_dir, 'img.png'))utils.lblsave(osp.join(out_dir, num+'.png'), lbl)          ###输出贴图png文件名与json文件名相同PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, 'label_viz.png'))with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:for lbl_name in label_names:f.write(lbl_name + '\n')#logger.warning('info.yaml is being replaced by label_names.txt')info = dict(label_names=label_names)with open(osp.join(out_dir, 'info.yaml'), 'w') as f:yaml.safe_dump(info, f, default_flow_style=False)logger.info('Saved to: {}'.format(out_dir))print('Saved to: %s' % out_dir)if __name__ == '__main__':main()

之前参考了一些其他博主的批量转换,结果是错的,融合图的图例会变成1:0background、2:4 0100、3:2 0200 这样(0100、0200是我的标签名),实际应该是下图这样:
在这里插入图片描述
不过这里本人有个疑问:labelme使用json_to_dataset后我的标签图是8位彩色,并非其他博主说的8位灰度图,不知道是不是labelme更新了版本?参考github给出的labelme代码说明,贴图label也是彩色的。

FCN模型训练及测试

本人是仿照voc数据集制作的,将测试集(包括:jpg原图+png贴图)放在pascal/voc2012目录下对应位置,训练集放在sbdd/banchmark/benchmarkRelease目录下对应位置,其中,sbdd需要新建,banchmark文件需要下载,下载地址 https://pan.baidu.com/s/1bhPulA6M4fXZH9Nl3yfCYA mm:i9st
将上面rename.py后复制的图片文件名复制到相应的训练集train.txt、验证集seg11valid.txt中去,在训练的时候会调用该文件夹来读取图片。
另外,不知道大家有没有把图片从win10复制到ubuntu下拓展名变成大写JPG的情况,反正我是有,写一个bat文件,放在win10的图片文件夹下跑一遍就Ok了。
超参数、分类数、迭代次数和权重获取方式等都是按照自己的情况修改。
net.py文件中有个计算平均RGB的地方,看有的博主修改了,有的没有修改,在此奉上从别人那里借鉴的计算代码:

import os
from PIL import Image  
import matplotlib.pyplot as plt
import numpy as np
from scipy.misc import imread filepath = '/home/zjhzwhj/caffe/fcn.berkeleyvision.org-master/data/sbdd/benchmark/benchmark_RELEASE/dataset/img' 
pathDir = os.listdir(filepath)R_channel = 0
G_channel = 0
B_channel = 0
for idx in xrange(len(pathDir)):filename = pathDir[idx]img = imread(os.path.join(filepath, filename))R_channel = R_channel + np.sum(img[:,:,0])G_channel = G_channel + np.sum(img[:,:,1])B_channel = B_channel + np.sum(img[:,:,2])num = len(pathDir) * 256 * 256 
R_mean = R_channel / num
G_mean = G_channel / num
B_mean = B_channel / numprint("R_mean is %f, G_mean is %f, B_mean is %f" %(R_mean, G_mean, B_mean))

修改好net.py中的num_output=21的地方和数据集地址后,运行python net.py,train.prototxt、val.prototxt会相应改动,不需要自己手动修改!
其他也没什么好说的,需要详细教程的可以参考这一篇的后半部分:https://blog.csdn.net/zoro_lov3/article/details/74550735

summary

受到样本数据集太小的影响,加上我用的影像光谱分辨率不够高,即使用了fine-tune,精度最高也只有0.60,与预期效果相差甚远,但也算是一次caffe小小实践。训练+数据处理前后耗时大半个月,年前配置caffe耗费一个星期,安装双系统对本人来说也是一个未知领域,算是给大学生活留下最后一笔财富,前两天提交了毕业论文终稿,接下来就是答辩啦,请叫我过儿!!!
第一次开博,写得不够好,一些地方也只是个人理解,望各位大佬多多批评指正!


http://chatgpt.dhexx.cn/article/bJe1gOE0.shtml

相关文章

高分辨率遥感影像融合技巧

软件下载地址&#xff1a; https://pan.baidu.com/s/1dt0yDUsAork9LnLnZTwCgw 需要百度网盘下载密码&#xff0c;留言邮箱地址。 或联系联系 QQ&#xff1a;1257396288​ 该软件包含高分辨率遥感影像融合功能&#xff08;pansharp2&#xff09;&#xff0c;融合效果好&#…

【GIS】高分辨率遥感影像智能解译

1 绪论 随着航空科技工业的不断成熟与发展&#xff0c;我国遥感卫星研制能力不断攀升&#xff0c;发射数量逐年提高&#xff0c;在轨运行的遥感卫星为社会生产及居民日常生活提供了巨大的支持与便利。我国目前同时在轨运行的遥感卫星数量已超过60颗&#xff0c;每天获取并传回…

数据结构学习笔记(四)—— 树

树 文章目录 树一.树的基本概念二.树的遍历1.先序遍历2.后序遍历3.中序遍历4.层序遍历 三.树的存储表示和操作实现1.双亲表示法2.孩子表示法3.双亲孩子表示法4.孩子兄弟表示法 四.树的性质五.二叉树基本概念与定义二叉树的特殊形态——斜树二叉树的特殊形态——满二叉树二叉树的…

sklearn学习(集成算法:随机森林)

随机森林树 一.概述【1】集成算法概述1.概念与应用2.集成算法的目标3.其他定义 【2】sklearn中的集成算法1.sklearn中的集成算法模块ensemble&#xff08;1&#xff09;类与类的功能 2.复习&#xff1a;sklearn中的决策树3.sklearn的基本建模流程 二.RandomForestClassifier【1…

数据结构与算法之树(三)AVL树

数据结构与算法之树 数据结构与算法之树&#xff08;一&#xff09;二叉树概念及遍历方式&#xff08;图文并茂&#xff09; 数据结构与算法之树&#xff08;二&#xff09;二叉查找树 数据结构与算法之树&#xff08;三&#xff09;AVL树 数据结构与算法之树&#xff08;四…

C语言数据结构总结:树

树 一&#xff0c;树的定义二&#xff0c;树的基本术语三&#xff0c;二叉树的定义四&#xff0c;二叉树的性质和存储结构五&#xff0c;关于二叉树的算法 一&#xff0c;树的定义 树是n&#xff08;n>0&#xff09;个结点的有限集合。 若n0&#xff0c;称为空树。 若n>…

【C++从入门到入土】第二十一篇:二叉搜索树之AVL树

AVL树 文章目录 AVL树一、AVL树1.特点2.操作旋转插入删除查找 一、AVL树 在计算机科学中&#xff0c;AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1&#xff0c;所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平…

数据结构--二叉搜索树

二叉搜索树 一丶概念以及特点二丶相关操作定义TreeMap类put()操作--插入节点get()操作--得到key对应的value值getOrDefault()操作containsKey()操作--检查key是否存在containsValue()操作--检查value是否存在remove()操作--删除操作思路&#xff08;1&#xff09;叶子结点&…

Java数据结构--树2

Java数据结构--树 一、平衡树1.1 2-3 查找树1.1.1 2-3查找树的定义1.1.2 查找1.1.3 插入1.1.3.1 向2-结点中插入新键1.1.3.2 向一棵只含有一个3-结点的树中插入新键1.1.3.3 向一个父结点为2-结点的3-结点中插入新键1.3.1.4 向一个父结点为3-结点的3-结点中插入新键1.3.1.5 分解…

数据结构之多路查找树

多路查找树 一、2-3树1.1 查找1.2 2-3树的插入实现1.3 2-3树的删除节点 二、2-3-4树三、总结 二叉排序树简单的实现在多数情况能够达到预期的查找效率&#xff0c;但是每个节点只能存储一个元素和只能有两个孩子&#xff0c;使得在大量数据下会造成二叉排序树的深度特别大&…

【数据结构 7】二叉查找树及其Java实现

【数据结构 1】顺序表及其Java实现 【数据结构 2】单向链表及其Java实现 【数据结构 3】双向链表及其Java实现 【数据结构 4】栈及其Java实现 【数据结构 5】队列及其Java实现 【数据结构 6】符号表及其Java实现&#xff08;使用链表实现&#xff09; 【数据结构 7】二叉查找树…

C++从入门到精通(第十篇) :二叉搜索树

二叉搜索树 一&#xff1a;二叉搜索树概念二&#xff1a; 二叉搜索树实现节点的定义二叉搜索树实现 三&#xff1a;二叉搜索树的应用四&#xff1a;二叉树有关面试题ps 很多小伙伴为了刷题发愁 今天为大家推荐一款刷题神奇哦&#xff1a;刷题面试神器牛客 各大互联网大厂面试真…

数据结构与算法之树(二)二叉查找树

数据结构与算法之树 数据结构与算法之树&#xff08;一&#xff09;二叉树概念及遍历方式&#xff08;图文并茂&#xff09; 数据结构与算法之树&#xff08;二&#xff09;二叉查找树 数据结构与算法之树&#xff08;三&#xff09;AVL树 数据结构与算法之树&#xff08;四…

【算法修炼】二叉搜索树

学习自&#xff1a;https://labuladong.gitee.io/algo/2/19/26/ 二叉搜索树 一、BST的中序遍历230、二叉搜索树中第k小的元素&#xff08;中等&#xff09;1038、从二叉搜索树到更大和树&#xff08;中等&#xff09; 二、判断BST的合法性※98、验证二叉搜索树&#xff08;中等…

数据结构(C语言)-树

树 一、树1、树的定义2、树的基本术语3、树结构和线性结构的比较 二、二叉树1、二叉树的定义2、二叉树的形态与树的形态3、二叉树的性质4 、二叉树的存储结构5、遍历二叉树6、二叉树的其他操作7、线索二叉树 三、树与二叉树的转换1、树转换成二叉树2、二叉树变树 四、哈夫曼树1…

【数据结构与算法】程序内功篇六--树

程序内功篇六--树 一、树1、树的含义2、树的特点(选看)3、树的逻辑结构 二、二叉树1、二叉树的含义2、二叉树性质3、二叉树-顺序存储4、二叉树-链式存储5、二叉树的遍历6、二叉树创建与遍历C程序的实现&#xff08;1&#xff09;二叉树的创建&#xff08;2&#xff09;前序遍历…

数据结构---与树相关的知识

与树有关的一系列知识: 树,二叉树,满二叉树,完全二叉树,文章还没完,我会后序补充的 一: 树(了解就行)1.1 概念1.2 一些与树相关的重要概念1.3 树的表示形式 二: 二叉树(非常重要,重点掌握)2.1 概念2.2 两种特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树 2.3 二叉树的性质2.4 二叉…

Java数据结构--树1

Java数据结构--树 一、二叉树入门1.1 树的基本定义1.2 树的相关术语1.3 二叉树的基本定义1.4 二叉查找树的创建1.4.1 二叉树的结点类1.4.2 二叉查找树API设计1.4.3 二叉查找树实现1.4.4 二叉查找树其他便捷方法1.4.4.1 查找二叉树中最小的键1.4.4.2 查找二叉树中最大的键 1.5 二…

树 一

文章目录 1.查找二分查找判定树 2. 树(Tree)2.1 树的术语2.2树的表示&#xff1a;儿子兄弟表示法 3. 二叉树&#xff08;Binary Tree&#xff09;3.1 特殊结构二叉树3.2 二叉树的性质3.3 二叉树的存储3.4二叉树的遍历 分层次组织管理上更有效地操作。 1.查找 静态查找&#xf…

树一:邂逅入门篇

一、树的概念 树是一种典型的非线性结构&#xff0c;是表达有层次特性的图结构的一种方法。 1.1 基本术语 术语描述空树当n0 时称为空树。根结点根结点是一个没有双亲结点的结点。一棵树最多一个。例如&#xff1a;A边结点之间的连线叶子结点没有孩子结点的结点。例如&#x…