IHS pansharpen

This commit is contained in:
nuknal
2024-09-14 10:25:49 +08:00
parent 001ad32b8e
commit 78f451672a
3 changed files with 70 additions and 2 deletions

126
pkg/auxilary/attitude.go Normal file
View File

@@ -0,0 +1,126 @@
package auxilary
import (
"fmt"
"math"
"os"
)
type Attitudes struct {
Atts []*Attitude
}
func (atts Attitudes) Save(attFile string) error {
f, err := os.Create(attFile)
if err != nil {
return err
}
defer f.Close()
for _, att := range atts.Atts {
content := fmt.Sprintf("%.6f %.8f %.8f %.8f %.8f\n", att.UTCTimestampSec, att.Q0, att.Q1, att.Q2, att.Q3)
f.WriteString(content)
}
return nil
}
// 四元数球面线性插值
func (atts Attitudes) Slerp(t float64) *Attitude {
// 取 t 前后的四元数
var q0, q1 *Attitude
for i, att := range atts.Atts {
if att.UTCTimestampSec >= t {
if i == 0 {
q0 = att
q1 = atts.Atts[i+1]
} else {
q0 = atts.Atts[i-1]
q1 = att
}
break
}
}
if q0 == nil || q1 == nil {
return atts.Atts[len(atts.Atts)-1]
}
var w0, x0, y0, z0, w1, x1, y1, z1 float64
w0, x0, y0, z0 = q0.Q0, q0.Q1, q0.Q2, q0.Q3
w1, x1, y1, z1 = q1.Q0, q1.Q1, q1.Q2, q1.Q3
// 用点乘计算两个四元数夹角的cos值
cosOmega := w0*w1 + x0*x1 + y0*y1 + z0*z1
// 如果点乘为负则反转一个四元数以取得短的4D弧
if cosOmega < 0.0 {
w1 = -w1
x1 = -x1
y1 = -y1
z1 = -z1
cosOmega = -cosOmega
}
var k0, k1 float64
t0, t1 := q0.UTCTimestampSec, q1.UTCTimestampSec
if cosOmega > 0.99999999 { // cos=1的时候就是夹角为0重合
k0 = (t1 - t) / (t1 - t0)
k1 = (t - t0) / (t1 - t0)
} else {
// 用三角公式sin^2+cos^2=1计算sin值
sinOmega := math.Sqrt(1.0 - cosOmega*cosOmega)
// 通过sin和cos计算角度
omega := math.Atan2(sinOmega, cosOmega) // 计算点(cosOmega,sinOmega)与x轴正向的夹角
// 计算分母的倒数,这样就只需要一次除法
oneOverSinOmega := 1.0 / sinOmega
//计算插值变量
k0 = math.Sin((t1-t)/(t1-t0)*omega) * oneOverSinOmega
k1 = math.Sin((t-t0)/(t1-t0)*omega) * oneOverSinOmega
}
// 插值
w := w0*k0 + w1*k1
x := x0*k0 + x1*k1
y := y0*k0 + y1*k1
z := z0*k0 + z1*k1
return &Attitude{
UTCTimestampSec: t,
Q0: w,
Q1: x,
Q2: y,
Q3: z,
}
}
type Attitude struct {
UTCTimestampSec float64
Q0, Q1, Q2, Q3 float64
}
func StoreAtt(aps []*AuxPlatform, attFile string) (*Attitudes, error) {
atts := ExtractAttitude(aps)
return atts, atts.Save(attFile)
}
func ExtractAttitude(aps []*AuxPlatform) *Attitudes {
var atts Attitudes
var sec, microsec uint32
for _, ap := range aps {
if ap.UTCTimeSec != sec || ap.Microsecond != microsec {
sec, microsec = ap.UTCTimeSec, ap.Microsecond
att := Attitude{
UTCTimestampSec: float64(sec) + float64(ReferenceTime2000) +
float64(transfromGPSandAttMicrosec(microsec))/1e6,
Q0: ap.QuatAttstarQ0,
Q1: ap.QuatAttstarQ1,
Q2: ap.QuatAttstarQ2,
Q3: ap.QuatAttstarQ3,
}
atts.Atts = append(atts.Atts, &att)
}
}
return &atts
}