一、功能需求与描述
经过一系列处理后的遥感影像产品都是GeoTiff标准的tif影像,但利用OpenCV无法直接对其进行读取和操作。 因此需要将影像转换成OpenCV能识别的png、jpg等格式才能应用后续算法。
二、技术分析与思路
利用专业处理遥感影像数据的GDAL库来读取影像,利用Numpy的矩阵作为媒介,最后利用OpenCV输出影像。 需要注意的是,遥感影像一般量化级数是10bit。而要想利用OpenCV保存大于8bit的影像,必须设置保存格式为png。
三、功能实现
代码及工程详见GitHub。https://github.com/zhaoxuhui/ToolForImageBitConvert
四、使用及功能展示
在电脑中有一幅tif遥感影像,量化级数是10bit。直接是无法打开的。 通过本脚本,可以分别获取影像的各个波段以及对影像进行升降量化级数。
1.降为8bit量化
下图为8bit量化后的影像,由于有RGB三个通道,每个通道8bit,所以一共24bit。
2.升为16bit量化 下图为16bit量化后的影像,由于有RGB三个通道,每个通道16bit,所以一共48bit。
3.获取影像单个波段 下图是获取的影像第一个波段(蓝色波段)的灰度图。由于是16bit量化,且只有一个波段,所以图像位深度为16。
4.假彩色合成 下图是按照1,0,2的波段顺序输出的假彩色图像。影像默认的存储顺序是BGR,因此想获取真彩色图像,输出波段顺序应该是2,1,0。
五、注意
这里需要注意的是,在代码中指定的是“可视化”的量化级数,像素的真实值并不一定是对的。
在OpenCV中,保存图像只有两种量化级数可选,8-bit和16-bit,8bit用jpg保存,16bit用png保存。
那么如果有一张1bit量化的图像,那么理论上来说像素值只能为0或1。但由于OpenCV的保存策略,只能保存8bit。
因此会造成的问题是保存的图片看起来是完全黑色的。因为像素范围是[0,255],但实际像素只有0,1两种值。
因此为了从视觉上看起来像是1bit量化,就只能对图像进行灰度线性拉伸,将其灰度范围拉伸到8bit,变成0和255两种值。
这样从视觉上看起来就是符合我们的预期了,但实际像素的值却是错误的了。
在代码中提供了IsVisible
选项,默认为True
,表示按照视觉保存,也可以改成False
,这样像素值就是严格正确的,但是图像可能看起来不太对。
下面是一幅10bit量化的单波段全色遥感影像在不同灰度量化级数下的样子(视觉上),原图大小24513*23995,1.09G。
原图 1-bit量化,jpg,118MB 2-bit量化,jpg,139MB 3-bit量化,jpg,142MB 4-bit量化,jpg,155MB 5-bit量化,jpg,147MB 6-bit量化,jpg,135MB 7-bit量化,jpg,127MB 8-bit量化,jpg,125MB 9-bit量化,png,440MB 10-bit量化,png,513MB 11-bit量化,png,513MB 16-bit量化,png,513MB 可以看到,随着量化级数的增多,图片的过渡越来越“温和”,更加好看。 但由于上传图片压缩等问题,所以不太明显,如果放大看原图细节则会更有这种体会。 当然你可能会有疑问,为什么处理的10bit图和原图比不太一样呢。 原图之所以看起来比较好看是因为并不是真正的原图,而是已经经过灰度拉伸、直方图均衡化之后的缩略图。 而处理的这些图片并没有经过均衡化,是原始真实的像素值,所以看起来对比度不高,整体偏暗、偏灰。
不过也能发现,同样大小的图片,500多兆的png也是挺恐怖的,和100多兆的jpg相比不在一个层次上。 可见png也是保存了非常多的信息,几乎没有压缩。GTiff格式的影像也许除了储存的地理信息剩下的大小和这个差不了多少。
当然,由于原图只有10bit量化,因此提高量化等级并不会有新的信息出现,就没有意义了。 只能说通过向高、向低转换,也间接检验了程序的正确性,是否有问题。 但是降低量化等级还是很有意义的,可以起到图像压缩的效果。
本文作者原创,未经许可不得转载,谢谢配合