遥感图像地物分类流程

遥感图像地物分类流程

1. 制作标签

使用arcgis pro或者arcgis或者envi,画标签,保存为tiff格式

2. 处理标签数据

用python gdal库安装 osgdal库,如果安装失败就需要下载 对应库得 .whl去安装,网站具体搞忘了,可以百度

或者rasterio库

2.1 读入tif数据
def readTif(fileName):"""dataset包含了tif文件得属性比如波段数高宽数据"""dataset = rasterio.open(fileName)if dataset == None:print(fileName + "文件无法打开")return None# print(dataset.width)return dataset
2.2 处理数据
import csv
# 提取栅格图像信息,制作数据
ori_dataset = readTif(orgin_path)
label_dataset = readTif(sample_path)width = ori_dataset.width # 宽
height = ori_dataset.height # 高bands = ori_dataset.count # 波段数
# ori_data = for k in range(bands)label_matri = label_dataset.read(1) #读出标签的矩阵
data_matri = ori_dataset.read() #原始图像的矩阵count = np.count_nonzero(label_matri) #非零就是标签, 有多少非零的就代表样本像素是多少
print(count)
train_data = np.zeros((count, 8), dtype=data_matri.dtype) # 新建一个count*8的numpy数组,第8维度是原始图像的某一像素点对应的标签,0~6代表这一个像素点对应的7ge波段,landsata影像
nonzero_indices = np.nonzero(label_matri) #非零索引, 返回的是
"""
(row:array([ 30,  31,  31, ..., 390, 390, 390], dtype=int64), col:array([166, 165, 166, ..., 186, 187, 188], dtype=int64))
"""
print(nonzero_indices)
# 写入数据csv, 提取训练数据
# 将 train_data 写入 CSV 文件
csv_file = open(csv_filename, mode='w', newline='')
csv_writer = csv.writer(csv_file)
# 写入 CSV 文件的标题行,包括 Label 和 LabelName
csv_writer.writerow(csv_head_name)for i in range(count):print(i)row, col = nonzero_indices[0][i], nonzero_indices[1][i]train_data[i, :7] = data_matri[:, row, col]train_data[i, 7] = label_matri[row, col]label = int(train_data[i, 7])row_data = train_data[i]row_data = np.append(row_data, labels_name[label])  # 在数据行中添加 LabelNamecsv_writer.writerow(row_data)print(f"已将数据写入 CSV 文件: {csv_filename}")
csv_file.close()
2.3 数据格式

生成的数据格式如下

Band1,Band2,Band3,Band4,Band5,Band6,Band7,Label,LabelName
812,774,969,1111,1152,1146,1069,2,building
801,755,846,1016,1177,1411,1472,2,building
794,748,949,1179,1202,1399,1383,2,building
605,567,691,877,1537,1880,2070,2,building
602,556,768,994,1506,1625,1607,2,building
613,570,768,1045,1394,1483,1460,2,building
465,408,562,772,963,1035,990,2,building
549,484,648,828,969,1096,1028,2,building

3. 训练

from sklearn.ensemble import RandomForestClassifier
from sklearn import model_selection
import pickleX = train_data[:, :7]
Y = train_data[:, 7]
# print(X.shape)
# print(Y.shape)
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, Y, test_size=0.1, random_state=42, stratify=Y)
print(y_train)
# 3.用100个树来创建随机森林模型,训练随机森林
classifier = RandomForestClassifier(n_estimators=100,bootstrap = True,max_features = 'sqrt')
classifier.fit(X_train, y_train)#  4.计算随机森林的准确率
print("训练集:",classifier.score(X_train,y_train))
print("测试集:",classifier.score(X_test,y_test))pred_test_y = classifier.predict(X_test)
cfm = CFM(5, labels_name)
cfm.update(pred_test_y, y_test)
acc, comment_numpy = cfm.get_cfm()
print(comment_numpy)
cfm.plot()file = open(model_path, "wb")
#将模型写入文件:
pickle.dump(classifier, file)
#最后关闭文件:
file.close()

4. 使用模型预测

pred_dataset = readTif(pred_path)
pred_width = pred_dataset.width
pred_height = pred_dataset.height
pred_bands = pred_dataset.count
pred_geotrans = pred_dataset.transform
pred_crs = pred_dataset.crsprint(pred_geotrans)
print(pred_crs)file = open(model_path, "rb")
# 把模型从文件中读取出来
rf_model = pickle.load(file)
# 关闭文件
file.close()pred_martix = pred_dataset.read()
data = np.zeros((pred_martix.shape[0], pred_martix.shape[1] * pred_martix.shape[2]))# print(pred_martix.shape)
# print(pred_martix[0])
for i in range(pred_martix.shape[0]):# 第i个波段一维数组data[i] = pred_martix[i].flatten()
# 转换下维度
pred_x = data.swapaxes(0, 1)pred_y = rf_model.predict(pred_x)
# print(pred_y, pred_y.shape)# 将标签还原为图像的二维矩阵
pred_image = pred_y.reshape(pred_martix.shape[1], pred_martix.shape[2])
height_, width_ = pred_image.shape
tif_data = np.zeros((height_, width_, 3), dtype=np.int64)
for label, color in color_mapping.items():tif_data[pred_image == label] = colortif_data = np.transpose(tif_data, (2, 0, 1))im_bands, im_height, im_width = tif_data.shape
driver = gdal.GetDriverByName("GTiff")
dataset = driver.Create(pred_result_tif_path, im_width, im_height, im_bands, gdal.GDT_Byte)
for i in range(im_bands):dataset.GetRasterBand(i + 1).WriteArray(tif_data[i])
# if dataset != None:
#     #将栅格数据和地理坐标系统关联起来
#     dataset.SetProjection(pred_crs)  # 写入投影
#     dataset.SetGeoTransform(pred_geotrans)  # 写入仿射变换参数dataset = None

5. other

import numpy as np
import matplotlib.pyplot as plt
from prettytable import PrettyTableclass CFM:"""混淆矩阵类返回精度和混淆举证"""def __init__(self, num_classes: int, labels: list):self.matrix = np.zeros((num_classes, num_classes))self.num_classes = num_classesself.labels = labelsdef plot(self):matrix = self.matrixprint(matrix)plt.imshow(matrix, cmap=plt.cm.Blues)# 设置x轴坐标labelplt.xticks(range(self.num_classes), self.labels, rotation=45)# 设置y轴坐标labelplt.yticks(range(self.num_classes), self.labels)# 显示colorbarplt.colorbar()plt.xlabel('True Labels')plt.ylabel('Predicted Labels')plt.title('Confusion matrix')# 在图中标注数量/概率信息thresh = matrix.max() / 2for x in range(self.num_classes):for y in range(self.num_classes):# 注意这里的matrix[y, x]不是matrix[x, y]info = int(matrix[y, x])plt.text(x, y, info,verticalalignment='center',horizontalalignment='center',color="white" if info > thresh else "black")plt.tight_layout()plt.show()def update(self, preds, labels):"""_summary_Args:preds (_type_): _description_labels (_type_): _description_preds:预测值labels:真实值confusion martixlabel0 label1 label2 label3pred0pred1pred2pred3"""for p, t in zip(preds, labels):self.matrix[p, t] += 1print("confusion matrix", self.matrix)def get_cfm(self):"""Accuarcy: 正确样本占总样本数量的比例Percision: 精度PrecisionRecall: 召回率Specificaity: 特异性"""sum_true = 0for i in range(self.num_classes):sum_true += self.matrix[i, i]acc = sum_true / np.sum(self.matrix)print("the model accuracy is ", acc)comment_labels = ["categeory", "Precision", "Recall", "Specificity"]tabel = PrettyTable()tabel.field_names = comment_labelscomment_numpy = np.zeros((self.num_classes, 3))for i in range(self.num_classes):# 第i个分类的精确率, 召回率, 特异度TP = self.matrix[i, i]FP = np.sum(self.matrix[i, :]) - TPFN = np.sum(self.matrix[:, i]) - TPTN = np.sum(self.matrix) - TP - FN - FP# 保留三位小数, 如果 TP + FN 不等于零,就计算并将结果四舍五入到小数点后三位;否则,率设置为0。Precision = round(TP / (TP + FP), 3) if TP + FP != 0 else 0.Recall = round(TP / (TP + FN), 3) if TP + FN != 0 else 0.Specificity = round(TN / (TN + FP), 3) if TN + FP != 0 else 0.tabel.add_row([self.labels[i], Precision, Recall, Specificity])comment_numpy[i] = [Precision, Recall, Specificity]print(tabel)return acc, comment_numpyif __name__ == "__main__":cfm = CFM(2, ["cat", "dog"])actual = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]predicted = [1, 0, 1, 0, 0, 1, 1, 1, 1, 0]cfm.update(predicted, actual)acc, comment_numpy = cfm.get_cfm()print(comment_numpy)cfm.plot()

变量名代表得含义

sample_path = "../sample/sample.tif" #标签图
orgin_path = "../datasets/landsat.tif" #原始图
pred_path = "../datasets/landsat.tif" #需要预测的图
txt_Path = "./result/label_data.txt" #无
labels_name = ["", "tudi", "building", "veg", "water"] # 样本名字,分类的类别
csv_filename = '../result/train_data.csv' # 生成训练数据的存放路径
csv_head_name = ['Band1', 'Band2', 'Band3', 'Band4', 'Band5', 'Band6', 'Band7', 'Label', "LabelName"] # 存放格式
model_path = "../model/myrnf.pickle" # 最终保存的模型路径
pred_result_tif_path = "../result/pred_landsat.tif" # 用训练的模型保存的路径
color_mapping = {1: (255, 255, 0),2: (255, 0, 0),3: (0, 255, 0),4: (0, 0, 255)
}
# 颜色映射从2D标签映射到3D

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/758583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13年资深测试,性能测试常见指标分析总结,看这篇就够了...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、什么是性能测试…

Reactive: Vue3数据更新但是表单没有更新

这两天在折腾前端, 因为前端基础不牢靠, 所以,通常都是猜一半, 查一半, 基本上也就是个面向百度编程。 过程中碰到了一个问题, 就是在编辑table的时候, 明明我把pinia的数据缓存更新了&#xf…

LeetCode 面试经典150题 238.除自身以外数组的乘积

题目: 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c…

Kotlin runBlocking CoroutineScope synchronized简单死锁场景

Kotlin runBlocking CoroutineScope synchronized简单死锁场景 import kotlinx.coroutines.*fun main(args: Array<String>) {runBlocking {val lock1 Any()val lock2 Any()CoroutineScope(Dispatchers.IO).launch {repeat(10) {println("A-$it 申请 lock1...&quo…

【SpringBoot】优雅实现超大文件上传

前言 文件上传是一个老生常谈的话题了&#xff0c;在文件相对比较小的情况下&#xff0c;可以直接把文件转化为字节流上传到服务器&#xff0c;但在文件比较大的情况下&#xff0c;用普通的方式进行上传&#xff0c;这可不是一个好的办法&#xff0c;毕竟很少有人会忍受&#…

Http 超文本传输协议基本概念学习摘录

目录 HTTP协议 超文本传输协议 HyperText超文本 HTML超文本标记语言 HTTP协议原理 请求发送 服务器处理 响应发送 连接关闭或保持 HTTP协议版本 HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 HTTP请求方法 GET POST PUT DELETE HEAD OPTIONS HTTP请求头字…

python中的类与对象

前言 在Python中&#xff0c;类是一种用于创建新类型对象的结构&#xff0c;它允许我们将数据和功能&#xff08;属性和方法&#xff09;封装到一个单独的逻辑单元中。类可以被看作是创建对象&#xff08;实例&#xff09;的蓝图或模板。类&#xff08;Class&#xff09;和对象…

JVM学习-类加载

目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展&#xff1a;反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…

猜数字游戏有三变(Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

小白学视觉 | 超详细!Python中 pip 常用命令

本文来源公众号“小白学视觉”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;超详细&#xff01;Python中 pip 常用命令 相信对于大多数熟悉Python的人来说&#xff0c;一定都听说并且使用过pip这个工具&#xff0c;但是对它的了…

中国联通推出了一站式全流程的专业安全服务

中国联通依托多年深耕通信与信息安全领域的丰富经验和专业技术积累&#xff0c;推出了一站式全流程的专业安全服务&#xff0c;从网络环境的前期准备阶段直至正式运行&#xff0c;均提供全面、立体、高效的保障措施&#xff0c;确保各类企事业单位在网络空间的安全稳定。 请点击…

算法打卡day23|回溯法篇03|Leetcode 39. 组合总和、40.组合总和II、131.分割回文串

算法题 Leetcode 39. 组合总和 题目链接:39. 组合总和 大佬视频讲解&#xff1a;组合总和视频讲解 个人思路 这道组合题主要是有总和的限制&#xff0c;当递归和超过了总和就return&#xff0c;递归时加上回溯去遍历数组。 解法 回溯法 把组合问题抽象为如下树形结构 如上…

【通信原理笔记】【二】随机信号分析——2.5 高斯随机过程

文章目录 前言一、高斯分布二、高斯过程三、高斯白噪声四、窄带高斯白噪声的复包络总结 前言 这篇我们来学习通信原理中非常重要的高斯&#xff08;正态&#xff09;随机过程&#xff0c;在之后的内容中会反复使用这个模型 一、高斯分布 首先回顾一下概率论中学过的高斯分布的…

达源电机超高速数码马达震撼来袭

新质生产力是什么? 12万转高速电吹风机马达引领行业技术革新 随着科技的不断进步&#xff0c;电吹风机行业正迎来一场深刻新质生产力技术革新。在这场革新中&#xff0c;达源电机以其独特绕线技术与自适应平衡磁场的马达技术&#xff0c;成功打破了国外高速马达电机悬臂梁专利…

uniapp——第3篇:自定义组件、组件间传数据

前提&#xff0c;建议先学会前端几大基础&#xff1a;HTML、CSS、JS、Ajax&#xff0c;还有一定要会Vue!&#xff08;Vue2\Vue3&#xff09;都要会&#xff01;&#xff01;&#xff01;不然不好懂 一、组件是啥玩意&#xff1f; 我之前讲vue2的文章讲过 Vue全家桶:vue2vue3全…

位图与布隆过滤器

目录 一、位图 1、问题用位图来解决&#xff1a; 二、 布隆过滤器 1、将哈希与位图结合&#xff0c;即布隆过滤器 2.布隆过滤器的查找 3.布隆过滤器的删除 4.布隆过滤器优点 5、布隆过滤器缺陷 三、海量数据处理问题&#xff1a; 一、位图 问题1&#xff1a;给40亿个不…

netron:本地查看服务器端打开的onnx文件

我们开发一般都在服务器中开发&#xff0c;假如我们在服务器端导出了一个onnx文件&#xff0c;不将onnx文件传到本地&#xff0c;如何进行本地查看呢&#xff1f; netron --port 8082 --host 10.75.29.201 model_data/deeplab_0131.onnx--host : 指定服务器的ip, 注意不是本地…

2024/03/19(网络编程·day5)

一、思维导图 二、selec函数实现TCP并发服务器 #include<myhead.h>#define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.117.116" //服务器IP int main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET,SOC…

软件设计师:03 - 数据库系统

一、数据模型的分类 1.1、概念数据模型 1.2、结构数据模型 1.3 真题 二、三级模式 概念模式对应的是基本表&#xff0c;概念模式也称为模式 外模式对应的是视图&#xff0c;也称用户模式或者子模式 内模式对应的是数据库里面的存储文件&#xff0c;也称存储模式 真题 三、两级…

VO、RVO、ORCA(动态避障)算法

碰撞锥&#xff08;碰撞区域&#xff09; 上上图中假设B物体处于静止状态&#xff0c;A物体沿着向量v1和v2移动&#xff0c;刚好能和B擦肩而过&#xff0c;不会发生碰撞&#xff1b;若V1和V2的夹角再小一点的话就一定会发生碰撞。此时会产生碰撞区域&#xff1a; 红线画出来…