zoukankan      html  css  js  c++  java
  • 完善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,还请与我交流,共同提高。

     

  • 相关阅读:
    图片懒加载DEMO
    手写offset函数
    DOM
    jQuery笔记
    children和 childNodes辨析
    运算符...典型的三种用处
    Python中的数据结构---栈,队列
    手写call方法
    移动零元素--leetcode题解总结
    剑指 Offer 36. 二叉搜索树与双向链表
  • 原文地址:https://www.cnblogs.com/zyore2013/p/5815941.html
Copyright © 2011-2022 走看看