随笔 - 934, 文章 - 0, 评论 - 249, 阅读 - 345万

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

光谱信息散度与光谱角的匹配算法(SID_SA)

Posted on   蝈蝈俊  阅读(2879)  评论(0编辑  收藏  举报

在卫星遥感技术上,对地物的识别和分类用到了SID_SA算法,即比较被测地物的光谱曲线与已有光谱数据库中光谱曲线的相似度以判断地物的类别。

这种技术在判断依赖服务是否互相影响时?即流量、吞吐量走势曲线是否相似上也可用。

光谱角度制图(Spectral angle mapping, SAM )

基于光谱曲线整体相似性的一种算法,把图像中的每个像元的光谱视为一个高维向量,通过计算两向量间的夹角来度量光谱间的相似性,夹角越小,两光谱越相似,属于同类物的可能性越大,因而可根据光谱角的大小来辨别未知数据的类别。

分类时,通过计算未知数据与已知数据间的光谱角,并把未知数据的类别归为最小光谱角对应的类别中。

假设,xy 分别代表目标光谱与测试光谱,长度都为 n1
SAM用来计算两个数组之间的相似性,其计算结果可看作两数组之间余弦角。

其中

  • 为2 条光谱间的光谱夹角值。

  • 分别为 2 条光谱向量的 模

用go语言实现的代码如下:

// 光谱角制图
func SAM(src, dst []float64) float64 {
	s := floats.Dot(src, dst)
	t := floats.Norm(src, 2) * floats.Norm(dst, 2)
	return math.Acos(s / t)
}

光谱信息散度(spectral information divergence,SID)

光谱信息散度是一种基于信息论衡量两条光谱之间差异的波谱分类方法,将光谱向量作为随机变量,基于概率统计理论分析两个随机向量的相似度,即其中,光谱信息散度的值越小,说明两组光谱越相似。

假设 xy 分别代表目标光谱与测试光谱,长度都为 n1

其中

ai=xi/i=1n1xibi=yi/i=1n1yi 分别代表2个光谱的概率。

Ii(x)=lgaiIi(y)=lgbi

分别是根据信息理论得到的 2 条光谱的自信息值。

同理

用go语言实现的代码:


// 光谱信息散度
func SID(src, dst []float64) float64 {
	lensrc := len(src)
	lendst := len(dst)
	if lensrc != lendst {
		panic(fmt.Sprintf("两个数组的长度不一样!%d,%d", lensrc, lendst))
	}

	srcf := []float64{}
	dstf := []float64{}
	sumsrc, sumdst := 0.0, 0.0
	for i := 0; i < lensrc; i++ {
		sumsrc += src[i]
		sumdst += dst[i]
		srcf = append(srcf, 0.0)
		dstf = append(dstf, 0.0)
	}
	log.Printf("sum %f %f", sumsrc, sumdst)

	for i := 0; i < lensrc; i++ {
		srcf[i] = src[i] / sumsrc
		dstf[i] = dst[i] / sumdst
	}

	sid := 0.0
	for i := 0; i < lensrc; i++ {
		if dstf[i] != 0.0 && srcf[i] != 0.0 { // 排除分母出现 0 的情况 ,0 是没数据,不参与比较
			sid += srcf[i]*math.Log10(srcf[i]/dstf[i]) + dstf[i]*math.Log10(dstf[i]/srcf[i])
		}

	}
	return sid
}

SID_SA 结合法

  • SAM的原理是将目标光谱与测试光谱投影到空间中,计算其间的夹角,其值越小代表相似度越高。
  • SID是一种基于信息论理念,通过计算信息熵来判断光谱相似性的方法。

而2种方法结合的 SID_SA 结合法同时考虑到 SAM 和 SID的优点,从光谱的形状以及反射能量差异2方面入手,能有效计算光谱间的相似度。

计算公式


值越小,证明光谱相似度越高,反之则说明光谱间相似度低。

用go实现的代码:

import (
	"fmt"
	"log"
	"math"
	"gonum.org/v1/gonum/floats"
)

// 组合使用 SID 和 SAM
func SidSa(src, dst []float64) float64 {
	return SID(src, dst) * math.Sin(SAM(src, dst))
}

参考:

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示