C++ 使用 GDAL 计算并保存 NDVI 图像

本篇文章将介绍如何使用 C++ 和 GDAL 库计算 NDVI (归一化差异植被指数),并将结果保存为新的图像文件。

1. 计算 NDVI

NDVI 是一个常用的植被指数,用于反映植被的生长状况。其计算公式如下:

NDVI = (NIR - RED) / (NIR + RED)

其中,NIR 为近红外波段的反射率,RED 为红光波段的反射率。

2. 使用 GDAL 计算 NDVI

GDAL 是一个开源的地理空间数据抽象库,可以用于读取和处理多种栅格和矢量数据格式。

以下代码展示了如何使用 GDAL 库计算 NDVI:

void CBandMath::NDVICal(CString pathName, int bands, int width, int height, int dataType)
{
    // 计算 NDVI
    // ...

    // 将结果保存为一个新的图像文件
    CString newPathName = pathName.Left(pathName.ReverseFind('.')) + '_ndvi.tif';
    GDALDriver *pDriver = GetGDALDriverManager()->GetDriverByName('GTiff');
    GDALDataset *pDataset = pDriver->Create(newPathName, width, height, 1, dataType, NULL);
    GDALRasterBand *pBand = pDataset->GetRasterBand(1);
    pBand->RasterIO(GF_Write, 0, 0, width, height, resultData, width, height, dataType, 0, 0);
    pDataset->FlushCache();
    GDALClose(pDataset);
}

在上面的代码中,首先计算 NDVI,然后将结果保存为一个新的图像文件。新的文件名是在原始文件名的基础上添加了 '_ndvi' 后缀。使用 GDAL 库中的函数可以创建一个新的 GDAL 数据集,并将结果数据写入到其中。最后,关闭数据集并刷新缓存。

3. 示例

以下是一个完整的示例代码,展示了如何打开一个图像文件,计算 NDVI,并将结果保存为一个新的图像文件:

#include <gdal_priv.h>

// ...

void CBsqViewView::OnNdvi()
{
    // ...

    CBandMath fBandsMath;
    fBandsMath.NDVICal(m_pathname, Bands, Width, Height, dataType);
}

void CBandMath::NDVICal(CString pathName, int bands, int width, int height, int dataType)
{
    // 打开图像文件
    GDALDataset *pDataset = (GDALDataset *)GDALOpen(pathName, GA_ReadOnly);
    if (pDataset == NULL)
    {
        // 处理错误
        return;
    }

    // 获取红光和近红外波段的数据
    GDALRasterBand *pRedBand = pDataset->GetRasterBand(1); // 假设红光波段是第一个波段
    GDALRasterBand *pNIRBand = pDataset->GetRasterBand(2); // 假设近红外波段是第二个波段

    // 分配内存存储数据
    float *pRedData = (float *)CPLMalloc(sizeof(float) * width * height);
    float *pNIRData = (float *)CPLMalloc(sizeof(float) * width * height);
    float *pNDVIData = (float *)CPLMalloc(sizeof(float) * width * height);

    // 读取数据
    pRedBand->RasterIO(GF_Read, 0, 0, width, height, pRedData, width, height, GDT_Float32, 0, 0);
    pNIRBand->RasterIO(GF_Read, 0, 0, width, height, pNIRData, width, height, GDT_Float32, 0, 0);

    // 计算 NDVI
    for (int i = 0; i < width * height; i++)
    {
        if (pRedData[i] + pNIRData[i] != 0)
        {
            pNDVIData[i] = (pNIRData[i] - pRedData[i]) / (pNIRData[i] + pRedData[i]);
        }
        else
        {
            pNDVIData[i] = 0;
        }
    }

    // 将结果保存为一个新的图像文件
    CString newPathName = pathName.Left(pathName.ReverseFind('.')) + '_ndvi.tif';
    GDALDriver *pDriver = GetGDALDriverManager()->GetDriverByName('GTiff');
    GDALDataset *pNewDataset = pDriver->Create(newPathName, width, height, 1, GDT_Float32, NULL);
    GDALRasterBand *pNewBand = pNewDataset->GetRasterBand(1);
    pNewBand->RasterIO(GF_Write, 0, 0, width, height, pNDVIData, width, height, GDT_Float32, 0, 0);

    // 释放内存
    CPLFree(pRedData);
    CPLFree(pNIRData);
    CPLFree(pNDVIData);

    // 关闭数据集
    GDALClose(pDataset);
    GDALClose(pNewDataset);
}

4. 总结

本文介绍了如何使用 C++ 和 GDAL 库计算 NDVI,并将结果保存为新的图像文件。GDAL 提供了丰富的功能,可以方便地处理各种地理空间数据。

C++ 使用 GDAL 计算并保存 NDVI 图像

原文地址: https://www.cveoy.top/t/topic/jlr1 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录