Many remote sensing satellite data must be quantified at a higher level than 8 bits. For example, worldview often uses 12 bits for quantification, and some image processing software cannot directly process 12 bits for quantified images, therefore, we need to convert 12-bit data into 16-bit data or 8-bit data for processing.
The following describes a simple function for processing. The specific principle is very simple. gdal is used to read 12-bit data and then linearly stretch the data into 8-Bit Memory, or save it as 16-bit data. Note that 12-bit data is displayed as 16-bit data when read in gdal, just like 8-bit data in gdal, in C or C ++, it is difficult to find a type that represents 2bit or 12bit. The smallest char is 8bit, and the short is 16bit. The Code is as follows:
/*************************************** ************************************* Time: 2012-02-23 * Project: remote sensing platform * purpose: converts 12bit data to 8bit or 16bit * Author: Li minlu * copyright (c) 2012, liminlu0314@gmail.com * describe: convert 12-bit data to 8-bit or 16-bit ******************************** **************************************** * ***/# ifndef datarescale_h # define datarescale_h /*! 8u */typedef unsigned chardt_8u ;/*! 16u */typedef unsigned into dt_16u;/*** @ brief release array */# define release (x) if (X! = NULL) {Delete [] X; X = NULL;}/*** @ brief image conversion, save the image as 16bit, make sure that the input data is 12-bit * @ Param pszsrcfile input file path * @ Param pszdstfile output file path * @ Param bto8 whether to convert to 8-bit, and false is designed for 16-bit data, true indicates converting to 8-Bit Data * @ Param pszformat output file format. For details, see gdal support data type * @ return value, various error messages during calculation */INT imagedatarescale216 (const char * pszsrcfile, const char * pszdstfile, bool bto8 = true, const char * pszformat = "gtiff "); # endif/* datarescale_h */
The following is the function implementation code:
/*************************************** ************************************* Time: 2012-02-23 * Project: remote sensing platform * purpose: converts 12bit data to 8bit or 16bit * Author: Li minlu * copyright (c) 2012, liminlu0314@gmail.com * describe: convert 12-bit data to 8-bit or 16-bit ******************************** **************************************** * ***/# include "datarescale. H "# include" gdal_priv.h "/*** @ brief image conversion, save the image as 16bit, make sure that the input data is 12-bit * @ Param pszsrcfile input file path * @ Param pszdstfile output file path * @ Param bto8 whether to convert to 8-bit, and false is designed for 16-bit data, true indicates converting to 8-Bit Data * @ Param pszformat output file format. For details, see gdal support data type * @ return value, various error messages during calculation */INT imagedatarescale (const char * pszsrcfile, const char * pszdstfile, bool bto8 = true, const char * pszformat = "gtiff ") {// determine whether the input path is null 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) {// you cannot create a file of the specified type. Check whether gdal supports creating gdalclose (gdaldataseth) posrcds); Return-3 ;} // obtain the image width and band count int ixsize = posrcds-> getrasterxsize (); int iysize = posrcds-> getrasterysize (); int ibandcount = posrcds-> getrastercount (); // determine the number of digits of the output image: gdaldatatype EDT = gdt_uint16; If (bto8) EDT = gdt_byte; elseedt = gdt_uint16; // create 16-Bit Data gdaldataset * podstds = podriver-> Create (pszdstfile, ixsize, iysize, ibandcount, EDT, null); double dgeotrans [6] = {0 }; // set the parameter posrcds-> getgeotransform (dgeotrans); podstds-> setgeotransform (dgeotrans ); // set the image projection information podstds-> setprojection (posrcds-> getprojectionref (); // It is used to save the read 12bit data dt_16u * psrcdata = new dt_16u [ixsize]; if (bto8) // convert to 8bit {// define the result data storage space dt_8u * pdstdata = new dt_8u [ixsize]; // cyclic band for (INT iband = 1; iband <= ibandcount; iband ++) {gdalrasterband * psrcband = posrcds-> getrasterband (iband); gdalrasterband * pdstband = podstds-> getrasterband (iband ); for (INT I = 0; I <iysize; I ++) // cyclic Image Height {// read data out psrcband-> rasterio (gf_read, 0, I, ixsize, 1, psrcdata, ixsize, 1, gdt_uint16, 0, 0); // cyclically, the 12-bit data is specially designed for 8-bit data, and linear stretching is used for (Int J = 0; j <ixsize; j ++) {double dtemp = psrcdata [J] * 255.0/4095.0; If (dtemp> 255.0) pdstdata [J] = 255; elsepdstdata [J] = (dt_8u) dtemp;} pdstband-> rasterio (gf_write, 0, I, ixsize, 1, pdstdata, ixsize, 1, gdt_byte, 0, 0) ;}} release (pdstdata); // release memory} else // convert to 16-Bit Data {// cyclic band for (INT iband = 1; iband <= ibandcount; iband ++) {gdalrasterband * psrcband = posrcds-> getrasterband (iband); gdalrasterband * pdstband = podstds-> getrasterband (iband); For (INT I = 0; I <iysize; I ++) // The cyclic Image Height {// read the data and write the result data 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); // close the original image and result image gdalclose (gdaldataseth) podstds); gdalclose (gdaldataseth) posrcds); Return 0 ;}
A simple description of the above implementation is provided. The 12-bit data is read in, and the 16-bit data is directly written into the result image, which is not stretched to the 16-bit range, in this way, all the image information of the original data is completely retained. For 8-bit data, part of the information will be lost, and the simplest linear equation is used for stretching ~ Stretch the range of 4095 to 0 ~ The value range is 255.