完善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,还请与我交流,共同提高。
完善GDAL与OpenCV间的数据格式转换与影像分块读写的更多相关文章
- zw版【转发·台湾nvp系列Delphi例程】Delphi 使用 HALCON库件COM控件数据格式转换
zw版[转发·台湾nvp系列Delphi例程]Delphi 使用 HALCON库件COM控件数据格式转换 Delphi 使用 HALCON库件COM控件数据格式转换,与IHObjectX接口有关 va ...
- Java将其他数据格式转换成json字符串格式
package com.wangbo.util; import java.beans.IntrospectionException; import java.beans.Introspector; i ...
- JAVA线程间的状态转换
线程间的状态转换: 1. 新建(new):新创建了一个线程对象. 2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法.该状态的线程位于可运 ...
- 页面输入的数据格式转换类:BaseAction(经常使用于Struts框架中)
在我们接收页面传来的数据时,这些数据都是以String类型接收的,所以要进行数据格式转换,这时候就能够统一为它们进行转换,并且在处理这些数据的类中能够继承ActionSupport类,然后让每个接收数 ...
- SBC数据格式转换软件
北京博信施科技有限公司是一家专业从事数据格式转换.数据处理领域研发软件产品和解决方案实施的技术型公司.在当今信息时代,PDF文档格式是在Internet上进行电子文档发行和数字化信息传播的理想文档格式 ...
- Java 整数型的进制间的互相转换
/** * 整数型, 进制间的互相转换 */ public class IntConversion { public static void main(String[] args) { int num ...
- mfc 类型间的强制转换
一. static_cast运算符 用法:static_cast < type-id > ( expression ) 该运算符把expression 转换为type-id类型,但没有运行 ...
- 【C#/WPF】图像数据格式转换时,透明度丢失的问题
问题:工作中涉及到图像的数据类型转换,经常转着转着发现,到了哪一步图像的透明度丢失了! 例如,Bitmap转BitmapImage的经典代码如下: public static BitmapImage ...
- 【转】C语言中不同的结构体类型的指针间的强制转换详解
C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险.只要理解了其内部机制,你会发现C是非常灵活的. 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在 ...
随机推荐
- SQL通用函数-nvl-nvl2 -nvlif-nullif-coalesce-decode-case
通用函数适用于任何类型数据(包括空值),一般用于实现空值处理.条件运算和多路分支结果,下面介绍其中常用的几种: nvl(exp1, exp2) 函数nvl(exp1, exp2)用于将空值转换为指定的 ...
- HTML与CSS入门——第五章 使用文本块和列表
知识点: 1.在页面上对齐文本的方法 2.三种HTML列表的使用方法 3.在列表中放置列表的方法 5.1 在页面上对齐文本: 父元素内子元素文本的居中:在控制父元素的text-align:center ...
- C#异步编程的实现方式——ThreadPool线程池
在需要创建的线程很多,且都是比较小的线程的情况下,可以使用线程池(ThreadPool类).ThreadPool是一个静态方法,提供了对一个线程集合的操作,它会在线程数不足时增加线程,空闲线程数过多时 ...
- 安装XP和Ubuntu双系统问题——Ubuntu安装时无法识别原有系统
我主机本来安装了windows xp 和unbuntu15.04,由于在ubuntu下不小心卸载某依赖后,无法登入桌面,网上查了好多资料,原因各种,解决途径也各种,最终是还没有解决问题.各种更新,各种 ...
- x++ and ++x
http://blog.sina.com.cn/s/blog_6c762bb30101ar1w.html 看到个东西,搞不清的时候可以看看 =.=
- 概率dp小结
好久之前学过,记得是一次亚洲区的前几天看了看概率dp,然后亚洲区就出了一道概率dp,当时虽然做上了,但是感觉有很多地方没懂,今天起早温习了一下,觉得很多地方茅塞顿开,果然学习的话早上效果最好了. 首先 ...
- ZOJ3551 Bloodsucker(概率dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Bloodsucker Time Limit: 2 Seconds Me ...
- 安卓仿制新浪微博(一)之OAuth2授权接口
这里需要用到请求授权(authorize)以及获取授权(access_token) 第一步: 将新浪的sdk放在src/libs下面 二: //创建方法实现authorize public void ...
- NGINX和PHP之间的环境变量传递
昨天遇到的,想将IP访问转换成域名访问.则NGINX需要将相关的变量转换后传递给PHP. 网上有一系统的方法: 前面讲过该不该把信息写在服务器配置文件里?.通过php扩展hidef来define常量, ...
- 关于iostream的效率问题
前言 经常有人说iostream的速度慢,IO流比stdio的慢多了.但是有人测试过的,iostream的速度是超过stdio的. 测试结果 /* C */#include <stdio. ...