最近在处理一些高空间分辨率的卫星数据,数据量非常大。一个图幅都几十个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))
标签:return,RS,Python,压缩,param,影像,path,image,GDAL From: https://www.cnblogs.com/RSran/p/17510566.html遥感影像的压缩其实还是非常重要的,当然重中之重肯定还是无损!压缩。同样,对于高光谱数据的降维其实也是为了提高工作效率,减少数据的冗余。所以多学多看吧,任重道远!
如果大家在学习Python或者RS时有什么问题,可以随时留言交流!如果大家对批量处理有兴趣同样可以留言给博主,博主会分享相关代码以供学习!