GDAL c++ 遥感影像16位转8位

3 篇文章 0 订阅
typedef unsigned __int16 uint16_t;
typedef unsigned unsigned char uint8_t;

int 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 << "16位影像降到8位影像处理..." << endl;

	for (int iBand = 0; iBand < InBands; iBand++)

	{

		cout << "正在处理第 " << iBand + 1 << " 波段" << endl;

		//读取影像

		uint16_t *srcData = (uint16_t *)malloc(sizeof(uint16_t) *src_width * src_height * 1);

		memset(srcData, 0, sizeof(uint16_t) * 1 * src_width * src_height);

		int src_max = 0, src_min = 65500;

		//读取多光谱影像到缓存

		poIn->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);



	}

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值