机器学习猪

--------一只帅气潇洒略带才气的猪

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本博客为原创内容,未经博主允许禁止转载,商用,谢谢。

一、前言

  关于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,还请与我交流,共同提高。

 

posted on 2016-08-28 20:52  机器学习猪  阅读(4305)  评论(43编辑  收藏  举报