【Python&RS】基于GDAL的遥感影像压缩

36587 📅 2025-08-28 19:34:34 👤 admin 👁️ 7916 ❤️ 778
【Python&RS】基于GDAL的遥感影像压缩

最近在处理一些高空间分辨率的卫星数据,数据量非常大。一个图幅都几十个G,ENVI表示压力太大了根本跑不动。所以研究了一下影像压缩的方式,在ArcGIS导出的压缩方式有很多限制,而且压缩并不是很明显。

所以我尝试使用GDAL库对影像进行压缩,速度还可以,至少不会向ArcGIS一样未响应。压缩之后效果跟ArcGIS差不多,但是也达不到十几个G,压缩成几百兆的效果。毕竟遥感影像最重要的就是像素值,别为了压缩牺牲了质量,这就得不偿失了。

一、安装三方库

import os

from osgeo import gdal

二、压缩函数

这里使用到GDAL的CreateCopy函数,在这里面可以设置压缩的参数。网上有很多人说LZW的压缩效果比PACKBITS好,但我在实测中发现PACKBITS的效果更好一点,可能因影像而已吧。不过庆幸的是两者都是无损压缩,我对比了压缩前后的像素值,均为一致的。

def Image_Compress(path_image, path_out_image):

"""

:param path_image: 输入需要压缩的影像路径

:param path_out_image: 输出压缩后的影像路径

:return: None

"""

ds = gdal.Open(path_image)

# 打开影像数据

driver = gdal.GetDriverByName('GTiff')

# 创建输出的数据驱动

driver.CreateCopy(path_out_image, ds, strict=1, callback=Show_Progress,

options=["TILED=YES", "COMPRESS=PACKBITS", "BIGTIFF=YES"])

# 设置压缩参数

"""

PACKBITS:连续字节压缩,快速无损压缩

LZW:所有信息全部保留(可逆),以某一数值代替字符串,快速无损压缩

"""

del ds

三、回调函数(显示进度)

这个可以没有,将第压缩函数中的callback参数删除即可。作用就是用来显示压缩进度的。

def Show_Progress(percent, msg, tag):

"""

:param percent: 进度,0~1

:param msg:

:param tag:

:return:

"""

if 0 <= percent * 100 <= 1:

print("进度:" + "%.2f" % (0 * 100) + "%")

if 25 <= percent*100 <= 26:

print("进度:" + "%.2f" % (percent*100) + "%")

if 50 <= percent*100 <= 51:

print("进度:" + "%.2f" % (percent*100) + "%")

if 75 <= percent*100 <= 76:

print("进度:" + "%.2f" % (percent*100) + "%")

if 99 <= percent * 100 <= 100:

print("进度:" + "%.2f" % (1 * 100) + "%")

四、压缩效果展示

这里用到了os的getsize函数,用来直观的显示压缩前后的空间占用率,当然也可以不要。纯属为了水一水字数(手动滑稽)。

def Get_Size(path_file):

"""

:param path_file: 需要压缩影像的路径

:return: 返回占用多少M

"""

size = os.path.getsize(path_file)

size = size / float(1024 * 1024)

return round(size, 2)

五、完整代码

# -*- coding: utf-8 -*-

"""

@Time : 2023/6/20 14:20

@Auth : RS迷途小书童

@File :Image Compression.py

@IDE :PyCharm

@Purpose :遥感影像压缩

"""

import os

from osgeo import gdal

def Show_Progress(percent, msg, tag):

"""

:param percent: 进度,0~1

:param msg:

:param tag:

:return:

"""

if 0 <= percent * 100 <= 1:

print("进度:" + "%.2f" % (0 * 100) + "%")

if 25 <= percent*100 <= 26:

print("进度:" + "%.2f" % (percent*100) + "%")

if 50 <= percent*100 <= 51:

print("进度:" + "%.2f" % (percent*100) + "%")

if 75 <= percent*100 <= 76:

print("进度:" + "%.2f" % (percent*100) + "%")

if 99 <= percent * 100 <= 100:

print("进度:" + "%.2f" % (1 * 100) + "%")

def Image_Compress(path_image, path_out_image):

"""

:param path_image: 输入需要压缩的影像路径

:param path_out_image: 输出压缩后的影像路径

:return: None

"""

ds = gdal.Open(path_image)

# 打开影像数据

driver = gdal.GetDriverByName('GTiff')

# 创建输出的数据驱动

driver.CreateCopy(path_out_image, ds, strict=1, callback=Show_Progress,

options=["TILED=YES", "COMPRESS=PACKBITS", "BIGTIFF=YES"])

# 设置压缩参数

"""

PACKBITS:连续字节压缩,快速无损压缩

LZW:所有信息全部保留(可逆),以某一数值代替字符串,快速无损压缩

"""

del ds

def Get_Size(path_file):

"""

:param path_file: 需要压缩影像的路径

:return: 返回占用多少M

"""

size = os.path.getsize(path_file)

size = size / float(1024 * 1024)

return round(size, 2)

if __name__ == "__main__":

path_input = "B:\sharpening1"

path_output = "B:\sharpening1.tif"

print("开始压缩......")

Image_Compress(path_input, path_output)

print("压缩已完成......")

print("压缩前:%sMB" % Get_Size(path_input))

print("压缩后:%sMB" % Get_Size(path_output))

遥感影像的压缩其实还是非常重要的,当然重中之重肯定还是无损!压缩。同样,对于高光谱数据的降维其实也是为了提高工作效率,减少数据的冗余。所以多学多看吧,任重道远!

如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!

相关养生推荐

掉入黑洞会怎么样?
365买球怎么玩

掉入黑洞会怎么样?

📅 07-02 👁️ 4617
1、苹果手机怎么更新王者
365买球怎么玩

1、苹果手机怎么更新王者

📅 06-27 👁️ 2145
梅西辱骂裁判遭禁赛 阿根廷也要忧心进不去世界杯
365买球怎么玩

梅西辱骂裁判遭禁赛 阿根廷也要忧心进不去世界杯

📅 08-04 👁️ 2224
择天记什么时候播出
36587

择天记什么时候播出

📅 07-06 👁️ 7879