因为做任务时发现opencv只是支持部分Tiff文件格式,对于GeoTiff这样带有投影和坐标信息的遥感栅格影像总是读不出来,输出时这些信息也会消失。搜网上的解决方法大多都是基于早期的IplImage与CvMat数据结构来表示图像,新版本的opencv中只需Mat类就能解决。本人是菜鸟,对OpenCV接触不多,所以就利用GDAL函数库作中介对图像进行读写,并赋给Mat矩阵。这是比较简单的方法将GeoTiff遥感图像转化为Mat格式,即只是希望能够其他遇到这个问题的人能够有所参考和改进,顺便告诉下我,本人感激不尽。参考网址:http://blog.csdn.net/liminlu0314/article/details/7433936
这段代码使用了GDAL(1.10.1)与OpenCV(2.4.8)两个函数库,只是针对单个波段的影像而言:
#include "gdal_priv.h" #include //单个波段影像而言 Mat ConvertImage2CV(const char *pszRasterFile) { //为了支持中文路径,请添加下面这句代码 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //注册栅格驱动 GDALAllRegister(); GDALDataset *poRaDS=(GDALDataset*)GDALOpen(pszRasterFile,GA_ReadOnly);//以只读方式打开遥感图像 if (poRaDS==NULL) printf("文件: %s打开失败.\n",pszRasterFile); GDALRasterBand *poband=poRaDS->GetRasterBand(1); int nBandCount=poRaDS->GetRasterCount(); int ImageLength=poRaDS->GetRasterXSize(); int ImageWidth=poRaDS->GetRasterYSize(); DT_16U *pRaData=new DT_16U[ImageLength]; if (nBandCount!=1) printf("掩膜文件存在多个波段,检查输入是否有误\n"); Mat MaskIM(ImageWidth,ImageLength,CV_16UC1,Scalar(0)); //遍历所有像素,并赋值 for (int i=0;iRasterIO(GF_Read,0,i,ImageLength,1,pRaData,ImageLength,1,GDT_UInt16, 0, 0); for (int j=0;j(i,j)=pRaData[j]; } } //别忘记释放 RELEASE(pRaData); GDALClose((GDALDatasetH)poRaDS); return MaskIM; } //单个波段影像而言 int SaveMat2Image(Mat &MaskIM,GDALDataset *poReferIM,const char *pszRasterFile,const char* pszFormat ) { int XSize=MaskIM->cols;//获得输出对象大小 int YSize=MaskIM->rows; //为了支持中文路径,请添加下面这句代码 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //注册栅格驱动 GDALAllRegister(); GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); if( poDriver == NULL ) { printf("不能创建制定类型的文件,请检查该文件类型GDAL是否支持创建!"); return RE_FILENOTSUPPORT; } //假设输入图像也是16U的数据 ,1个波段 GDALDataset *poRasterDS = poDriver->Create(pszRasterFile, XSize, YSize, 1, GDT_UInt16, NULL); double dGeoTrans[6] = {0}; //设置仿射变换参数 poReferIM->GetGeoTransform(dGeoTrans); poRasterDS->SetGeoTransform(dGeoTrans); //设置图像投影信息 poRasterDS->SetProjection(poReferIM->GetProjectionRef()); GDALRasterBand *poband=poRasterDS->GetRasterBand(1); DT_16U *pRaData=new DT_16U[XSize]; for (int i=0;irows;i++) { for (int j=0;jcols;j++) { pRaData[j]=MaskIM->at(i,j); } poband->RasterIO(GF_Write,0,i,XSize,1,pRaData,XSize,1,GDT_UInt16, 0, 0); } printf("Mat存储为影像成功\n"); RELEASE(pRaData); GDALClose((GDALDatasetH)poRasterDS); return RE_SUCCESS; } int main(int argc,char **argv) { GDALDataset *poImageDS=ReadImageFile(); const char *pszRaReadFile="D:\\Documents\\ExerciseData\\Mask.tif"; Mat MaskIM=ConvertImage2CV(pszRaReadFile); //poImageDS影像提供投影和坐标信息,Format为输出格式 const char *pszSaveRaFile="D:\\Documents\\ExerciseData\\MaskMat.tif"; const char* pszFormat="GTiff"; int z=SaveMat2Image(MaskIM,poImageDS,pszSaveRaFile,pszFormat); if (z==RE_SUCCESS) printf("输出文件成功\n"); else { printf("输出文件失败\n"); return 0; } GDALClose((GDALDatasetH)poImageDS); return 1; }
经过编译运行后是成功的。