GDAL多光谱与全色图像融合简单使用

2023-11-20

目录

简述

最近在GDAL的代码中看见了gdalpansharpen.cpp,于是简单的尝试了一下。

融合后的效果比较差,这应该是我对这个算法的使用还不熟悉,还有些地方没有弄清楚。这个代码比较新,是2.1版本才加上的,我在看的时候,代码还有一些小问题,已经在github上提交了issuse了。

融合使用的数据是我在网上找到的高分一号的一景数据,先做了校正,形成全色波段TIFF(单波段)多光谱波段TIFF(4波段)

相关知识参考:
遥感影像的“全色”与“多光谱”
高分一号(GF-1)卫星影像数据介绍
国内遥感卫星资源综述
高分一号影像处理流程
遥感影像融合方法(英文)
ENVI 遥感图像融合
为何全色影像分辨率高于多光谱影像分辨率

C++代码

代码基于当前https://github.com/OSGeo/gdal仓库的master分支构建。

// g++ gdal_pansharpen.cpp -o gdal_pansharpen -I../include -L../lib -lgdal

#include <gdalpansharpen.h>
#include <cpl_auto_close.h>
#include <cpl_error.h>

int main()
{
    GDALAllRegister();
    // 打开全色波段(高分辨率)文件
    GDALDatasetH hPanDset = GDALOpen("/mnt/data/GF1_PMS2_E116.5_N39.6_20130501_L1A0000127213-PAN2_rpc.tiff",GA_ReadOnly);
    CPL_AUTO_CLOSE_WARP(hPanDset,GDALClose);
    VALIDATE_POINTER1(hPanDset,"Open Pansharpen file failed",1);
    // 打开多光谱(低分辨率)文件
    GDALDatasetH hMssDset = GDALOpen("/mnt/data/GF1_PMS2_E116.5_N39.6_20130501_L1A0000127213-MSS2_rpc.tiff",GA_ReadOnly);
    CPL_AUTO_CLOSE_WARP(hMssDset,GDALClose);
    VALIDATE_POINTER1(hPanDset,"Open Spectral Band file failed",1);
    int nSpectralBands = GDALGetRasterCount(hMssDset);

    GDALPansharpenOptions opts;
    opts.ePansharpenAlg = GDAL_PSH_WEIGHTED_BROVEY;     // 超分辨率贝叶斯法,当前仅支持brovery加权
    opts.eResampleAlg    = GRIORA_Cubic;                 // 重采样至全色光谱波段分辨率的算法
    opts.nBitDepth     = 0;                            // 多光谱波段位深度,0表示默认
    opts.nWeightCount    = nSpectralBands;               // 权重系数数组元素个数(与输入多光谱波段数一致)
    double* pWeightCount= static_cast<double*>(
        CPLMalloc(opts.nWeightCount * sizeof(double))); // 权重系数数组
    CPL_AUTO_CLOSE_WARP(pWeightCount,CPLFree);
    opts.padfWeights = pWeightCount;
    opts.padfWeights[0] = 0.334;    // 蓝
    opts.padfWeights[1] = 0.333;    // 绿
    opts.padfWeights[2] = 0.333;    // 红
    opts.padfWeights[3] = 0.0;        // 近红外

    // 设置全色波段(高分辨率)
    opts.hPanchroBand = GDALGetRasterBand(hPanDset,1);
    // 设置多光谱波段
    opts.nInputSpectralBands = nSpectralBands;
    GDALRasterBandH* pInputSpectralBands = static_cast<GDALRasterBandH*>(
        CPLMalloc(sizeof(GDALRasterBandH) * nSpectralBands));
    CPL_AUTO_CLOSE_WARP(pInputSpectralBands,CPLFree);
    opts.pahInputSpectralBands = pInputSpectralBands;
    // std::generatr
    for(int i=0;i< nSpectralBands;++i) {
        opts.pahInputSpectralBands[i] = GDALGetRasterBand(hMssDset,i+1);
    }
    // 设置需要输出到全色波段分辨率的波段
    opts.nOutPansharpenedBands = 4;
    // 这个数组里面存的是pahInputSpectralBands里波段的索引值
    int panOutPansharpenedBands[4] = { 2, 1, 0, 3}; // 红、绿、蓝、近红外
    opts.panOutPansharpenedBands = panOutPansharpenedBands;

    opts.bHasNoData = FALSE;   // 全色和多光谱波段是否具有无效值(NoData值)
    opts.dfNoData   = 0.0;     // 全色和多光谱波段的无效值,也将作为输出的NoData值
    opts.nThreads   = -1;      // 使用的线程数,-1表示使用CPU线程数
    // 设置多光谱波段与全色波段在像素上的移位(保证地理空间位置对齐)
    // 都是相对于全色波段的0,0像素的像素(全色波段像素大小)偏移
    // 也就是两者的0,0像素的地理空间上的偏移量在全色波段分辨率相应的像素数
    double adfGTPan[6];
    GDALGetGeoTransform(hPanDset,adfGTPan);
    double adfGTMss[6];
    GDALGetGeoTransform(hPanDset,adfGTMss);
    opts.dfMSShiftX = (adfGTPan[0] - adfGTMss[0]) / adfGTPan[1];
    opts.dfMSShiftY = (adfGTPan[3] - adfGTMss[3]) / adfGTPan[5];

    GDALPansharpenOperation operation;
    CPLErr err = operation.Initialize(&opts);
    if(err != CE_None) {
        return -2;
    }
    // 创建输出文件(和全色波段一样大)
    int nOutXSize, nOutYSize;
    nOutXSize = GDALGetRasterBandXSize(opts.hPanchroBand);
    nOutYSize = GDALGetRasterBandYSize(opts.hPanchroBand);
    GDALDataType eBufDataType = GDALGetRasterDataType(opts.pahInputSpectralBands[0]);
    eBufDataType = GDT_Float64;
    GDALDriverH hDriver = GDALGetDriverByName("GTiff");
    CPLStringList CreateOption;
    CreateOption.AddNameValue("TILED", "YES");
    CreateOption.AddNameValue("BIGTIFF", "YES");
    CreateOption.AddNameValue("INTERLEAVE", "BAND");
    CreateOption.AddNameValue("COMPRESS", "LZW");   // 中度压缩
    CreateOption.AddNameValue("ZLEVEL", "6");

    GDALDatasetH hOutDset = GDALCreate(hDriver,
                "/mnt/data/GF1_PMS2_E116.5_N39.6_20130501_L1A0000127213.tif",
                nOutXSize, nOutYSize, nSpectralBands, GDT_UInt16,
                CreateOption);
    CPL_AUTO_CLOSE_WARP(hOutDset,GDALClose);
    VALIDATE_POINTER1(hOutDset,"Create Output file error", -3);

    GDALSetGeoTransform(hOutDset, adfGTPan);
    GDALSetProjection(hOutDset,GDALGetProjectionRef(hPanDset));

     void* pData = CPLMalloc(256*256*GDALGetDataTypeSizeBytes(eBufDataType)*nSpectralBands);
     CPL_AUTO_CLOSE_WARP(pData,CPLFree);

    for(int nYOff = 0; nYOff < nOutYSize; nYOff += 256) {
        for(int nXOff = 0; nXOff < nOutXSize; nXOff += 256) {
            int nXSize = std::min(nOutXSize - nXOff,256);
            int nYSize = std::min(nOutYSize - nYOff,256);
            printf("Process[%6d,%6d,%6d,%6d]\r",nXOff,nYOff,nXOff+nXSize,nYOff+nYSize);

            err = operation.ProcessRegion(nXOff,nYOff,nXSize,nYSize,pData,eBufDataType);
            if(err == CE_Failure) {
                CPLError(err,CPLE_AppDefined,"operation.ProcessRegion");
                return -4;
            }
            int panBandMap[4] = { 1, 2, 3, 4};
            err = GDALDatasetRasterIO(hOutDset, GF_Write,
                        nXOff,nYOff,nXSize,nYSize,
                        pData,nXSize,nYSize,
                        eBufDataType,
                        4,panBandMap,
                        0,0,nXSize*nYSize*GDALGetDataTypeSizeBytes(eBufDataType));
        }
    }
    puts("\nPansharpen finished");

    return 0;
}

效果对比

GDAL融合效果和原始多光谱波段对比

GDAL融合效果和原始多光谱波段对比

GDAL融合效果和原始全色波段对比

GDAL融合效果和原始全色波段对比

ARCGIS融合效果与原始全色和多光谱对比

693958-20181123105312637-428434967.png

ArcGIS融合过程使用工具箱-->系统工具箱-->Data Management Tools-->栅格-->栅格处理-->创建全色锐化的栅格数据集

ARCGIS融合效果与原始全色

左边ArcGIS融合效果,右边原始多光谱影像
ARCGIS融合效果与原始多光谱

GDAL融合效果与ArcGIS融合效果对比

左边GDAL融合效果,右边ArcGIS融合效果
693958-20181123105147579-562638217.png

左边ArcGIS融合效果,右边GDAL融合效果
693958-20181123105137141-1388044375.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GDAL多光谱与全色图像融合简单使用 的相关文章

随机推荐

  • 网络流量在线分析系统的设计与实现

    编译环境 visual studio2019 安装并配置winpcap和pthreads库函数 1 配置环境 1 1 安装vscode 参考微信公众号 软件安装管家 1 2 安装MinGW w64 下载地址 添加链接描述 安装参考博客 Mi
  • 实验二 程序流程控制

    1 编写程序计算 1 3 5 7 99 之和 summ 0 for i in range 1 100 summ summ i print 和为 summ 2 编写程序 计算 2 4 6 8 100 之和 summ 0 for i in ra
  • 计算机网络试题

    一 选择题 1 OSI模型与TCP IP模型都具有的层次是 A 会话层 网络层和物理层 B 表示层 会话层和数据链路层 C 网络层 传输层和应用层 D 表示层 数据链路层和物理层 2 对于计算机网络体系结构 下列关于第N层和第N 1层的关系
  • 蓝桥杯:字符串

    题目链接 include
  • notepad++字符串替换

    删除空白行 在编辑选项里面包括很多功能 编辑 gt 行操作 gt 移除空行 包括空白字符 行首添加字符串 按CTRL F 选择替换页签 选择正则表达式 查找目标 设置为 替换为 设置自己想要替换的字符串 特殊字符需要添加 进行转义 行尾添加
  • 【MySQL】34道SQL综合练习详解(员工表、部门表、工资等级表)

    文章目录 一 34道SQL综合练习 二 测试使用的数据表 三 创建测试表的SQL语句 一 34道SQL综合练习 1 查询取得每个部门最高工资的人员信息 select e ename t from emp e join select dept
  • 如何使用PCL将XYZRGB点云转换为彩色mesh模型

    如何使用PCL将XYZRGB点云转换为彩色mesh模型 最近完成了一个使用RGBD传感器 构建物体模型的小demo 其中有点难的最后一步是如何将获得的物体点云变成彩色mesh模型 效果图如下 从点云变成彩色mesh 其实整体的步骤可以总结如
  • M1 macbook上安装docker 编译内核 并使用qemu启动内核。

    一 编译内核并通过qemu启动内核 1 在M1上安装docker这个就不用提供步骤了 网上自行搜索 2 在M1上pull一个ubuntu的容器 docker pull ubuntu 18 04 docker images REPOSITOR
  • 卡尔曼滤波及其MATLAB程序

    今天写了个卡尔曼滤波的小程序 希望对有需要的同学有点帮助 卡尔曼滤波是一个很常用的滤波算法 与维纳滤波相比有很多长处 这里我们把Kalman Filter简称为KF KF的基本思想是 采用信号 噪声 状态空间模型 利用前一时刻的状态最优估计
  • 学习python笔记01

    一 python是什么 人生苦短 我用python python是一门解释型语言 边解释边运行 与编译型语言的区别是 编译型语言是先编译后运行 python语言的特点 1 优雅 2 明确 3 简单 python是一个完全面向对象语言 具有强
  • 纯java实现相片转素描

    1 实例演示图片转素描效果 首先我们来看一下具体的效果 在项目中添加依赖
  • unity制作一个可以自由滑动收缩的历史记录功能。

    公司在做一款模拟经营类的卖车游戏 需要一个简单的历史记录功能 放在左上角 记录最近20条的收入 支出记录 超过2秒不动则收起 收起时展示最近的一个消息记录 用到的组件是ScrollView 使用方法可以参考我写过的一篇博客 ScrollVi
  • Input.GetAxis _ Unity3d

    Input GetAxis 获取轴 static function GetAxis axisName string float Description描述 Returns the value of the virtual axis iden
  • 【论文精读】时序逻辑应用之模型预测控制Model Predictive Control with Signal Temporal Logic Specifications

    前言 因为天天写代码实在是太枯燥了 所以读点其他东西来调剂一下 这样科研进度不至于停下 前面读了几篇关于时序逻辑学习的文章 今天来了解一下时序逻辑公式在控制中的应用 Raman V Donze A Maasoumy M Murray R M
  • Android Studio编译失败问题(aapt2)

    Android Studio 3 1编译时出错 org gradle api tasks TaskExecutionException Execution failed for task app mergeDebugResources at
  • 心灵鸡汤

    心灵鸡汤 比尔盖茨不想弯腰去捡100美金 浪费了1秒 时间是最宝贵 有限的时间资源最大化 如果你不够优秀 人脉是不值钱的 它不是追求来的 而是吸引来的 只有等价的交换 才能得到合理的帮助 虽然听起来很冷 但这是事实 与凤凰同飞 必是俊鸟 与
  • AESCBCUtil

    import javax crypto Cipher import javax crypto spec IvParameterSpec import javax crypto spec SecretKeySpec import org ap
  • 面试必问的 CAS ,要多了解

    前言 CAS Compare and Swap 即比较并替换 实现并发算法时常用到的一种技术 Doug lea大神在java同步器中大量使用了CAS技术 鬼斧神工的实现了多线程执行的安全性 CAS的思想很简单 三个参数 一个当前内存值V 旧
  • 结构体中数组放在最后位置的问题

    以下出自 C Programming FAQS 先看下面的代码 struct name int namelen char namestr 1 struct name makename char newname struct name ret
  • GDAL多光谱与全色图像融合简单使用

    目录 简述 C 代码 效果对比 GDAL融合效果和原始多光谱波段对比 GDAL融合效果和原始全色波段对比 ARCGIS融合效果与原始全色和多光谱对比 GDAL融合效果与ArcGIS融合效果对比 简述 最近在GDAL的代码中看见了gdalpa