get raw data

This commit is contained in:
nuknal
2024-05-17 21:46:38 +08:00
parent 58acd444d6
commit 0d59c8514b
11 changed files with 365 additions and 47 deletions

View File

@@ -5,6 +5,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"sort"
@@ -62,7 +63,7 @@ func (afh *AuxFrameHead) Decode(data []byte) error {
afh.IsLinerMatrix = (afh.ImgMode&(1<<5) == 0x0 && afh.ImgMode&(1<<6) == 0x0 && afh.ImgMode&(1<<7) == 0x0)
afh.SerialNo = binary.BigEndian.Uint32(data[12:16])
afh.TimeSec = binary.BigEndian.Uint32(data[16:20])
afh.TimeSecFrac = uint32(uint32(data[20])<<16 | uint32(data[21])<<8 | uint32(data[22])) //binary.BigEndian.Uint32(data[20:23])
afh.TimeSecFrac = uint32(uint32(data[20])<<16 | uint32(data[21])<<8 | uint32(data[22]))
afh.FileNo = data[23]
afh.RowLength = afh.LengthOfRow()
@@ -112,7 +113,7 @@ type Record struct {
}
// 从传输帧文件中分离辅助数据,分别存储到辅助数据文件 _AUX.dat 和图像数据文件 _IMG_{波谱}.dat 中
func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
func (p *Extractor) SeprateAuxAndImgData(sDataFile string, segmentIndex int) error {
// 打开传输帧文件 - 一次读入内存
sData, err := os.ReadFile(sDataFile)
if err != nil {
@@ -127,6 +128,8 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
defer fimg.Close()
fimg.WriteString("字节数 帧头流水号 文件号 帧头时间 中心辅助数据前4字节(行33-36)\n")
var qmap []*Record
var startAuxLine bool
var preSN uint32
for i := 0; i < len(sData); {
// 解析帧
if i+24 > len(sData) {
@@ -148,22 +151,22 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
if !afh.IsValidFrmHead {
log.Debugf("[%d] invalid frame head of original raw data %v", i, afh.FrmHead)
i += 1
continue
}
r := &Record{index: i, frmHead: afh}
qmap = append(qmap, r)
utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36])
t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), int64(afh.TimeSecFrac)*1000)
tAux := time.Unix(int64(utcTime+uint32(ReferenceTime2000)), 0)
startAuxLine = tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() &&
tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute()
if !startAuxLine {
// fimg.WriteString(fmt.Sprintf("-----%d not AUX Start -----\n", afh.SerialNo))
} else {
r := &Record{index: i, frmHead: afh}
qmap = append(qmap, r)
i += 24
utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36])
t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), 0)
tAux := time.Unix(int64(utcTime), 0)
startAuxLine := tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() &&
tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute()
if startAuxLine {
fimg.WriteString("----- AUX Start -----\n")
}
fimg.WriteString(fmt.Sprintf("%d %d %d %s %s\n",
i,
afh.SerialNo,
@@ -171,7 +174,14 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
t.String(),
tAux.String(),
))
if afh.SerialNo-preSN != 16 {
fmt.Println("serial number not continuous", afh.SerialNo, preSN)
}
preSN = afh.SerialNo
}
i += afh.RowLength
}
sort.Slice(qmap, func(i, j int) bool {
@@ -196,31 +206,34 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
defer waux1.Flush()
defer faux1.Close()
pan := outputDir + "/" + name + "_IMG_PAN.RAW"
pan := outputDir + "/" + name + "_PAN.RAW"
os.Remove(pan)
fpan, _ := os.OpenFile(pan, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
wpan := bufio.NewWriter(fpan)
defer wpan.Flush()
defer fpan.Close()
panEnviHdr := EnviHdr{}
wpanHdr, _ := NewBSQWriter(outputDir+"/"+name+"_IMG_PAN.HDR", &panEnviHdr)
wpanHdr, _ := NewBSQWriter(outputDir+"/"+name+"_PAN.HDR", &panEnviHdr)
defer wpanHdr.Close()
// 先按单波段存储,再按波段组合存储为 BSQ 格式的 MSS
mss := outputDir + "/" + name + "_IMG_MSS.RAW"
mss := outputDir + "/" + name + "_MSS.RAW"
os.Remove(mss)
fmss, _ := os.OpenFile(mss, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
wmss := bufio.NewWriter(fmss)
defer wmss.Flush()
defer fmss.Close()
mssEnviHdr := EnviHdr{}
wmssHdr, _ := NewBSQWriter(outputDir+"/"+name+"_IMG_MSS.HDR", &mssEnviHdr)
wmssHdr, _ := NewBSQWriter(outputDir+"/"+name+"_MSS.HDR", &mssEnviHdr)
defer wmssHdr.Close()
var afh AuxFrameHead
dataLen := len(sData)
mssData := make([][]byte, 4)
var firstLineFound bool
var totalLines int
var pancount int
for i := 0; i < dataLen; {
if i+4 > dataLen {
logrus.Println("end of data, dataLen:", dataLen, "i:", i)
@@ -262,6 +275,21 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
break
}
// 通过中心辅助时间判断是否第一行数据
if !firstLineFound {
utcTime := binary.BigEndian.Uint32(sData[i+32 : i+36])
t := time.Unix(int64(afh.TimeSec+uint32(ReferenceTime2000)), int64(afh.TimeSecFrac)*1000)
tAux := time.Unix(int64(utcTime+uint32(ReferenceTime2000)), 0)
firstLineFound = tAux.Year() == t.Year() && tAux.Month() == t.Month() && tAux.Day() == t.Day() &&
tAux.Hour() == t.Hour() && tAux.Minute() == t.Minute()
if !firstLineFound {
log.Info("did not find first line of aux data, skip this frame: ", afh.SerialNo)
i += afh.RowLength
continue
}
}
totalLines += 1
// 存储辅助数据到临时文件
dataIndex := i + 24
waux0.Write(sData[dataIndex : dataIndex+8]) // 8字节焦面电箱辅助数据
@@ -271,29 +299,31 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
// 存储图像数据到临时文件 - 以 ENVI BSQ 格式存储,同时提供 HDR 描述文件
if afh.B0 {
wpan.Write(sData[dataIndex : dataIndex+19040])
// wpan.Write(sData[dataIndex : dataIndex+19040])
write16bPixelLittleEndian(wpan, sData[dataIndex:dataIndex+19040])
dataIndex += 19040
panEnviHdr.Lines += 1
pancount += 19040
}
if afh.B1 {
// wmss.Write(sData[dataIndex : dataIndex+1192])
// write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192])
mssData[0] = append(mssData[0], sData[dataIndex:dataIndex+1192]...)
dataIndex += 1192
mssEnviHdr.Lines += 1
}
if afh.B2 {
// wmss.Write(sData[dataIndex : dataIndex+1192])
// write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192])
mssData[1] = append(mssData[1], sData[dataIndex:dataIndex+1192]...)
dataIndex += 1192
}
if afh.B3 {
// wmss.Write(sData[dataIndex : dataIndex+1192])
// write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192])
mssData[2] = append(mssData[2], sData[dataIndex:dataIndex+1192]...)
dataIndex += 1192
}
if afh.B4 {
// wmss.Write(sData[dataIndex : dataIndex+1192])
// write16bPixelLittleEndian(wmss, sData[dataIndex:dataIndex+1192])
mssData[3] = append(mssData[3], sData[dataIndex:dataIndex+1192]...)
dataIndex += 1192
}
@@ -304,7 +334,7 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
for i := 0; i < 4; i++ {
if len(mssData[i]) > 0 {
log.Println("write mss data of band B", i+1)
_, err := wmss.Write(mssData[i])
// _, err := write16bPixelLittleEndian(wmss, mssData[i])
if err != nil {
log.Error("write mss data error:", err.Error())
}
@@ -312,14 +342,24 @@ func (p *Extractor) SeprateAuxAndImgData(sDataFile string) error {
}
}
write16bPixelLittleEndian(wmss, mssData[2])
panEnviHdr.Samples = 9520
panEnviHdr.Bands = 1
wpanHdr.Write([]byte(panEnviHdr.String()))
mssEnviHdr.Lines = mssEnviHdr.Lines / 4 // 多光谱波段分别在 4 行中传输
mssEnviHdr.Samples = 2384
mssEnviHdr.Bands = bands
mssEnviHdr.Bands = 1
wmssHdr.Write([]byte(mssEnviHdr.String()))
return nil
}
// 写入 16 位像素值,小端序
func write16bPixelLittleEndian(w io.Writer, data []byte) (int, error) {
for i := 0; i < len(data)-1; i += 2 {
data[i], data[i+1] = data[i+1], data[i]
}
return w.Write(data)
}