您的位置 首页 > 数码极客

如何读tif卡、如何将图片转为tif

OpenCV实现了很多图像处理中的算法,极大的降低了我们研究中码代码的工作量,可以把更多的精力放在算法设计上。

Mat是OpenCV中最常见的数据格式,可以直接用imread函数将图像数据读取并存储为Mat格式。Mat型图像矩阵可以直接应用于OpenCV的大多数算法,例如图像形态学操作、行列号访问像素、仿射变换等。

最近在研究中,我需要读取一些多波段的tiff影像,OpenCV读取tiff的时候,有个波段数≤4的限制,这个在面对多光谱数据的时候,有点不方便。一开始我是将多波段的tiff用ENVI分成多个4波段的tiff文件导出,再多次读取,也将就着完成了研究需求。不过实现方法着实麻烦,也很不优雅。

在完成了研究所需后,再返回来看这个问题本身。我需要的是将多波段的tiff读取为Mat格式。OpenCV不能读取多波段tiff,但是GDAL可以。那我可不可以写个函数,就是用GDAL读取多波段tiff,然后输出给Mat呢?

想法有了,下面就是面向搜索引擎的编程环节了。

网上看了一圈,大概思路是GDAL循环读取tiff的每个波段,然后每个波段存储为一个单波段的Mat,然后存入vector,最后返回一个成员数量与tiff波段数相同的Mat型vector。

这边有个大佬写的特别好,也很详细,不过我还没细啃,我的代码与大佬的相比,相当于从跑车上获得灵感然后造了个自行车。这边是大佬的博客链接:

下面是我的代码,定义了一个函数,并读取一张landsat8影像作为测试:

#include <iostream> #include <vector> #include <opencv2; #include <gdal_; using namespace std; using namespace cv; //gdal读取tiff,转为Mat型Vector,并获取图像左上角坐标与分辨率 vector<Mat> ReadTiffAsMatVector(const char* in_tiff_img, double& map_tie_point_x , double& map_tie_point_y, double& map_pixel_size) { //读取数据千万记得查看数据类型 /***********************************************************/ // 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 /***********************************************************/ //注册驱动 GDALAllRegister(); //读取tiff图像 GDALDataset* in_tiff_dataset = (GDALDataset*)GDALOpen(in_tiff_img, GA_ReadOnly); // GDAL数据集 //获取行列数、图像左上角坐标、分辨率、波段数等基本信息 int col_num = in_tiff_dataset->GetRasterXSize(); // 列 int rol_num = in_tiff_dataset->GetRasterYSize(); // 行 int band_num = in_tiff_dataset->GetRasterCount();//波段数 double* tiff_img_geoTransform = new double[6]; in_tiff_dataset->GetGeoTransform(tiff_img_geoTransform); map_tie_point_x = tiff_img_geoTransform[0]; map_tie_point_y = tiff_img_geoTransform[3]; map_pixel_size = tiff_img_geoTransform[1]; // Mat型容器,每个元素用于存储一个波段的数据 vector <Mat>img_mat_vector; // 读取每个波段的数据,注意数据类型 unsigned int* tiff_img_band_mat; // 循环读取每个波段 for (int current_band_num = 0; current_band_num < band_num; current_band_num++) { //读取第GDAL波段数从1开始 GDALRasterBand* tiff_img_band_data = in_tiff_dataset->GetRasterBand(current_band_num + 1); tiff_img_band_mat = new unsigned int[col_num * rol_num]; //读取数据 tiff_img_band_data->RasterIO(GF_Read, 0, 0, col_num, rol_num, tiff_img_band_mat, col_num, rol_num, GDT_UInt16, 0, 0); //转为Mat Mat band_mat_temp = Mat(rol_num, col_num, CV_16U, tiff_img_band_mat); //存入容器 img_ma()); delete[]tiff_img_band_data; band_ma(); } return img_mat_vector; } int main() { //新建存放数据的容器 vector<Mat> cls_img_band_vector; //新建用于接收图像左上角坐标与分辨率的变量 double cls_img_tie_point_x, cls_img_tie_point_y, cls_img_pixel_size; //调用函数读取数据 cls_img_band_vector = ReadTiffAsMatVector("land;, cls_img_tie_point_x, cls_img_tie_point_y, cls_img_pixel_size); cout << "读取的tiff波段数为:" << cl() << endl; cout << "图像左上角坐标为:" << cls_img_tie_point_x <<","<< cls_img_tie_point_y <<endl; cout << "图像分辨率为:" << cls_img_pixel_size << endl; //将读取的landsat8的RBG波段融合为mat,注意OpenCV的波段顺序为B、G、R vector<Mat> out_img_mat(3); out_img_mat[0] = cls_img_band_vector[2]; out_img_mat[1] = cls_img_band_vector[3]; out_img_mat[2] = cls_img_band_vector[4]; Mat out_img; merge(out_img_mat, out_img); //显示 namedWindow("测试", 0); resizeWindow("测试", 640, 640); imshow("测试", out_img); waitKey(36000); return 0; }

结果如图



#科技萌新成长营##编程##OpenCV#

注意事项:注意GDAL与OpenCV的数据格式对应,以及OpenCV的波段顺序B、G、R。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“如何读tif卡,如何将图片转为tif,如何打开tif文件,如何打开tif,如何编辑tif图片”边界阅读