0
点赞
收藏
分享

微信扫一扫

C++ Bayer图像格式,使用GDAL进行格式转换。

时光已翩然轻擦 2022-03-11 阅读 46
c++

Bayer图像说明

1、Bayer图像格式介绍

  bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发明的,Bryce Bayer所发明的拜耳阵列被广泛运用数字图像。
       在这里插入图片描述

  对于彩色图像,需要采集多种最基本的颜色,如rgb三种颜色,最简单的方法就是用滤镜的方法,红色的滤镜透过红色的波长,绿色的滤镜透过绿色的波长,蓝色的滤镜透过蓝色的波长。如果要采集rgb三个基本色,则需要三块滤镜,这样价格昂贵,且不好制造,因为三块滤镜都必须保证每一个像素点都对齐。当用bayer格式的时候,很好的解决了这个问题。bayer 格式图片在一块滤镜上设置的不同的颜色,通过分析人眼对颜色的感知发现,人眼对绿色比较敏感,所以一般bayer格式的图片绿色格式的像素是是r和g像素的和。

  另外,Bayer格式是相机内部的原始图片, 一般后缀名为.raw。很多软件都可以查看, 比如PS。我们相机拍照下来存储在存储卡上的.jpeg或其它格式的图片, 都是从.raw格式转化过来的。如下图,为bayer色彩滤波阵列,由一半的G,1/4的R,1/4的B组成。
           颜色排布示例

2、Bayer图像传感原理

  图像传感器的结构如下所示,每一个感光像素之间都有金属隔离层,光纤通过显微镜头,在色彩滤波器过滤之后,投射到相应的漏洞式硅的感光元件上。
    
在这里插入图片描述

  当Image Sensor往外逐行输出数据时,像素的序列为GRGRGR…/BGBGBG…(顺序RGB)。这样阵列的Sensor设计,使得RGB传感器减少到了全色传感器的1/3,如下所示。
                在这里插入图片描述

3、bayer格式插值红蓝算法实现

  每一个像素仅仅包括了光谱的一部分,必须通过插值来实现每个像素的RGB值。为了从Bayer格式得到每个像素的RGB格式,我们需要通过插值填补缺失的2个色彩。插值的方法有很多(包括领域、线性、3*3等),速度与质量权衡,最好的线性插值补偿算法。其中算法如下:

  R和B通过线性领域插值,但这有四种不同的分布,如下图所示:
在这里插入图片描述
    A             B
在这里插入图片描述
    C             D
在(a)与(b)中,R和B分别取邻域的平均值。

在(c)与(d)中,取领域的4个B或R的均值作为中间像素的B值。

4、bayer格式插值绿算法实现

在这里插入图片描述
      E              F
由于人眼对绿光反应最敏感,对紫光和红光则反应较弱,因此为了达到更好的画质,需要对G特殊照顾。在上述(c)与(d)中,扩展开来就是上图的(e)与(f)中间像素G的取值,者也有一定的算法要求,不同的算法效果上会有差异。经过相关的研究,
(e)中间像素G值的算法如下:
      在这里插入图片描述

(f)中间像素G值的算法如下:
      在这里插入图片描述

  CMOS摄像头这部分转换是在内部用ADC或者ISP完成的,生产商为了降低成本必然会使得图像失真。当然用外部处理器来实现转换,如果处理器的速度足够NB,能够胜任像素的操作,用上面的算法来进行转换,皆大欢喜。不过上述算法将直接成倍提高了算法的复杂度,速度上将会有所限制。因此为了速度的提成,可以直接通过来4领域G取均值来中间像素的G值,将会降低一倍的速率,而在性能上差之甚微,算法如下:
     在这里插入图片描述

  如果能够通过损失图像的额质量,来达到更快的速度,还可以取G1、G2的均值来实现,但是这样的做法会导致边沿以及跳变部分的失真。

将Bayer格式转换为tif格式

//全部.h文件
#include <iostream>
#include <vector>
#include <fstream>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal.h>
#include <stdio.h>
#include <stdlib.h>
#include "j2k_mem_advance.h"
#include "format_defs.h"
#include "j2k_mem.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/io.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <memory>
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <time.h>
#include <thread>
#include <stdio.h>
#include <string.h>
#include "TinyXML.h"

using namespace std;
//此头文件应该是必须的部分
#include <iostream>
#include <fstream>
#include <gdal_priv.h>
#include <gdalwarper.h>
#include <gdal.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

//核心代码部分
//将.dat文件读取后进行gbbr转换,最后转码为TIF文件
bool Anal_pixel(string strFilePath, string strSavePath, long nWidth, long nHeight, int nType)
{
	// TODO:  在此添加控件通知处理程序代码
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");   //支持中文路径

	if (strFilePath == "")
	{
		return false;
	}

	const char* pszFormat = "GTIFF";
	GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
	if (!poDriver) {
		return false;
	}

	//long width = 7920;
	//long height = 6004;
	long long width = nWidth;
	long long height = nHeight;

	GDALDataType gdal_data_type = GDT_UInt16;


	unsigned short* pData = new unsigned short[width * height];

	fstream sf;
	sf.open(strFilePath, ios::in | ios::binary);//打开文件,供读
	sf.seekg(0, ios::beg);

	//byte *bTemp = new byte[2];
	unsigned char* bTemp = new unsigned char[2];

	for (int i = 0; i < height * width; i++)
	{
		sf.read((char*)&bTemp[0], sizeof(unsigned char));
		sf.read((char*)&bTemp[1], sizeof(unsigned char));
		pData[i] = bTemp[0] * 256 + bTemp[1];
		//char pBuff[8];
		//sprintf(pBuff, "%04x", pData[i]);
		//int isdsd = 0;
	}
	sf.close();
	delete[] bTemp;
	//----------------------解析
#pragma region 解析

	PointInfo** cArryAllPoint; // 二维数组
	cArryAllPoint = (PointInfo**)malloc(height * sizeof(PointInfo*));//height 行
	for (int i = 0; i < height; i++) {
		cArryAllPoint[i] = (PointInfo*)malloc(width * sizeof(PointInfo));//width 列
	}

	//读取文件,将文件中的数值填充
	for (long long y = 0; y < height; y++)
	{
		for (long long x = 0; x < width / 2; x++)
		{
			cArryAllPoint[y][2 * x].Point_X = 2 * x;
			cArryAllPoint[y][2 * x].Point_Y = y;

			cArryAllPoint[y][2 * x + 1].Point_X = 2 * x + 1;
			cArryAllPoint[y][2 * x + 1].Point_Y = y;
			if (y % 2 == 0)
			{
				cArryAllPoint[y][2 * x].Point_B = pData[y * width / 4 + x + height * width * 1 / 2];//B
				cArryAllPoint[y][2 * x + 1].Point_G = pData[y * width / 2 + x];//G
			}
			else
			{
				cArryAllPoint[y][2 * x].Point_G = pData[y * width / 2 + x];//G
				cArryAllPoint[y][2 * x + 1].Point_R = pData[(y - 1) * width / 4 + x + height * width * 3 / 4];//R
			}
		}
	}
	delete[] pData;//释放内存

	//计算RGB值
	unsigned short R1, R2, R3, R4, B1, B2, B3, B4, G1, G2, G3, G4;
	for (long long y = 0; y < height; y++)//初始化数据 
	{
		for (long long x = 0; x < width; x++)
		{
			if (y % 2 == 0)
			{
				if (x % 2 == 0)
				{
					if (x == 0)
					{
						if (y == 0)
						{
							R1 = 0;
							R2 = 0;
							R3 = 0;
							R4 = cArryAllPoint[y + 1][x + 1].Point_R;
							G1 = 0;
							G2 = 0;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
						else if (y == height - 1)
						{
							R1 = 0;
							R2 = 0;
							R3 = cArryAllPoint[y - 1][x + 1].Point_R;
							R4 = 0;
							G1 = 0;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = 0;
						}
						else
						{
							R1 = 0;
							R2 = 0;
							R3 = cArryAllPoint[y - 1][x + 1].Point_R;
							R4 = cArryAllPoint[y + 1][x + 1].Point_R;
							G1 = 0;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
					}
					else if (x == width - 1)
					{
						if (y == 0)
						{
							R1 = cArryAllPoint[y + 1][x - 1].Point_R;
							R2 = 0;
							R3 = 0;
							R4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = 0;
							G3 = 0;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
						else if (y == height - 1)
						{
							R1 = 0;
							R2 = cArryAllPoint[y - 1][x - 1].Point_R;
							R3 = 0;
							R4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = 0;
							G4 = 0;
						}
						else
						{
							R1 = cArryAllPoint[y + 1][x - 1].Point_R;
							R2 = cArryAllPoint[y - 1][x - 1].Point_R;
							R3 = 0;
							R4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = 0;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
					}
					else
					{
						if (y == 0)
						{
							R1 = cArryAllPoint[y + 1][x - 1].Point_R;
							R2 = 0;
							R3 = 0;
							R4 = cArryAllPoint[y + 1][x + 1].Point_R;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = 0;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
						else if (y == height - 1)
						{
							R1 = 0;
							R2 = cArryAllPoint[y - 1][x - 1].Point_R;
							R3 = cArryAllPoint[y - 1][x + 1].Point_R;
							R4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = 0;
						}
						else
						{
							R1 = cArryAllPoint[y + 1][x - 1].Point_R;
							R2 = cArryAllPoint[y - 1][x - 1].Point_R;
							R3 = cArryAllPoint[y - 1][x + 1].Point_R;
							R4 = cArryAllPoint[y + 1][x + 1].Point_R;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
					}

					cArryAllPoint[y][x].Point_R = (R1 + R2 + R3 + R4) / 4;
					cArryAllPoint[y][x].Point_G = (G1 + G2 + G3 + G4) / 4;
				}
				else
				{
					//unsigned short R1, R2, B1, B2;
					//G
					//G1,R2,G4
					//B1,G ,B2
					//G2,R1,G3
					//R1 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_R;
					//R2 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_R;
					//B1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_B;
					//B2 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_B;

					if (x == 0)
					{
						if (y == 0)
						{
							R1 = 0;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = 0;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
						else if (y == height - 1)
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = 0;
							B1 = 0;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
						else
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = 0;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
					}
					else if (x == width - 1)
					{
						if (y == 0)
						{
							R1 = 0;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = 0;
						}
						else if (y == height - 1)
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = 0;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = 0;
						}
						else
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = 0;
						}
					}
					else
					{
						if (y == 0)
						{
							R1 = 0;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
						else if (y == height - 1)
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = 0;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
						else
						{
							R1 = cArryAllPoint[y - 1][x].Point_R;
							R2 = cArryAllPoint[y + 1][x].Point_R;
							B1 = cArryAllPoint[y][x - 1].Point_B;
							B2 = cArryAllPoint[y][x + 1].Point_B;
						}
					}

					cArryAllPoint[y][x].Point_R = (R1 + R2) / 2;
					cArryAllPoint[y][x].Point_B = (B1 + B2) / 2;
				}
			}
			else
			{
				if (x % 2 == 0)
				{
					//unsigned short R1, R2, B1, B2;
					//G
					//G1,B2,G4
					//R1,G ,R2
					//G2,B1,G3

					//R1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_R;
					//R2 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_R;
					//B1 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_B;
					//B2 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_B;
					if (x == 0)
					{
						if (y == 0)
						{
							R1 = 0;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = 0;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
						else if (y == height - 1)
						{
							R1 = 0;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = 0;
						}
						else
						{
							R1 = 0;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
					}
					else if (x == width - 1)
					{
						if (y == 0)
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = 0;
							B1 = 0;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
						else if (y == height - 1)
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = 0;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = 0;
						}
						else
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = 0;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
					}
					else
					{
						if (y == 0)
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = 0;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
						else if (y == height - 1)
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = 0;
						}
						else
						{
							R1 = cArryAllPoint[y][x - 1].Point_R;
							R2 = cArryAllPoint[y][x + 1].Point_R;
							B1 = cArryAllPoint[y - 1][x].Point_B;
							B2 = cArryAllPoint[y + 1][x].Point_B;
						}
					}

					cArryAllPoint[y][x].Point_R = (R1 + R2) / 2;
					cArryAllPoint[y][x].Point_B = (B1 + B2) / 2;
				}
				else
				{
					//unsigned short B1, B2, B3, B4, G1, G2, G3, G4;
					//R
					//B1,G4,B4
					//G1,R ,G3
					//B2,G2,B3

					//B1 = cArryAllPoint.GetAt(y + 1)->GetAt(x - 1).Point_B;
					//B2 = cArryAllPoint.GetAt(y - 1)->GetAt(x - 1).Point_B;
					//B3 = cArryAllPoint.GetAt(y - 1)->GetAt(x + 1).Point_B;
					//B4 = cArryAllPoint.GetAt(y + 1)->GetAt(x + 1).Point_B;
					//G1 = cArryAllPoint.GetAt(y)->GetAt(x - 1).Point_G;
					//G2 = cArryAllPoint.GetAt(y - 1)->GetAt(x).Point_G;
					//G3 = cArryAllPoint.GetAt(y)->GetAt(x + 1).Point_G;
					//G4 = cArryAllPoint.GetAt(y + 1)->GetAt(x).Point_G;

					if (x == 0)
					{
						//不存在 X=0
					}
					else if (x == width - 1)
					{
						if (y == 0)
						{
							//不存在 Y=0
						}
						else if (y == height - 1)
						{
							B1 = 0;
							B2 = cArryAllPoint[y - 1][x - 1].Point_B;
							B3 = 0;
							B4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = 0;
							G4 = 0;
						}
						else
						{
							B1 = cArryAllPoint[y + 1][x - 1].Point_B;
							B2 = cArryAllPoint[y - 1][x - 1].Point_B;
							B3 = 0;
							B4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = 0;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
					}
					else
					{
						if (y == 0)
						{
							//不存在 Y=0
						}
						else if (y == height - 1)
						{
							B1 = 0;
							B2 = cArryAllPoint[y - 1][x - 1].Point_B;
							B3 = cArryAllPoint[y - 1][x + 1].Point_B;
							B4 = 0;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = 0;
						}
						else
						{
							B1 = cArryAllPoint[y + 1][x - 1].Point_B;
							B2 = cArryAllPoint[y - 1][x - 1].Point_B;
							B3 = cArryAllPoint[y - 1][x + 1].Point_B;
							B4 = cArryAllPoint[y + 1][x + 1].Point_B;
							G1 = cArryAllPoint[y][x - 1].Point_G;
							G2 = cArryAllPoint[y - 1][x].Point_G;
							G3 = cArryAllPoint[y][x + 1].Point_G;
							G4 = cArryAllPoint[y + 1][x].Point_G;
						}
					}

					cArryAllPoint[y][x].Point_B = (B1 + B2 + B3 + B4) / 4;
					cArryAllPoint[y][x].Point_G = (G1 + G2 + G3 + G4) / 4;
				}
			}

		}
	}
	//整合到pDataRGB中
	//unsigned char * pDataRGB = new unsigned char[width * height * 3];
	unsigned short** newbuffs = new unsigned short* [3]; // 1, 2, 3 : r g b 
	newbuffs[0] = new unsigned short[width * height];
	newbuffs[1] = new unsigned short[width * height];
	newbuffs[2] = new unsigned short[width * height];
	double dTemp;
	for (long long y = 0; y < height; y++)//初始化数据
	{
		for (long long x = 0; x < width; x++)
		{
			dTemp = (double)cArryAllPoint[y][x].Point_R;
			newbuffs[0][y * width + x] = (unsigned short)dTemp;
			dTemp = (double)cArryAllPoint[y][x].Point_G;
			newbuffs[1][y * width + x] = (unsigned short)dTemp;
			dTemp = (double)cArryAllPoint[y][x].Point_B;
			newbuffs[2][y * width + x] = (unsigned short)dTemp;
		}
	}

	double minDN[3] = { 0 };//统计最小的DN值
	double maxDN[3] = { 0 };//统计最大的DN值

	//释放内存 cArryAllPoint
	for (int i = 0; i < height; i++)
	{
		delete[] cArryAllPoint[i];
	}
	free(cArryAllPoint);

//将原数据进行拉伸放大
	for (long long m = 0; m < height; m++)
	{
		for (long long n = 0; n < width; n++)
		{
			for (long long i = 0; i < 3; i++)
			{

				if (newbuffs[i][m * width + n] < minDN[i])
					minDN[i] = newbuffs[i][m * width + n];
				if (newbuffs[i][m * width + n] > maxDN[i])
					maxDN[i] = newbuffs[i][m * width + n];
			}
		}
	}
	for (long long i = 0; i < 3; i++)
	{
		for (long long m = 0; m < height*width; m++)
		{
			newbuffs[i][m] = (newbuffs[i][m] - minDN[i]) * 1.0 / (maxDN[i] - minDN[i]) * 65535;
		}
	}




#pragma endregion

	if (nType == 0)//拉伸后的图像
	{
		char** papszOptions = nullptr;
		papszOptions = CSLSetNameValue(papszOptions, "INTERLEAVE", "BAND");
		papszOptions = CSLSetNameValue(papszOptions, "BIGTIFF", "IF_NEEDED");
		const char* pszDstFilename = strSavePath.c_str();
		GDALDataset* poDstDS = poDriver->Create(pszDstFilename, width, height, 3, GDT_UInt16, papszOptions);
		if (!poDstDS) {
			for (int i = 0; i < 3; i++)
			{
				delete[] newbuffs[i];
			}
			free(newbuffs);
			return false;
		}

		int bandMap[3] = { 1, 2, 3 };

		for (int i = 0; i < 3; i++)
		{
			poDstDS->GetRasterBand(i + 1)->RasterIO(GF_Write, 0, 0, width, height, newbuffs[i], width, height, GDT_UInt16, 0, 0, 0);
			delete[] newbuffs[i];
		}
		free(newbuffs);
		GDALClose((GDALDatasetH)poDstDS);


	}
	else
	{
//针对原图16位的值进行高8位、低8位、中8位的转换。
		unsigned char** newbuffs1 = new unsigned char* [3]; // 1, 2, 3 : r g b 
		newbuffs1[0] = new unsigned char[width * height];
		newbuffs1[1] = new unsigned char[width * height];
		newbuffs1[2] = new unsigned char[width * height];

		for (long long i = 0; i < 3; i++)
		{
			for (long long m = 0; m < height; m++)
			{

				for (long long n = 0; n < width; n++)
				{
					char pBuff[4], pBuff2[8];
					if (nType == 1)//高8
					{
						newbuffs1[i][m * width + n] = newbuffs[i][m * width + n] / 4;//------G8
					}
					else if (nType == 2)//中8
					{
						newbuffs1[i][m * width + n] = newbuffs[i][m * width + n] / 2;//-------M8
					}
					else if (nType == 3)//低8
					{
						newbuffs1[i][m * width + n] = newbuffs[i][m * width + n];//------D8
					}
				}
			}

		}
		char** papszOptions = nullptr;
		papszOptions = CSLSetNameValue(papszOptions, "INTERLEAVE", "BAND");
		papszOptions = CSLSetNameValue(papszOptions, "BIGTIFF", "IF_NEEDED");
		const char* pszDstFilename = strSavePath.c_str();
		GDALDataset* poDstDS = poDriver->Create(pszDstFilename, width, height, 3, GDT_Byte, papszOptions);
		if (!poDstDS) {
			for (int i = 0; i < 3; i++)
			{
				delete[] newbuffs[i];
				delete[] newbuffs1[i];
			}
			return false;
		}

		int bandMap[3] = { 1, 2, 3 };

		for (int i = 0; i < 3; i++)
		{
			poDstDS->GetRasterBand(i + 1)->RasterIO(GF_Write, 0, 0, width, height, newbuffs1[i], width, height, GDT_Byte, 0, 0, 0);
			delete[] newbuffs[i];
			delete[] newbuffs1[i];
		}
		GDALClose((GDALDatasetH)poDstDS);

	}
	return true;
}

第一次书写博客会有些许乱,有需求的可以私我或者留言询问具体问题。

参考文件:

感谢作者:
淇淇宝贝   https://www.cnblogs.com/qiqibaby/p/5267566.html

举报

相关推荐

0 条评论