GDAL和Pillow互操作
GDAL
和PIL
很相像,它们处理和操作的对象都是栅格图像。
区别在于
GDAL
主要重点放在地理或遥感数据的读写和数据建模以及地理定位和转换;
PIL
的重点是放在图像本身处理上的。
在底层逻辑上,两个库都是对numpy
的数据进行处理,因此理论上可以相互共享和交换数据。
GDAL
的核心在波段band
, 一切操作的基础和核心都在波段。
波段可以单独拿出来操作,至于波段在数据集中的顺序无关紧要。
遥感图像大多比RGB图像的波段要多,而每个波段单独都是一个完整的整体, 每个波段单独拿出来都是一个数据集。
Pillow
的核心在数据集DataSet
,但是Pillow
本身没这个概念,我们可以用GDAL
的理念迁移过去方便理解。PIL
一般是直接对整个影像进行一体化操作。
两部分的操作的主要衔接部分就是创建、读取与写入。
读取数据后怎么处理是两个库各自的事情。
GDAL和PIL的数据读取
from osgeo import gdal
from osgeo.gdalconst import *
from PIL import Imag
# 两种方式读取GDAL
dataset = gdal.Open('temp/demo11_create.tif')
datas = dataset.ReadAsArray(65,65,25,25)
datas_2 = dataset.ReadRaster(65,65,25,25)
print(datas)
print('-----------------------------')
print(datas_2)
print('-----------------------------')
# PIL读取
dataset_pil = Image.open('temp/demo11_create.tif')
crop_dataset_pil = dataset_pil.crop((50, 50, 75, 75))
print(crop_dataset_pil.tobytes())
结果:分别是矩阵数组、bytearray
、二进制。
GDAL和PIL数据转换
GDAL
和PIL
的读取参数有点出入
GDAL
的四个参数是x顶点、y顶点、x方向长度、y方向长度;
PIL
的四个参数是左上角顶点xy坐标、右下角顶点xy坐标。
from osgeo import gdal
from osgeo.gdalconst import *
import numpy as np
from numpy import reshape
if __name__ == '__main__':
dataset = gdal.Open('temp/demo11_create.tif')
data = dataset.ReadAsArray(0, 0, 10, 10)
datas = [i for i in data]
print(datas)
print('-------------------------')
datas = [reshape(i, (-1, 1)) for i in data]
datas = np.concatenate(datas, 1)
datas.tobytes()
print(datas)
看不懂numpy
的几个函数,跳过。
只需要知道进行了转换。虽然没有引入PIL
。
对于单波段
单波段中可以直接观察有什么区别。
from PIL import Image
from osgeo import gdal
if __name__ == '__main__':
dataset = gdal.Open('temp/demo11_create.tif')
band1 = dataset.GetRasterBand(1)
data_band1 = band1.ReadRaster(0, 0, 10, 10)
print(data_band1)
img1 = Image.open('temp/demo11_create.tif')
R, G, B = img1.split()
data_band1 = R.crop((0, 0, 10, 10))
print(data_band1.tobytes())
# GDAL
bytearray(b'\x19<l\x8d_Y4(#*>[u\x8ceDZE-%Zj{w\x84eS%\x0c\x06Au\x83e\xc1\xb4a\x0c\x06\x0eRly`\xd2\xcej\x04\n\x12hu\xa0\x95\xb7\xa3Z\x1e\x14\x16l{|~}\x8aT1 djtQHk@1&(m\x84\x7fR@496#\x1c\x94\x99\x86{K7;*\x19\x13')
# PIL
b'\x19<l\x8d_Y4(#*>[u\x8ceDZE-%Zj{w\x84eS%\x0c\x06Au\x83e\xc1\xb4a\x0c\x06\x0eRly`\xd2\xcej\x04\n\x12hu\xa0\x95\xb7\xa3Z\x1e\x14\x16l{|~}\x8aT1 djtQHk@1&(m\x84\x7fR@496#\x1c\x94\x99\x86{K7;*\x19\x13'
可以看出虽然是bytearray
格式,但其中的结果都是二进制。
单波段不需要考虑像素叠合和排列的问题。
本章说明,GDAL
和PIL
是可以进行互操作的,无论是读取还是写入。