当前位置: 首页 > news >正文

GDAL python教程基础篇(12)GDAL和 Pillow 的互操作

GDAL和 Pillow

GDAL和PIL处理和操作的对象都是栅格图像。 但它们又不一样。 GDAL主要重点放在地理或遥感数据的读写和数据建模以及地理定位和转换, 但是PIL的重点是放在图像本身处理上的。

至于在底层数据处理上,两者都可以用 numpy 转化的二进制作为数据处理。 所以,理论上是可以互相共享和交换数据的。实际上也确实可以。

GDAL的核心在波段(band), 一切操作的基础和核心都在波段。 波段可以单独拿出来操作,至于波段在数据集中的顺序无关紧要。 因为遥感图像大多比RGB图像的波段要多,而每个波段单独都是一个完整的整体, 每个波段单独拿出来都是一个数据集。而 Pillow 的核心在数据集(DataSet)这里的概念是对应GDAL中的数据集的概念。 当然,在 Pillow 本身中没有这种说法,也就是不把波段单独操作, 操作大部分需要RGB一体化地进行。

两部分的操作的主要衔接部分就是创建、读取与写入。 读取数据后怎么处理是两个库各自的事情。 所以这里主要内容就是介绍两个库各自的创建,读取和写入的操作,以及两个库的过渡。

1. 使用GDAL读取数据

比较两个库的读取,GDAL读取一个图像中的数据

>>> from osgeo import gdal
>>> dataset = gdal.Open("/gdata/geotiff_file.tif")
>>> data_arr = dataset.ReadAsArray(30,70,5,5)
>>> type(data_arr)
numpy.ndarray
>>> data_arr
array([[[147, 141, 151, 146, 145],[148, 149, 151, 143, 139],[163, 164, 162, 152, 149],[167, 169, 164, 160, 159],[168, 172, 162, 162, 164]],[[  7,   4,  17,  12,  11],[  7,  10,  14,   6,   2],[ 10,  11,  11,   3,   0],[  8,  10,   8,   4,   4],[ 12,  16,   6,   6,   9]],[[ 18,  12,  24,  19,  18],[ 16,  17,  21,  13,   9],[ 15,  16,  16,   7,   6],[ 13,  14,  11,   8,  10],[ 16,  20,  10,  10,  15]]], dtype=uint8)
>>> data_bin = dataset.ReadRaster(30,70,5,5)
>>> data_bin
b'x93x8dx97x92x91x94x95x97x8fx8bxa3xa4xa2x98x95xa7xa9xa4xa0x9fxa8xacxa2xa2xa4x07x04x11x0cx0bx07nx0ex06x02nx0bx0bx03x00x08nx08x04x04x0cx10x06x06tx12x0cx18x13x12x10x11x15rtx0fx10x10x07x06rx0ex0bx08nx10x14nnx0f'

打开了数据集,就有两种方法来获取数据。虽然读出的一个是二进制,一个是数组,Numpy数组用tostirng转换出来的二进制和用ReadRaster读出的相同。

>>> data_arr.tostring()
<ipython-input-5-e83da5e06f5b>:1: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.data_arr.tostring()
b'x93x8dx97x92x91x94x95x97x8fx8bxa3xa4xa2x98x95xa7xa9xa4xa0x9fxa8xacxa2xa2xa4x07x04x11x0cx0bx07nx0ex06x02nx0bx0bx03x00x08nx08x04x04x0cx10x06x06tx12x0cx18x13x12x10x11x15rtx0fx10x10x07x06rx0ex0bx08nx10x14nnx0f'

从波段中获取数据和从数据集中获取数据的方法十分相似。

2. 使用Pillow读取数据

注意,使用Pillow读取时,要注意其类型。

>>> from PIL import Image
>>> im = Image.open("/gdata/geotiff_file.tif")
>>> region = im.crop((30,70,35,75))
>>> region.tobytes()
b'x93x07x12x8dx04x0cx97x11x18x92x0cx13x91x0bx12x94x07x10x95nx11x97x0ex15x8fx06rx8bx02txa3nx0fxa4x0bx10xa2x0bx10x98x03x07x95x00x06xa7x08rxa9nx0exa4x08x0bxa0x04x08x9fx04nxa8x0cx10xacx10x14xa2x06nxa2x06nxa4tx0f'

im可以类比成gdal的dataset,im也可以从DataSet中提取某个范围的数据。
可以看出,虽然读取的都是同样位置的数据,但是输出的结果不一样。

3. Pillow与GDAL读取数据的转换

这里注意,GDAL与Pillow的空间模型并不一致。 在Pillow的下,截取区域矩形的定义和GDAL不同,GDAL是顶点X、顶点Y、宽、高; Pillow是顶点X、顶点Y、终点X,终点Y。 这就是GDAL和Pillow的区别。转换一下:

>>> import numpy as np
>>> data = dataset.ReadAsArray(30,70,5,5)
>>> datas = [i for i in data]
>>> from numpy import reshape
>>> datas = [reshape(i,(-1,1)) for i in data]
>>> datas = np.concatenate(datas,1)
>>> datas.tostring()
<ipython-input-8-b652c983ce99>:7: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.datas.tostring()
b'x93x07x12x8dx04x0cx97x11x18x92x0cx13x91x0bx12x94x07x10x95nx11x97x0ex15x8fx06rx8bx02txa3nx0fxa4x0bx10xa2x0bx10x98x03x07x95x00x06xa7x08rxa9nx0exa4x08x0bxa0x04x08x9fx04nxa8x0cx10xacx10x14xa2x06nxa2x06nxa4tx0f'

可以看到现在结果一致了。这里就表现了两个库的设计概念模型的不同。 GDAL把图像看成是由不同传感器获取的不同频率的电磁波构成的影像文件,读取的数据是默认的以band组织的; Pillow则把图像看成是由单个像素构成的,每个像素是记录的由RGB三色构成的像素颜色的数据。

4. 从波段来看

如果是单个波段,就不存在RGB存储的问题了。使用下面的方式打开,可以看出读取数据时,两个库读取的结果是一样的。

>>> r,g,b = region.split()
>>> r.tobytes()
b'x93x8dx97x92x91x94x95x97x8fx8bxa3xa4xa2x98x95xa7xa9xa4xa0x9fxa8xacxa2xa2xa4'
>>> band = dataset.GetRasterBand(1)
>>> band.ReadRaster(30,70,5,5)
b'x93x8dx97x92x91x94x95x97x8fx8bxa3xa4xa2x98x95xa7xa9xa4xa0x9fxa8xacxa2xa2xa4'

相关文章:

GDAL python教程基础篇(12)GDAL和 Pillow 的互操作

GDAL和 Pillow GDAL和PIL处理和操作的对象都是栅格图像。 但它们又不一样。 GDAL主要重点放在地理或遥感数据的读写和数据建模以及地理定位和转换&#xff0c; 但是PIL的重点是放在图像本身处理上的。 至于在底层数据处理上&#xff0c;两者都可以用 numpy 转化的二进制作为数…...

快速学习java路线建议

还有2 &#xff0c;3个月就要毕业了&#xff0c;啥都不会的你是不是很慌呢&#xff0c;是不是想知道怎么样快速学习java呢。嘿嘿&#xff01;它来了。 首先是java的学习 &#xff0c;推荐 ​​​​​​【尚硅谷】7天搞定Java基础&#xff0c;Java零…...

【MySQL】深入浅出主从复制数据同步原理

【MySQL】深入浅出主从复制数据同步原理 参考资料&#xff1a; 全解MySQL之主从篇&#xff1a;死磕主从复制中数据同步原理与优化 MySQL 日志&#xff1a;undo log、redo log、binlog 有什么用&#xff1f; 文章目录【MySQL】深入浅出主从复制数据同步原理一、主从复制架构概述…...

Redis持久化和高可用

Redis持久化和高可用一、Redis持久化1、Redis持久化的功能2、Redis提供两种方式进行持久化二、RDB持久化1、触发条件2、bgsave执行流程3、启动时加载三、Redis高可用1、什么是高可用2、Redis高可用技术四、AOF持久化&#xff08;支持秒级写入&#xff09;1、开启AOF2、执行流程…...

【数据结构】第六站:栈和队列

目录 一、栈 1.栈的概念和结构 2.栈的实现方案 3.栈的具体实现 4.栈的完整代码 5.有效的括号 二、队列 1.队列的概念及结构 2.队列的实现方案 3.队列的实现 4.队列实现的完整代码 一、栈 1.栈的概念和结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定…...

python matplotlib 绘制训练曲线 综合示例——平滑处理、图题设置、图例设置、字体大小、线条样式、颜色设置

文章目录1 导出曲线数据2 python简单的 绘制曲线3 Savitzky-Golay 滤波器--平滑曲线4 对y轴数值缩放处理5 设置图题、图例、字体、网格、保存曲线图6 补充6.1 python 曲线平滑处理——方法总结-详解6.2 Tensorboard可视化训练曲线导出数据用Python绘制6.3 PyTorch可视化工具-Te…...

vue-element-plus-admin整合后端实战——实现系统登录、缓存用户数据、实现动态路由

目标 整合vue-element-plus-admin前端框架&#xff0c;作为开发平台的前端。 准备工作 前端选用vue-element-plus-admin&#xff0c;地址 https://gitee.com/kailong110120130/vue-element-plus-admin。 首先clone项目&#xff0c;然后整合到开发平台中去。这是一个独立的前…...

Shader Graph2-PBR介绍之表面属性(图解)

PBR的实现由光线和表面属性决定&#xff0c;下面我们介绍一下表面属性。这个5个属性在ShaderGraph的根节点是经常的看到&#xff0c;左侧是Unity中的&#xff0c;右侧是UE中的。 在没有Metallic金属的情况下&#xff0c;基础颜色值就决定了颜色的漫反射值&#xff0c;也就是说基…...

Java多线程编程,Thread类的基本用法讲解

文章目录如何创建一个线程start 与 run线程休眠线程中断线程等待获取线程实例如何创建一个线程 之前我们介绍了什么是进程与线程&#xff0c;那么我们如何使用代码去创建一个线程呢&#xff1f;线程操作是操作系统中的概念&#xff0c;操作系统内核实现了线程这样的机制&#…...

TIA博途Wincc_多路复用变量的使用方法示例(实现多台相同设备参数的画面精简)

TIA博途Wincc_多路复用变量的使用方法示例(实现多台相同设备参数的画面精简) 使用多路复用变量的好处: 当项目中存在多个相同的设备(例如:变频器、电机等),对这些设备在HMI上进行监控或修改参数时,不再需要逐个建立画面或IO域等,只需通过单个画面或IO域组合即可实现对…...

关于console你不知道的那些事

看到标题&#xff0c;大家会不会想&#xff0c;我都在前端岗位叱咤风云这么多年了, console 这个玩意用你讲 但是, 今天我将带你看到不一样的 console, 可以带来更多的帮助 了解 console 什么是 console ? console 其实是 JavaScript 内的一个原生对象。内部存储的方法大部…...

Java设计模式-责任链模式

1 概述 在现实生活中&#xff0c;常常会出现这样的事例&#xff1a;一个请求有多个对象可以处理&#xff0c;但每个对象的处理条件或权限不同。例如&#xff0c;公司员工请假&#xff0c;可批假的领导有部门负责人、副总经理、总经理等&#xff0c;但每个领导能批准的天数不同…...

顺序表设计循环队列

使用顺序表来设计队列的最大优势是顺序表有可以定位元素的下标。 并且可以以Mod来使数组下标循环 #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> typedef int CQDataType; typedef struct { int* array; in…...

UEFI 基础教程 (十四) - 设置默认启动项为UEFI Shell

一 编写源代码 OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c UINTN BootOptionPriority ( CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { DEBUG ((EFI_D_ERROR," [CSDN] BootOptionPriority %S .\n", BootOption->Description)); if (StrCmp (…...

python编程:判断一个数是否是超级素数

请定义一个函数&#xff0c;实现判断一个数是否是超级素数,并输出判断的结果。 一、编程题目 我们都知道&#xff0c;素数是除了1之外只能被自身整数的数&#xff0c;1除外。如果一个素数&#xff0c;去除一位、两位或多位后依然是素数&#xff0c;则我们称该素数为超级素数。…...

雷迪RD8200管线探测仪参数/管线仪使用方法/管线仪说明书

预防损坏和工作效率是我们客户面临的最大挑战 全新的 RD8200可以解决这些问题。这是我们功能优秀的精密管线仪系列&#xff0c;设计时充分考虑了操作员的需要。 预防损坏的专业选择 速度、准确性和可靠的性能 易于设置和使用 阳光下可读的显示屏、高性能的音频系统和用于嘈杂…...

会话共享保存到redis

1. 安装redis服务 [rootdb01 ~]# yum -y install redis 2. 配置redis服务 修改配置文件可以让其他服务器远程连接 127.0.0.1:6379 # 默认只能本地连接 [rootdb01 ~]# vim /etc/redis.conf [rootdb01 ~]# grep 172.16.1.51 /etc/redis.conf bind 127.…...

python 曲线平滑处理——方法总结(Savitzky-Golay 滤波器、make_interp_spline插值法和convolve滑动平均滤波)

文章目录1 插值法对曲线平滑处理1.1 插值法的常见实现方法1.2 拟合和插值的区别1.3 代码实例2 Savitzky-Golay 滤波器实现曲线平滑2.1 问题描述2.2 Savitzky-Golay 滤波器--调用讲解2.3 Savitzky-Golay 曲线平滑处理 示例2.4 Savitzky-Golay原理剖析3 基于Numpy.convolve实现滑…...

小驰私房菜_10_camx Otp Dump

#小驰私房菜# #camx# #Otp Dump# 本篇文章分下面几点展开: 1、otp dump的目的? 2、如何打开otp dump开关? 3、otp guide手册如何查看? 4、如何初步确认dump 出来的数据是否正确? 一、otp dump的目的 关于otp的一些概念,这里就不做过多的介绍了,不了解的同学,可以先去…...

priority_queue(堆)干货归纳+用法示例

10.priority_queue一.priority_queue&#xff08;堆Heap&#xff09;简介1.堆的特点&#xff1a;2.使用场景&#xff1a;二.成员函数1.构造函数&#xff1a;priority_queue构造函数方式&#xff1a;2.push()函数&#xff1a;向priority_queue中插入一个元素&#xff1a;3.pop()…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

leetcode73-矩阵置零

leetcode 73 思路 记录 0 元素的位置&#xff1a;遍历整个矩阵&#xff0c;找出所有值为 0 的元素&#xff0c;并将它们的坐标记录在数组zeroPosition中置零操作&#xff1a;遍历记录的所有 0 元素位置&#xff0c;将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...

性能优化中,多面体模型基本原理

1&#xff09;多面体编译技术是一种基于多面体模型的程序分析和优化技术&#xff0c;它将程序 中的语句实例、访问关系、依赖关系和调度等信息映射到多维空间中的几何对 象&#xff0c;通过对这些几何对象进行几何操作和线性代数计算来进行程序的分析和优 化。 其中&#xff0…...

初级程序员入门指南

初级程序员入门指南 在数字化浪潮中&#xff0c;编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言&#xff0c;明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 &#xff08;一&#xff09;编程语言抉择 编…...