使用GDAL将12bit量化图像转为16bit或者8bit
2012-02-23 12:56
791 查看
很多遥感卫星数据使用的量化级别都要比8bit高,比如常用的WorldView用的是12bit的量化,对于一些图像处理软件,是不能直接处理12bit量化的图像,所以需要将12bit的数据转为16bit数据或者8bit数据来进行处理。
下面写了一个简单的函数来进行处理,具体原理很简单,就是使用GDAL将12bit的数据读进来,然后再使用线性拉伸为8bit存出去,或者直接保存为16bit数据。注意12bit的数据在GDAL中读取的时候会显示为16bit数据,就好比2bit的数据在GDAL中是8bit一样,因为在C或者C++中很难找到一个类型来表示2bit或者12bit的东西,最小的char是8bit,short是16bit。代码如下,首先是头文件:
对于上面的实现做一个简单的说明,12bit的数据读进来,对于16bit的直接写到结果图像里面,没有拉伸到16bit的范围,这样就是完全保留了原始数据的所有图像信息,对于保存为8bit的数据,肯定会造成部分信息的丢失,使用最简单的线性方程进行拉伸,将0~4095的范围拉伸到0~255的范围。
下面写了一个简单的函数来进行处理,具体原理很简单,就是使用GDAL将12bit的数据读进来,然后再使用线性拉伸为8bit存出去,或者直接保存为16bit数据。注意12bit的数据在GDAL中读取的时候会显示为16bit数据,就好比2bit的数据在GDAL中是8bit一样,因为在C或者C++中很难找到一个类型来表示2bit或者12bit的东西,最小的char是8bit,short是16bit。代码如下,首先是头文件:
/*************************************************************************** * * Time: 2012-02-23 * Project: 遥感平台 * Purpose: 将12bit数据转换为8bit或者16bit * Author: 李民录 * Copyright (c) 2012, liminlu0314@gmail.com * Describe:将12bit数据转换为8bit或者16bit * ****************************************************************************/ #ifndef DATARESCALE_H #define DATARESCALE_H /*! 8U */ typedef unsigned char DT_8U; /*! 16U */ typedef unsigned short DT_16U; /** * @brief 释放数组 */ #define RELEASE(x) if(x!=NULL) {delete []x; x = NULL;} /** * @brief 图像转换,将图像存为16bit,前提确保输入的数据是12bit的 * @param pszSrcFile 输入文件路径 * @param pszDstFile 输出文件路径 * @param bTo8 是否转为8位,false为专为16bit数据,true表示转为8bit数据 * @param pszFormat 输出文件格式,详细参考GDAL支持数据类型 * @return 返回值,表示计算过程中出现的各种错误信息 */ int ImageDataRescale216(const char* pszSrcFile, const char* pszDstFile, bool bTo8 = true, const char* pszFormat = "GTiff"); #endif /* DATARESCALE_H */下面是函数实现代码:
/*************************************************************************** * * Time: 2012-02-23 * Project: 遥感平台 * Purpose: 将12bit数据转换为8bit或者16bit * Author: 李民录 * Copyright (c) 2012, liminlu0314@gmail.com * Describe:将12bit数据转换为8bit或者16bit * ****************************************************************************/ #include "DataRescale.h" #include "gdal_priv.h" /** * @brief 图像转换,将图像存为16bit,前提确保输入的数据是12bit的 * @param pszSrcFile 输入文件路径 * @param pszDstFile 输出文件路径 * @param bTo8 是否转为8位,false为专为16bit数据,true表示转为8bit数据 * @param pszFormat 输出文件格式,详细参考GDAL支持数据类型 * @return 返回值,表示计算过程中出现的各种错误信息 */ int ImageDataRescale(const char* pszSrcFile, const char* pszDstFile, bool bTo8 = true, const char* pszFormat = "GTiff") { //判断输入路径是否为空 if(pszSrcFile == NULL || pszDstFile == NULL) return -1; GDALAllRegister(); GDALDataset *poSrcDS = (GDALDataset *) GDALOpen( pszSrcFile, GA_ReadOnly ); if( poSrcDS == NULL ) { //图像打开失败 return -2; } GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); if( poDriver == NULL ) { //不能创建制定类型的文件,请检查该文件类型GDAL是否支持创建 GDALClose( (GDALDatasetH) poSrcDS ); return -3; } //获取图像宽高和波段数 int iXSize = poSrcDS->GetRasterXSize(); int iYSize = poSrcDS->GetRasterYSize(); int iBandCount = poSrcDS->GetRasterCount(); //确定输出图像的位数 GDALDataType eDT = GDT_UInt16; if(bTo8) eDT = GDT_Byte; else eDT = GDT_UInt16; //创建16bit的数据 GDALDataset *poDstDS = poDriver->Create(pszDstFile, iXSize, iYSize, iBandCount, eDT, NULL); double dGeoTrans[6] = {0}; //设置仿射变换参数 poSrcDS->GetGeoTransform(dGeoTrans); poDstDS->SetGeoTransform(dGeoTrans); //设置图像投影信息 poDstDS->SetProjection(poSrcDS->GetProjectionRef()); //用于保存读取的12bit数据 DT_16U *pSrcData = new DT_16U[iXSize]; if(bTo8) //转换为8bit { //定义结果数据存储空间 DT_8U *pDstData = new DT_8U[iXSize]; //循环波段 for(int iBand=1; iBand<=iBandCount; iBand++) { GDALRasterBand *pSrcBand = poSrcDS->GetRasterBand(iBand); GDALRasterBand *pDstBand = poDstDS->GetRasterBand(iBand); for(int i=0; i<iYSize; i++) //循环图像高 { //将数据读出来 pSrcBand->RasterIO(GF_Read, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0); //循环,将12bit数据专为8bit数据,使用线性拉伸方式 for(int j=0; j<iXSize; j++) { double dTemp = pSrcData[j] * 255.0 / 4095.0; if(dTemp > 255.0) pDstData[j] = 255; else pDstData[j] = (DT_8U)dTemp; } pDstBand->RasterIO(GF_Write, 0, i, iXSize, 1, pDstData, iXSize, 1, GDT_Byte, 0, 0); } } RELEASE(pDstData); //释放内存 } else //转换为16bit数据 { //循环波段 for(int iBand=1; iBand<=iBandCount; iBand++) { GDALRasterBand *pSrcBand = poSrcDS->GetRasterBand(iBand); GDALRasterBand *pDstBand = poDstDS->GetRasterBand(iBand); for(int i=0; i<iYSize; i++) //循环图像高 { //将数据读出来,然后写入结果数据 pSrcBand->RasterIO(GF_Read, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0); pDstBand->RasterIO(GF_Write, 0, i, iXSize, 1, pSrcData, iXSize, 1, GDT_UInt16, 0, 0); } } } RELEASE(pSrcData); //关闭原始图像和结果图像 GDALClose( (GDALDatasetH) poDstDS ); GDALClose( (GDALDatasetH) poSrcDS ); return 0; }
对于上面的实现做一个简单的说明,12bit的数据读进来,对于16bit的直接写到结果图像里面,没有拉伸到16bit的范围,这样就是完全保留了原始数据的所有图像信息,对于保存为8bit的数据,肯定会造成部分信息的丢失,使用最简单的线性方程进行拉伸,将0~4095的范围拉伸到0~255的范围。
相关文章推荐
- 使用GDAL将12bit量化图像转为16bit或者8bit
- 使用GDAL将下载的Google卫星图像转为带坐标的tif
- 使用GDAL将下载的Google卫星图像转为带坐标的tif
- 使用webcam 直接从内存获取图像 非读取ClipBoard或者File.
- 16bit灰度图像映射到8bit显示
- CImage类的介绍与使用 【图像打开,另存为,转为灰度图像(利用cimage方法实现)】
- 使用GDAL获取HDF等数据集中的图像
- 使用Python将时间或者时间间隔转为ISO 8601格式
- CImage类的介绍与使用 【图像打开,另存为,转为灰度图像(利用cimage方法实现)】
- Android使用Palette把drawable转为bitmap图像大小改变的问题
- 使用GDAL获取HDF等数据集中的图像
- 使用TensorFlow进行常用的图像处理-图像转为矩阵以及图像大小调整
- 16bit灰度图像映射到8bit显示
- OpenGL 使用 PBO 高速复制屏幕图像到内存或者纹理中
- 12bit灰度图像映射到8bit显示及python 实现
- 使用GDAL构造OpenCV的图像格式
- java中使用XStream实现将对象转为xml格式字符串或者将xml格式的字符串转换为对象==
- QT中使用GDAL多线程读取遥感图像到QImage
- 使用GDAL构造OpenCV的图像格式
- 如何使用GDAL进行图像镶嵌