リモートセンシング映像は16ビットから8ビットにダウン
From: https://blog.csdn.net/shenshanxiaozhu/article/details/53224554
常用衛星映像は基本的に16ビット映像であり、一部の応用シーンでは16ビット映像を8ビット映像に下げる必要があり、データ量を減らすだけでなく、後期処理も容易である.一般的な下位法は、ヒストグラムによってパーセンテージカットされ、次いで、最も簡単な線形延伸、セグメント延伸、対数変換、指数変換などを含む.ここでは、一般的な画像の特徴と組み合わせて、パーセンテージカットと指数(べき乗0.7)変換を用いて、画像を16ビットから8ビットに下げる.
常用衛星映像は基本的に16ビット映像であり、一部の応用シーンでは16ビット映像を8ビット映像に下げる必要があり、データ量を減らすだけでなく、後期処理も容易である.一般的な下位法は、ヒストグラムによってパーセンテージカットされ、次いで、最も簡単な線形延伸、セグメント延伸、対数変換、指数変換などを含む.ここでは、一般的な画像の特徴と組み合わせて、パーセンテージカットと指数(べき乗0.7)変換を用いて、画像を16ビットから8ビットに下げる.
int imageprocessing::stretch_percent_16to8(const char *inFilename, const char *dstFilename)
{
GDALAllRegister();
//
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
int src_height = 0;
int src_width = 0;
GDALDataset *poIn = (GDALDataset *)GDALOpen(inFilename,GA_ReadOnly); //
//
src_width = poIn ->GetRasterXSize();
src_height = poIn ->GetRasterYSize();
//
int InBands = poIn ->GetRasterCount();
//
GDALDataType eDataType = poIn -> GetRasterBand(1) -> GetRasterDataType();
//
double adfInGeoTransform[6] = {0};
const char *pszWKT = NULL;
//
poIn ->GetGeoTransform(adfInGeoTransform);
pszWKT = poIn ->GetProjectionRef();
//
GDALDriver *poDriver = (GDALDriver *)GDALGetDriverByName("GTiff");
GDALDataset *poOutputDS = poDriver -> Create(dstFilename,src_width,src_height,InBands,GDT_Byte,NULL);
//
poOutputDS -> SetGeoTransform(adfInGeoTransform);
poOutputDS -> SetProjection(pszWKT);
//
cout<GetRasterBand( iBand + 1) -> RasterIO( GF_Read, 0, 0, src_width, src_height , srcData + 0 * src_width * src_height,src_width,src_height, GDT_UInt16, 0, 0 );
//}
//
for (int src_row = 0; src_row < src_height; src_row ++)
{
for (int src_col = 0; src_col < src_width; src_col++)
{
uint16_t src_temVal = *(srcData + src_row * src_width + src_col);
if (src_temVal > src_max)
src_max = src_temVal;
if(src_temVal < src_min )
src_min = src_temVal;
}
}
double *numb_pix = (double *)malloc(sizeof(double)*(src_max+1)); // ,
memset(numb_pix,0,sizeof(double) * (src_max+1));
// ------- ------------ //
for (int src_row = 0; src_row < src_height; src_row ++)
{
for (int src_col = 0; src_col < src_width; src_col++)
{
uint16_t src_temVal = *(srcData + src_row * src_width + src_col);
*(numb_pix + src_temVal) += 1;
}
}
double *frequency_val = (double *)malloc(sizeof(double)*(src_max+1)); //
memset(frequency_val,0.0,sizeof(double)*(src_max+1));
for (int val_i = 0; val_i <= src_max; val_i++)
{
*(frequency_val + val_i) = *(numb_pix + val_i) / double(src_width * src_height);
}
double *accumlt_frequency_val = (double*)malloc(sizeof(double)*(src_max+1)); //
memset(accumlt_frequency_val, 0.0,sizeof(double)*(src_max+1));
for (int val_i = 0; val_i <= src_max; val_i ++)
{
for (int val_j = 0; val_j < val_i; val_j ++ )
{
*(accumlt_frequency_val + val_i) += *(frequency_val + val_j);
}
}
//
int minVal = 0, maxVal = 0;
for (int val_i = 1; val_i < src_max; val_i++)
{
double acc_fre_temVal0 = *(frequency_val + 0);
double acc_fre_temVal = *(accumlt_frequency_val + val_i);
if((acc_fre_temVal - acc_fre_temVal0) > 0.0015 )
{ minVal = val_i;
break; }
}
for (int val_i = src_max-1; val_i > 0; val_i--)
{
double acc_fre_temVal0 = *(accumlt_frequency_val + src_max);
double acc_fre_temVal = *(accumlt_frequency_val + val_i);
if(acc_fre_temVal < (acc_fre_temVal0 - 0.00012) )
{ maxVal = val_i;
break; }
}
for (int src_row = 0; src_row < src_height; src_row ++)
{
uint8_t *dstData = (uint8_t*)malloc(sizeof(uint8_t)*src_width);
memset(dstData, 0, sizeof(uint8_t)*src_width);
for (int src_col = 0; src_col < src_width; src_col++)
{
uint16_t src_temVal = *(srcData + src_row * src_width + src_col);
double stre_temVal = (src_temVal - minVal) / double(maxVal - minVal) ;
if(src_temVal < minVal)
{
*(dstData + src_col) = (src_temVal) *(20.0/double(minVal)) ;
}
else if(src_temVal > maxVal)
{ stre_temVal = (src_temVal - src_min) / double(src_max - src_min);
*(dstData + src_col) = 254; }
else
*(dstData + src_col) = pow(stre_temVal,0.7) * 250;
}
poOutputDS->GetRasterBand(iBand + 1)->RasterIO(GF_Write, 0,src_row,src_width,1,dstData,src_width,1,GDT_Byte,0,0);
free(dstData);
}
free(numb_pix);
free(frequency_val);
free(accumlt_frequency_val);
free(srcData);
}
GDALClose(poIn);
GDALClose(poOutputDS);
return 0;
}