基于光谱角距离的遥感影像监督分类C++实现

在遥感影像处理中,影像分类是将影像中的每个像素根据其光谱特征划分到不同的地物类别中。监督分类是指利用已知类别样本的的光谱信息,对未知类别像素进行分类。

光谱角距离(Spectral Angle Mapper, SAM)是一种常用的监督分类方法,它将像素的光谱信息视为多维向量,并通过计算两个向量之间的夹角来衡量它们之间的相似度。

代码实现

以下是基于光谱角距离的遥感影像监督分类C++实现代码:

void CSupervised::SpectralAngle(int Rows, int Cols, int Bands, int number, float AverageValue[][200], LPSTR *pPointer)
{
    float *Gray = new float[number];
    float *Distance = new float[number];
    unsigned char *array = new unsigned char[Rows*Cols];

    float min;
    CFile g;

    CString filename;
    filename = 'spectral_angle_class'; //文件储存位置

    if (!g.Open(filename, CFile::modeCreate | CFile::modeWrite))
    {
        AfxMessageBox('输出文件打开失败!', MB_ICONHAND);
        return;
    }

    //计算参考光谱的几何平均向量
    float *reference = new float[Bands];
    for (int i = 0; i < Bands; i++)
    {
        float sum = 0;
        for (int j = 0; j < number; j++)
        {
            sum += AverageValue[j][i];
        }
        reference[i] = pow(sum / number, 1.0 / Bands);
    }

    //对每个像素进行处理
    for (int data = 0; data < Rows*Cols; data++)
    {
        //数组清零便于计算
        for (int k = 0; k < number; k++)
        {
            Gray[k] = 0;
            Distance[k] = 0;
        }
        //计算结果进行分类    (计算各个点到样本区的距离)

        min = 100000;
        for (int i = 0; i < number; i++)
        {
            /////////////////////////光谱角距离////////////////////////
            float numerator = 0, denominator1 = 0, denominator2 = 0;
            for (int j = 0; j < Bands; j++)
            {
                numerator += (*pPointer[j] * AverageValue[i][j]);
                denominator1 += pow(*pPointer[j], 2);
                denominator2 += pow(AverageValue[i][j], 2);
            }
            Distance[i] = acos(numerator / (sqrt(denominator1)*sqrt(denominator2)));
            ///////////////////////////////////////////////////////////

            //根据阈值进行分类
            float threshold = 0.1; //设定阈值
            if (Distance[i] <= threshold)
            {
                //计算未知像元与参考光谱的夹角
                float numerator_ref = 0, denominator1_ref = 0, denominator2_ref = 0;
                for (int j = 0; j < Bands; j++)
                {
                    numerator_ref += (*pPointer[j] * reference[j]);
                    denominator1_ref += pow(*pPointer[j], 2);
                    denominator2_ref += pow(reference[j], 2);
                }
                float ref_angle = acos(numerator_ref / (sqrt(denominator1_ref)*sqrt(denominator2_ref)));
                if (ref_angle < Distance[i])
                {
                    array[data] = i + 1; //分类
                    break;
                }
            }

            if (Distance[i] <= min)
                min = Distance[i];
        }

        //比较距离,进行分类
        for (int n = 0; n < number; n++)
        {
            if (min == Distance[n])
            {
                array[data] = n + 1;
            }
        }

        //循环一次,指针移动一位
        for (int ban = 0; ban < Bands; ban++)
        {
            pPointer[ban]++;
        }
    }
    //进行图像的写入
    g.Write(array, Rows*Cols);
    delete[] Gray;
    delete[] Distance;
    delete[] array;
    delete[] reference;

    g.Close();
    AfxMessageBox('光谱角分类数据处理完毕!');
}

代码说明

  • 函数SpectralAngle实现了基于光谱角距离的监督分类算法。
  • 函数参数:
    • Rows, Cols: 影像的行数和列数
    • Bands: 影像的波段数
    • number: 类别数
    • AverageValue: 存储每个类别样本的平均光谱向量
    • pPointer: 指向输入影像数据的指针数组
  • 函数首先计算每个类别样本的几何平均向量,作为参考光谱。
  • 然后遍历每个像素,计算该像素与每个类别参考光谱之间的光谱角距离。
  • 如果某个类别的光谱角距离小于设定的阈值,则计算该像素与该类别参考光谱之间的夹角。
  • 如果该夹角小于该像素与其他类别参考光谱之间的夹角,则将该像素分类到该类别中。
  • 最后将分类结果写入文件。

总结

光谱角距离是一种简单有效的监督分类方法,在遥感影像分类中得到广泛应用。本文介绍了如何使用C++实现基于光谱角距离的遥感影像监督分类算法,并提供了完整的代码示例。希望对您有所帮助。


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

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