目前在研究高光谱图像处理。与普通图像不同,高光谱图像是多波段的图像,而OPENCV只能直接处理至多3维的图像,所以要依赖GDAL库来处理高光谱图像。思路就是:根据文件名获得其GDALDataset数据集,然后分波段(波段相当于通道)存储在格式为Vector<cv::Mat>的容器内,最后利用MAT的Merge函数,对通道数据进行组合。以上方法适合任意波段数据,对多光谱和高光谱数据比较实用。
#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <gdal.h> #include <gdal_priv.h> #include <gdal_alg.h> #include <highgui.h> #include <vector> using namespace cv; using namespace std; cv::Mat GDAL2Mat(const char* fileName) { GDALAllRegister(); GDALDataset *poDataset = (GDALDataset *)GDALOpen(fileName,GA_ReadOnly); // GDAL数据集 int Cols = poDataset->GetRasterXSize(); // 列 int Rows = poDataset->GetRasterYSize(); // 行 int BandSize = poDataset->GetRasterCount();//波段数 double *adfGeoTransform = new double[6]; poDataset->GetGeoTransform(adfGeoTransform); std::vector <cv::Mat>imgMat; // 定义元素为Mat的vecoter向量,向量的每一个元素存储一个波段的数据 float *pafScan; // 存储数据 for(int i = 0;i< BandSize;i++) { GDALRasterBand *pBand = poDataset->GetRasterBand(i+1);//读取第i+1个波段的数据 pafScan = new float[Cols*Rows]; pBand->RasterIO(GF_Read,0,0,Cols,Rows,pafScan, Cols,Rows,GDT_Float32,0,0);//将第i+1个波段的数据存入pafScan cv::Mat A = cv::Mat(Rows,Cols,CV_32FC1,pafScan);//将第i+1个波段的数据存存入A中 imgMat.push_back(A.clone()); delete []pBand; A.release(); } delete []pafScan; cv::Mat img; img.create(Rows,Cols,CV_32FC(BandSize)); merge(imgMat,img); // GDALClose((GDALDatasetH)poDataset); imgMat.clear(); return img; } int main() { Mat img; vector<Mat> band; img=GDAL2Mat("E:/raw.tif");//img中含有所有波段的数据 split(img,band);//将img拆分成单个波段存储在band中 cvNamedWindow("window1",CV_WINDOW_AUTOSIZE); imshow("window1",band[0]/100); cvWaitKey(0); band.clear(); cvDestroyWindow("window1"); img.release(); return 0; }