完善GDAL與OpenCV間的數據格式轉換與影像分塊讀寫


本博客為原創內容,未經博主允許禁止轉載,商用,謝謝。

一、前言

  關於GDAL與openCV間的數據格式轉換,在我之前的博客中已有簡要說明,這里,由於最近工作上經常用到openCV里的函數進行圖像處理,所以寫了一個程序,進一步對這兩個開源庫進行連接。

  除了格式轉換外,該類還支持數據的分塊讀入與寫出。

二、代碼

  所有功能在一個GDALOPENCV類中完成,其頭文件如下:

//////////////////////////////////////////////////////////////////////
   ////////////完成GDAL文件與OpenCV的文件讀寫轉換////////////////
//////////////////////支持數據分塊讀寫////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

#pragma once
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <gdal_priv.h>
#include <vector>
#include <string>
#include <math.h>
#include <iostream>

/***********************************************************/
// GCDataType:GDAL和OpenCV數據類型轉換的中間格式
// GC_Byte   =======  GDT_Byte   =======  CV_8U  =======  unsigned char
// GC_UInt16 =======  GDT_UInt16 =======  CV_16U =======  unsigned short
// GC_Int16  =======  GDT_Int16  =======  CV_16S =======  short int
// GC_UInt32 =======  GDT_UInt32 =======  缺失   =======  unsigned long
// GC_Int32  =======  GDT_Int32  =======  CV_32S =======  long
// GC_Float32=======  GDT_Float32=======  CV_32F =======  float
// GC_Float64=======  GDT_Float64=======  CV_64F =======  double
/***********************************************************/
typedef enum{
	GC_Byte = 0,
	GC_UInt16 = 1,
	GC_Int16 = 2,
	GC_UInt32 = 3,
	GC_Int32 = 4,
	GC_Float32 = 5,
	GC_Float64 = 6,
	GC_ERRType = 7
} GCDataType;

class GDALOpenCV
{
	/***********************************************************/
	// PatchIndex:存儲具體影像分塊信息
	// iPatch 分類表:1----兩個邊界重合    2----三個邊界重合   3----四個邊界重合
	//  11 12 13 14     21 22 23 24    31
	// =======================
	//   11 =    21    =  12
	// =======================
	//   24 =    31    =  22
	// =======================
	//   14 =    23    =  13 
	// =======================
    /***********************************************************/
	typedef struct {
		int iPatch;      //  第幾類
		int row_begin;   // 影像中起始行
		int col_begin;   // 影像中起始列
		int width;       // 影像塊的寬度
		int heigth;     // 影像塊的高度
	} PatchIndex;


public:
	GDALOpenCV(const std::string fileName);  // 唯一構造函數
	~GDALOpenCV(void);   // 析構函數
	
public:
	void Initialization();   // 初始化  實際上為獲取影像格式;
	cv::Size SetPatchSize(const int r,const int c)  // 設置分塊大小
	{
		m_patchSize.width = c;	m_patchSize.height = r;
		return m_patchSize;
	};

	void SetOverlappedPixel(const int num)
	{
		m_overlappedPixel = num;
	};


	bool GDAL2Mat(cv::Mat &img);  // 影像讀取為Mat格式  不分塊
	bool Mat2File(const std::string outFileName,cv::Mat &img,const int flag = 1);  // Mat文件輸出為影像
	//  flag = 默認為1  輸出TIFF   另外還支持ENVI 和 ARDAS數據格式

	int GetImgToPatchNum();  // 返回影像分塊數  和  獲取影像分塊信息
	void GetROIFromPatchIndex(const int,cv::Mat &);  //  獲取對應塊編號的影像
	bool SetROIMatToFileByIndex(const std::string outFile,cv::Mat &img,
		const int index,const int flag = 1); // 影像分塊寫入  有待改進  具體細節有點商榷  

	GCDataType GDALType2GCType(const GDALDataType ty); // GDAL Type ==========> GDALOpenCV Type
	GDALDataType GCType2GDALType(const GCDataType ty); //  GDALOpenCV Type ==========> GDAL Type
	GCDataType OPenCVType2GCType(const int ty); // OPenCV Type ==========> GDALOpenCV Type
	int GCType2OPenCVType(const GCDataType ty); // GDALOpenCV Type ==========> OPenCV Type

private:
	void* AllocateMemory(const GCDataType lDataType,const long long lSize);   // 智能分配內存
	void* SetMemCopy(void *dst,const void *src,const GCDataType lDataType,const long long lSize);

public:
	GCDataType m_dataType;  // 數據類型
	int m_imgWidth; // 影像寬度   列數
	int m_imgHeigth; // 影像高度   行數
	int m_bandNum; // 影像波段數
private:
	//GDALDataType m_gdalType;
	GDALDataset *m_poDataSet;  // 數據驅動集
	GDALDataset *m_outPoDataSet;
	cv::Size m_patchSize;// 分塊圖像大小
	//std::string m_fileName; // 文件名  打開
	cv::vector<PatchIndex> *m_patchIndex;//分塊標識
	int m_overlappedPixel;
};


//////////////////////////////////////////////////////////
//    使用說明:
/////////////////////////////////////////////////////////
//   GDALOpenCV gdalOpenCV(fileName);
//   gdalOpenCV.Initialization();

 cpp文件如下:

#include "GDALOpenCV.h"

GDALOpenCV::GDALOpenCV(const std::string fileName)
{
	m_poDataSet = NULL;
	GDALAllRegister();
	m_poDataSet = (GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly);
	m_outPoDataSet = NULL;
}

GDALOpenCV::~GDALOpenCV(void)
{
	if(m_poDataSet!=NULL)
		GDALClose((GDALDatasetH)m_poDataSet);
	if(m_outPoDataSet!=NULL)
		GDALClose((GDALDatasetH)m_outPoDataSet);
	m_patchIndex->clear();
	delete m_patchIndex;
	m_patchIndex = NULL;

}

void GDALOpenCV::Initialization()
{
	if(!m_poDataSet)
		return;
	m_imgHeigth= m_poDataSet->GetRasterYSize();  // 影像行
	m_imgWidth = m_poDataSet->GetRasterXSize();  // 影像列
	m_bandNum = m_poDataSet->GetRasterCount(); // 影像波段數
	m_overlappedPixel = -1;     //  重復像素個數 

	GDALRasterBand *pBand = m_poDataSet->GetRasterBand(1);
	GDALDataType gdalTy = pBand->GetRasterDataType();
	m_dataType = GDALType2GCType(gdalTy);

	m_patchSize.width = m_imgWidth;
	m_patchSize.height = m_imgHeigth;

	m_patchIndex = new std::vector<PatchIndex>(1);
	PatchIndex tmp = {1,0,0,m_imgWidth,m_imgHeigth};
	m_patchIndex->at(0) = tmp;
}

bool GDALOpenCV::GDAL2Mat(cv::Mat &img)
{
	if(!m_poDataSet)
		return false;

	GDALRasterBand *pBand = NULL;  // 波段
	void *pafBuffer = AllocateMemory(m_dataType,m_imgHeigth*m_imgWidth);  // 開辟內存
	std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum);   // 存儲各波段
	cv::Mat *tmpMat = NULL;  // 臨時存儲一個波段

	int iBand = 0; // 波段標記
	while(iBand<m_bandNum)        
	{
		pBand = m_poDataSet->GetRasterBand(++iBand);
		pBand->RasterIO(GF_Read,0,0,m_imgWidth,m_imgHeigth,pafBuffer,m_imgWidth,
			m_imgHeigth,GCType2GDALType(m_dataType),0,0);
		tmpMat = new cv::Mat(m_imgHeigth,m_imgWidth,GCType2OPenCVType(m_dataType),pafBuffer);
		imgMat->at(iBand-1) = (*tmpMat).clone();
		delete tmpMat;
		tmpMat = NULL;
	}
	cv::merge(*imgMat,img);

	// 內存管理
	delete pafBuffer;	pafBuffer = NULL;
	imgMat->clear();	delete imgMat;	imgMat = NULL;

	return true;
}


bool GDALOpenCV::Mat2File( const std::string outFileName,cv::Mat &img,
						  const int flag /*= 1*/ )
{
	if(img.empty())
		return false;

	const int nBandCount=img.channels();
	const int nImgSizeX=img.cols;
	const int nImgSizeY=img.rows;

	std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(nBandCount);
	cv::split(img,*imgMat);	

	GDALAllRegister();
	//GDALDataset *poDataset;   //GDAL數據集
	GDALDriver *poDriver;     //驅動,用於創建新的文件
	////////////////////////////////
	///flag:1 ====》TIFF
	///      2 ====》HFA
	///      3 ====》ENVI
	std::string pszFormat; //存儲數據類型
	switch (flag) {
	case 1:
		pszFormat = "GTiff";
		break;
	case 2:
		pszFormat = "HFA";
		break;
	case 3:
		pszFormat = "ENVI";
		break;
	default:
		return 0;
	}

	int OPenCVty = imgMat->at(0).type();
	GCDataType GCty = OPenCVType2GCType(OPenCVty);

	poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat.c_str());
	if(poDriver == NULL)
		return 0;
	if(m_outPoDataSet == NULL)
	{
		m_outPoDataSet=poDriver->Create(outFileName.c_str(),nImgSizeX,nImgSizeY,nBandCount,
			GCType2GDALType(GCty),NULL);
		m_outPoDataSet->SetProjection(m_poDataSet->GetProjectionRef());
		double dGeotransform[6];
		m_poDataSet->GetGeoTransform(dGeotransform);
		m_outPoDataSet->SetGeoTransform(dGeotransform);
	}

	//  循環寫入文件
	GDALRasterBand *pBand = NULL;
	void *ppafScan = AllocateMemory(GCty,nImgSizeX*nImgSizeY);
	int n1 = nImgSizeY;
	int nc = nImgSizeX;
	cv::Mat tmpMat;
	for(int i = 1;i<=nBandCount;i++)
	{
		pBand = m_outPoDataSet->GetRasterBand(i);
		tmpMat = imgMat->at(i-1);
		if(tmpMat.isContinuous())
			SetMemCopy(ppafScan,(void*)tmpMat.ptr(0),GCty,nImgSizeX*nImgSizeY);
		else
			return false;
		CPLErr err = pBand->RasterIO(GF_Write,0,0,nImgSizeX,nImgSizeY,ppafScan,
			nImgSizeX,nImgSizeY,GCType2GDALType(GCty),0,0);
	}

	delete ppafScan;	ppafScan = NULL;
	imgMat->clear();delete imgMat;imgMat = NULL;	
	return 1;
}


int GDALOpenCV::GetImgToPatchNum()
{
	if(m_patchSize.width >= m_imgWidth || m_patchSize.height >= m_imgHeigth)
		return 1;
	if(m_overlappedPixel == -1)
		return 1;
	////////////////分塊核心代碼/////////////////////
	//////////////分塊數確定////////////////////////
	int rPatchNum = cvCeil((m_imgHeigth*1.0 -m_patchSize.height)/(m_patchSize.height - m_overlappedPixel)) + 1;
	int cPatchNum = cvCeil((m_imgWidth*1.0 - m_patchSize.width)/(m_patchSize.width - m_overlappedPixel)) +1;

	PatchIndex tmpPatchIndex;
	int rowBegin = 0;
	int colBegin = 0;

	m_patchIndex->clear();
	for(int i = 0;i != rPatchNum; i++)
	{
		for(int j = 0;j != cPatchNum; j++)
		{
			if(0x00 == i && 0x00 == j)
				tmpPatchIndex.iPatch = 11;
			else if(0x00 == i && cPatchNum-1 == j)
				tmpPatchIndex.iPatch = 12;
			else if(rPatchNum-1 == i && cPatchNum-1 == j)
				tmpPatchIndex.iPatch = 13;
			else if(rPatchNum-1 == i && 0x00 == j)
				tmpPatchIndex.iPatch = 14;
			else if(0x00 == i && j>0 && j< cPatchNum-1)
				tmpPatchIndex.iPatch = 21;
			else if(j == cPatchNum -1 && i>0 && i<rPatchNum -1)
				tmpPatchIndex.iPatch = 22;
			else if(i == rPatchNum-1 && j>0 && j<cPatchNum -1)
				tmpPatchIndex.iPatch = 23;
			else if(0x00 == j && i > 0 && i<rPatchNum -1)
				tmpPatchIndex.iPatch = 24;
			else
				tmpPatchIndex.iPatch = 31;

			tmpPatchIndex.row_begin = rowBegin;
			tmpPatchIndex.col_begin = colBegin;
			if(rowBegin+m_patchSize.height > m_imgHeigth)
				tmpPatchIndex.heigth = m_imgHeigth - rowBegin;
			else
				tmpPatchIndex.heigth = m_patchSize.height;
			if(colBegin+m_patchSize.width > m_imgWidth)
				tmpPatchIndex.width = m_imgWidth - colBegin;
			else
				tmpPatchIndex.width = m_patchSize.width;
			m_patchIndex->push_back(tmpPatchIndex);
			colBegin = colBegin + m_patchSize.width - m_overlappedPixel;
		}
		rowBegin = rowBegin + m_patchSize.height - m_overlappedPixel;
		colBegin = 0;
	}
	return (int)m_patchIndex->size();
}


void GDALOpenCV::GetROIFromPatchIndex(const int index,cv::Mat &img)
{
	int patchNum = (int)m_patchIndex->size();
	if(index > patchNum || index < 1)
		return;
	PatchIndex curPatchIndex = m_patchIndex->at(index-1);
	int patchRowBegin = curPatchIndex.row_begin;
	int patchColBegin = curPatchIndex.col_begin;
	int patchWidth = curPatchIndex.width;
	int patchHeight = curPatchIndex.heigth;

	std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum);// 存儲讀取的每個波段數據 
	void *pafBuffer = AllocateMemory(m_dataType,patchWidth*patchHeight); // 內存分配
	GDALRasterBand *pBand = NULL;
	cv::Mat *tmpMat = NULL;

	int iBand = 0; // 波段標記
	while(iBand<m_bandNum)
	{
		pBand = m_poDataSet->GetRasterBand(++iBand);
		pBand->RasterIO(GF_Read,patchColBegin,patchRowBegin,patchWidth,patchHeight,pafBuffer,
			patchWidth,patchHeight,GCType2GDALType(m_dataType),0,0);
		tmpMat =new cv::Mat(patchHeight,patchWidth,GCType2OPenCVType(m_dataType),pafBuffer);
		imgMat->at(iBand-1) = (*tmpMat).clone();
		delete tmpMat;
		tmpMat = NULL;
	}
	cv::merge(*imgMat,img);

	delete pafBuffer;pafBuffer = NULL;
	//delete pBand;pBand = NULL;
	imgMat->clear();delete imgMat;imgMat = NULL;
}


bool GDALOpenCV::SetROIMatToFileByIndex( const std::string outFileName,cv::Mat &img, 
										const int index,const int flag /*= 1*/ )
{
	if(!outFileName.c_str() || img.empty())
		return false;

	const int nBandCount=img.channels();
	const int nImgSizeX=img.cols;
	const int nImgSizeY=img.rows;

	PatchIndex tmpPatchIndex = m_patchIndex->at(index-1);
	if(tmpPatchIndex.heigth != nImgSizeY || tmpPatchIndex.width != nImgSizeX)
		return false;

	std::vector<cv::Mat> *imgMat = new std::vector<cv::Mat>(m_bandNum);
	cv::split(img,*imgMat);

	const int ty = (*imgMat).at(0).type();

	GDALAllRegister();
	//GDALDataset *poDataset = NULL;   //GDAL數據集
	GDALDriver *poDriver = NULL;      //驅動,用於創建新的文件

	////////////////////////////////
	///flag:1 ====》TIFF
	///      2 ====》HFA
	///      3 ====》ENVI
	std::string pszFormat; //存儲數據類型
	switch (flag) {
	case 1:
		pszFormat = "GTiff";
		break;
	case 2:
		pszFormat = "HFA";
		break;
	case 3:
		pszFormat = "ENVI";
		break;
	default:
		return 0;
	}

	poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat.c_str());
	int OPenCVty = imgMat->at(0).type();
	GCDataType GCty = OPenCVType2GCType(OPenCVty);
	if(poDriver == NULL)
		return 0;
	if(m_outPoDataSet == NULL)
	{
		m_outPoDataSet=poDriver->Create(outFileName.c_str(),m_imgWidth,m_imgHeigth,nBandCount,
			GCType2GDALType(GCty),NULL);
		m_outPoDataSet->SetProjection(m_poDataSet->GetProjectionRef());
		double dGeotransform[6];
		m_poDataSet->GetGeoTransform(dGeotransform);
		m_outPoDataSet->SetGeoTransform(dGeotransform);
	}
	//  循環寫入文件
	GDALRasterBand *pBand = NULL;	
	int n1 = nImgSizeY;
	int nc = nImgSizeX;
	int overPix = int(m_overlappedPixel/2);

	void *ppafScan = NULL;
	int curCol = 0;
	int curRow = 0;
	
	for(int i = 1;i<=nBandCount;i++)
	{
		pBand = m_outPoDataSet->GetRasterBand(i);
		cv::Mat tmpMat;
		tmpMat = imgMat->at(i-1);
		// 文件的寫入
		if(tmpPatchIndex.iPatch == 11)      
		{	
			curCol = nImgSizeX-overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(0,0,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 12)
		{	
			curCol = nImgSizeX-overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(overPix,0,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 13)
		{
			curCol = nImgSizeX-overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(overPix,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 14)
		{
			curCol = nImgSizeX-overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(0,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 21)
		{
			curCol = nImgSizeX-2*overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(overPix,0,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 22)
		{
			curCol = nImgSizeX- overPix;
			curRow = nImgSizeY - 2*overPix;
			cv::Rect r1(overPix,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 23)
		{
			curCol = nImgSizeX- 2*overPix;
			curRow = nImgSizeY - overPix;
			cv::Rect r1(overPix,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 24)
		{
			curCol = nImgSizeX- overPix;
			curRow = nImgSizeY - 2*overPix;
			cv::Rect r1(0,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
		if(tmpPatchIndex.iPatch == 31)
		{
			curCol = nImgSizeX- 2*overPix;
			curRow = nImgSizeY - 2*overPix;
			cv::Rect r1(overPix,overPix,curCol,curRow);
			tmpMat = tmpMat(r1);
			cv::Mat *newMat = new cv::Mat(curRow,curCol,ty);
			*newMat = tmpMat.clone();
			ppafScan = AllocateMemory(GCty,curCol*curRow);
			if((*newMat).isContinuous())
				SetMemCopy(ppafScan,(void*)(*newMat).ptr(0),GCty,curCol*curRow);
			else
				return false;
			pBand->RasterIO(GF_Write,tmpPatchIndex.col_begin+overPix,tmpPatchIndex.row_begin+overPix,
				curCol,curRow,ppafScan,curCol,curRow,GCType2GDALType(GCty),0,0);
			delete newMat;newMat = NULL;
		}
	}
	delete ppafScan;ppafScan = NULL;
	imgMat->clear();delete imgMat;imgMat = NULL;
	return 1;
}

GCDataType GDALOpenCV::GDALType2GCType( const GDALDataType ty )
{
	switch(ty)
	{
	case GDT_Byte:
		return GC_Byte;
	case GDT_UInt16:
		return GC_UInt16;
	case GDT_Int16:
		return GC_Int16;
	case GDT_UInt32:
		return GC_UInt32;
	case GDT_Int32:
		return GC_Int32;
	case GDT_Float32:
		return GC_Float32;
	case GDT_Float64:
		return GC_Float64;
	default:
		assert(false);
		return GC_ERRType;
	}
}

GCDataType GDALOpenCV::OPenCVType2GCType( const int ty )
{
	switch(ty)
	{
	case 0:
		return GC_Byte;
	case 2:
		return GC_UInt16;
	case 3:
		return GC_Int16;
	case 4:
		return GC_Int32;
	case 5:
		return GC_Float32;
	case 6:
		return GC_Float64;
	default:
		assert(false);
		return GC_ERRType;
	}
}

GDALDataType GDALOpenCV::GCType2GDALType( const GCDataType ty )
{
	switch(ty)
	{
	case GC_Byte:
		return GDT_Byte;
	case GC_UInt16:
		return GDT_UInt16;
	case GC_Int16:
		return GDT_Int16;
	case GC_UInt32:
		return GDT_UInt32;
	case GC_Int32:
		return GDT_Int32;
	case GC_Float32:
		return GDT_Float32;
	case GC_Float64:
		return GDT_Float64;
	default:
		assert(false);
		return GDT_TypeCount;
	}
}

int GDALOpenCV::GCType2OPenCVType( const GCDataType ty )
{
	switch(ty)
	{
	case GC_Byte:
		return 0;
	case GC_UInt16:
		return 2;
	case GC_Int16:
		return 3;
	case GC_Int32:
		return 4;
	case GC_Float32:
		return 5;
	case GC_Float64:
		return 6;
	default:
		assert(false);
		return -1;
	}
}

void* GDALOpenCV::AllocateMemory(const GCDataType lDataType,const long long lSize )
{
	assert(0!=lSize);
	void* pvData = NULL;
	switch (lDataType)
	{
	case GC_Byte:
		pvData = new(std::nothrow) unsigned char[lSize];
		break;
	case GC_UInt16:
		pvData = new(std::nothrow) unsigned short int[lSize];
		break;
	case GC_Int16:
		pvData = new(std::nothrow) short int[lSize];
		break;
	case GC_UInt32:
		pvData = new(std::nothrow) unsigned long[lSize];
		break;
	case GC_Int32:
		pvData = new(std::nothrow) long[lSize];
		break;
	case GC_Float32:
		pvData = new(std::nothrow) float[lSize];
		break;
	case GC_Float64:
		pvData = new(std::nothrow) double[lSize];
		break;
	default: 
		assert(false);
		break;
	}
	return pvData;
}

void* GDALOpenCV::SetMemCopy( void *dst,const void *src,
							 const GCDataType lDataType,
							 const long long lSize )
{
	assert(0!=lSize);
	switch (lDataType)
	{
	case GC_Byte:
		return memmove(dst,src,sizeof(unsigned char)*lSize);
	case GC_UInt16:
		return memmove(dst,src,sizeof(unsigned short)*lSize);
	case GC_Int16:
		return memmove(dst,src,sizeof(short int)*lSize);
	case GC_UInt32:
		return memmove(dst,src,sizeof(unsigned long)*lSize);
	case GC_Int32:
		return memmove(dst,src,sizeof(long)*lSize);
	case GC_Float32:
		return memmove(dst,src,sizeof(float)*lSize);
	case GC_Float64:
		return memmove(dst,src,sizeof(double)*lSize);
	default: 
		return NULL;
	}
}

  這個類我已經用了一段時間,可以直接使用,如果有啥bug,還請與我交流,共同提高。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM