opencv(c++)遥感影像加载与保存
来源:互联网 发布:查看守望先锋数据 编辑:程序博客网 时间:2024/05/24 05:47
参考:
1、https://docs.opencv.org/3.2.0/d7/d73/tutorial_raster_io_gdal.html
2、http://www.cnblogs.com/zyore2013/p/4657702.html
3、http://www.cnblogs.com/zyore2013/p/5815941.html
4、http://blog.csdn.net/liminlu0314/article/details/7433936
1、使用imread加载
#include "opencv2/core.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include <iostream>using namespace std;using namespace cv;int main(){ char* img_path = "D:/14.tif"; //加载图像,这样加载没有投影信息 Mat image = imread(img_path, IMREAD_LOAD_GDAL | IMREAD_COLOR | IMREAD_ANYDEPTH); //判断是否加载成功 if (!image.data) //或者image.empty() { cout << img_path << " cannot open!" << endl; return -1; } // 输出图像大小信息 C x W x H cout << image.channels()<<" x " <<image.rows<<" x "<<image.cols<< endl; //转成灰度 Mat dst; cvtColor(image, dst, COLOR_BGR2GRAY); //显示图像 namedWindow("src", 1); namedWindow("dst", 1); imshow("src", image); imshow("dst", dst); waitKey(0); destroyAllWindows(); //保存转换的图像 imwrite("D:/14_2.tif", dst); return 0;}
注:直接使用imread加载遥感影像不会有投影信息,且只能加载不超过3波段的影像
2、结合GDAL
GDAL读取遥感图像在转成Mat,再保存
参考:
1、http://www.cnblogs.com/zyore2013/p/4657702.html
2、http://www.cnblogs.com/zyore2013/p/5815941.html
3、http://blog.csdn.net/liminlu0314/article/details/7433936
#include "opencv2/core.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include <gdal.h>#include <gdal_priv.h> #include <iostream>#include <string>#include <vector>using namespace std;using namespace cv;/*! byte */typedef unsigned char byte;/*! 8U */typedef unsigned char DT_8U;/*! 16U */typedef unsigned short DT_16U;/*! 16S */typedef short DT_16S;/*! 32U */typedef unsigned int DT_32U;/*! 32S */typedef int DT_32S;/*! 32F */typedef float DT_32F;/*! 64F */typedef double DT_64F;//创建一个存放影像信息的structuretypedef struct{ //GDALDataset *poDataset = NULL; int Xsize=0; int Ysize=0; int nbands=0; double *tmpadfGeoTransform=new double[6]; //存储地理6参数 const char* proj = NULL;//存储投影 GDALDataType iDataType = GDT_Byte;}MyStruct;cv::Mat GDAL2Mat(GDALDataset *poDataset, MyStruct &St);bool Mat2File(cv::Mat img, MyStruct &St, GDALDataset *poDataset);int main(){ //注册驱动 GDALAllRegister(); string src_path = "D:/14.tif"; string dst_path = "D:/14_2.tif"; MyStruct St; GDALDataset *poDataset = (GDALDataset *)GDALOpen(src_path.c_str(), GA_ReadOnly); St.Xsize = poDataset->GetRasterXSize(); St.Ysize = poDataset->GetRasterYSize(); St.nbands = poDataset->GetRasterCount(); poDataset->GetGeoTransform(St.tmpadfGeoTransform); St.proj = poDataset->GetProjectionRef(); //获取数据类型 St.iDataType = poDataset->GetRasterBand(1)->GetRasterDataType(); Mat img = GDAL2Mat(poDataset, St); /* //直接保存mat std::vector<cv::Mat> imgMat(St.nbands); std::vector<cv::Mat> tempMat(St.nbands); cv::split(img, imgMat); tempMat.at(0) = (imgMat.at(2));//BGR-->RGB tempMat.at(1) = (imgMat.at(1)); tempMat.at(2) = (imgMat.at(0)); Mat img2; cv::merge(tempMat, img2); imgMat.clear(); tempMat.clear(); imwrite("D:/14_3.tif", img2); */ //判断是否加载成功 if (!img.data) //或者image.empty() { cout << src_path << " cannot open!" << endl; return -1; } //定义输出数据 GDALDataset *poDataset2; //GDAL数据集 GDALDriver *poDriver; //驱动,用于创建新的文件 //poDriver = GetGDALDriverManager()->GetDriverByName("ENVI"); poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); if (poDriver == NULL) return 0; poDataset2 = poDriver->Create(dst_path.c_str(), St.Xsize, St.Ysize, St.nbands, St.iDataType, NULL);//GDT_Float32 //重新设置地理参考和投影系 poDataset2->SetGeoTransform(St.tmpadfGeoTransform); poDataset2->SetProjection(St.proj); GDALClose((GDALDatasetH)poDataset); Mat2File(img, St, poDataset2); GDALClose((GDALDatasetH)poDataset2); return 0;}//GDAL数据转opencv的Mat格式cv::Mat GDAL2Mat(GDALDataset *poDataset,MyStruct &St) //const QString fileName{ //获取数据类型 //GDALDataType iDataType = poDataset->GetRasterBand(1)->GetRasterDataType(); //int idepth = GDALGetDataTypeSize((GDALDataType)iDataType); //将GDAL的数据类型与Mat的数据类型对应起来 auto MdataType = NULL; auto MdataTypes = NULL; if (St.iDataType == GDT_Byte) { MdataType = CV_MAKETYPE(CV_8U, 1); MdataTypes= CV_MAKETYPE(CV_8U, St.nbands); } if (St.iDataType == GDT_UInt16) { MdataType = CV_MAKETYPE(CV_16U, 1); MdataTypes = CV_MAKETYPE(CV_16U, St.nbands); } //QVector <cv::Mat> imgMat; vector<Mat> imgMat;// 每个波段 float *pafScan = new float[St.Xsize*St.Ysize]; // 存储数据 for (int i = 0; i< St.nbands; i++) { GDALRasterBand *pBand = poDataset->GetRasterBand(i + 1); //pafScan = new float[tmpCols*tmpRows]; pBand->RasterIO(GF_Read, 0, 0, St.Xsize, St.Ysize, pafScan, St.Xsize, St.Ysize, St.iDataType, 0, 0); //GDT_Float32 cv::Mat tmpMat = cv::Mat(St.Ysize, St.Xsize, MdataType, pafScan);//CV_32FC1 imgMat.push_back(tmpMat.clone()); } delete[]pafScan; pafScan = NULL; cv::Mat img; img.create(St.Ysize, St.Xsize, MdataTypes); //CV_32FC(tmpBandSize) //cv::merge(imgMat.toStdVector(), img); cv::merge(imgMat, img); //释放内存 imgMat.clear(); //GDALClose((GDALDatasetH)poDataset); return img;}//Mat 数据保存bool Mat2File(cv::Mat img,MyStruct &St, GDALDataset *poDataset)//const QString fileName{ if (img.empty()) // 判断是否为空 return 0; const int nBandCount = St.nbands; const int nImgSizeX = St.Xsize; const int nImgSizeY = St.Ysize; // 将通道分开 // imgMat每个通道数据连续 std::vector<cv::Mat> imgMat(nBandCount); cv::split(img, imgMat); // 分波段写入文件 GDALAllRegister(); // 循环写入文件 GDALRasterBand *pBand = NULL; float *ppafScan = new float[nImgSizeX*nImgSizeY]; cv::Mat tmpMat;// = cv::Mat(nImgSizeY,nImgSizeX,CV_32FC1); for (int i = 1; i <= nBandCount; i++) { pBand = poDataset->GetRasterBand(i); tmpMat = imgMat.at(i - 1); if (tmpMat.isContinuous()) { if(St.iDataType==GDT_Byte) memmove(ppafScan, (void*)tmpMat.ptr(0), sizeof(unsigned char)*nImgSizeX*nImgSizeY);//GDT_Byte if(St.iDataType==GDT_UInt16) memmove(ppafScan, (void*)tmpMat.ptr(0), sizeof(unsigned short)*nImgSizeX*nImgSizeY);//GDT_Uint16 //memmove(ppafScan, (void*)tmpMat.ptr(0),sizeof(float)*nImgSizeX*nImgSizeY);//GDT_Float32 } else return false; CPLErr err = pBand->RasterIO(GF_Write, 0, 0, nImgSizeX, nImgSizeY, ppafScan, nImgSizeX, nImgSizeY, St.iDataType, 0, 0); } delete[] ppafScan; ppafScan = NULL; imgMat.clear(); //GDALClose(poDataset); return 1;}
3、使用imwrite保存
先使用GDAL与opencv将影像转成Mat,再直接使用opencv的imwrite保存Mat,只能针对不超过3波段的数据,而且保存的影像没有坐标。如果波段数不超过3,位数为8bit,推荐使用第一种方法加载图像,该方法保存;其他使用第二种方法加载图像和保存
//直接保存mat std::vector<cv::Mat> imgMat(St.nbands); std::vector<cv::Mat> tempMat(St.nbands); cv::split(img, imgMat); tempMat.at(0) = imgMat.at(2);//BGR-->RGB tempMat.at(1) = imgMat.at(1); tempMat.at(2) = imgMat.at(0); Mat img2; cv::merge(tempMat, img2); imgMat.clear(); tempMat.clear(); imwrite("D:/14_3.tif", img2);
阅读全文
0 0
- opencv(c++)遥感影像加载与保存
- opencv+GDAL 遥感影像滤波
- ArcIMS加载遥感影像解决方案
- 遥感影像的“全色”与“多光谱”
- 基于OpenCV和GDAL的遥感影像处理程序
- 【技术类】【遥感入门系列】2、遥感成像与遥感影像特征
- 利用Arcpy向Arcmap中批量加载遥感影像
- 【C/C++】超大遥感影像读取和存储 GDAL
- MFC OPENCV 加载与保存图片
- GDAL遥感影像读取与显示-vc环境
- Dem与遥感影像制作三维效果简单教程
- GDAL遥感影像读取与显示-vc环境
- 遥感影像多光谱与全色IHS融合
- 大幅面遥感影像多尺度分割与尺度转换-初探
- 遥感影像预处理
- 遥感影像几何校正
- 遥感影像命名规则
- 遥感影像几何校正
- Jzoj5462【NOIP2017提高A组冲刺11.8】证书
- android 监听
- 关于DPR2.0&DPR3.0手机上的适配问题(focusdroid)
- 达内课程-集合之ArrayList
- maven(二)maven安装
- opencv(c++)遥感影像加载与保存
- ARMCC和GCC编译ARM代码的软浮点和硬浮点问题
- 探究类加载机制
- Java读书笔记——02 基本结构
- linux-socket connect阻塞和非阻塞模式 示例
- SpringBoot学习笔记 入门
- spring源码:创建单例对象时用到了ObjectFactory匿名类
- 微信小程序图片
- 如何创建并运行 java 线程