aux extraction
This commit is contained in:
75
aos.go
75
aos.go
@@ -1,6 +1,81 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
AOSFrameLength = 1024
|
||||
)
|
||||
|
||||
var AOSSyncWord = []byte{0x1A, 0xCF, 0xFC, 0x1D}
|
||||
|
||||
type AOSFrame struct {
|
||||
}
|
||||
|
||||
func (p *Processor) ExtractAosData() error {
|
||||
// 打开传输帧文件 - 一次读入内存
|
||||
rawData, err := os.ReadFile(p.params.InputData)
|
||||
if err != nil {
|
||||
log.Println("read data from", p.params.InputData, "error:", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
name := filepath.Base(p.params.InputData)
|
||||
aosDataFile := filepath.Join(p.params.TempPath, "aos_data_"+name)
|
||||
foData, err := os.OpenFile(aosDataFile,
|
||||
os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
fmt.Println("create data err", err.Error())
|
||||
return err
|
||||
}
|
||||
defer foData.Close()
|
||||
wData := bufio.NewWriter(foData)
|
||||
|
||||
var validFrameCnt int
|
||||
var errFrameCnt int
|
||||
|
||||
for i := 0; i < len(rawData); {
|
||||
// 寻找帧头 0x1A CF FC 1D
|
||||
if i+4 > len(rawData) {
|
||||
log.Info("end of raw data")
|
||||
break
|
||||
}
|
||||
|
||||
if rawData[i] == 0x1A && rawData[i+1] == 0xCF && rawData[i+2] == 0xFC && rawData[i+3] == 0x1D {
|
||||
// 找到帧头
|
||||
log.Debug("detect AOS frame")
|
||||
} else {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
if i+1024 > len(rawData) {
|
||||
log.Info("not enough data for AOS frame")
|
||||
break
|
||||
}
|
||||
|
||||
// 读取完整帧
|
||||
if ldpcCheck(rawData[i:i+1024]) != nil {
|
||||
errFrameCnt++
|
||||
}
|
||||
|
||||
wData.Write(rawData[i+10 : i+894])
|
||||
i += 1024
|
||||
validFrameCnt++
|
||||
}
|
||||
|
||||
log.Println("valid AOS frame cnt:", validFrameCnt)
|
||||
log.Println("err AOS frame cnt:", errFrameCnt)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ldpcCheck(frame []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
247
aux.go
Normal file
247
aux.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// 每行传感器数据帧头信息长度为24字节
|
||||
type AuxFrameHead struct {
|
||||
PkgHead [4]byte // 包头头标识符,固定为0xD15BD15B
|
||||
FillByte0 byte // 填充字节 0x00
|
||||
FrmHead [6]byte // 帧头标识符,固定为0xEB90EB90EB90
|
||||
// 图像模式
|
||||
// B7 模式标识 000:为线阵模式
|
||||
// B6
|
||||
// B5
|
||||
// B4 B4谱状态 0:不输出1:输出
|
||||
// B3 B3谱状态 0:不输出1:输出
|
||||
// B2 B2谱状态 0:不输出1:输出
|
||||
// B1 B1谱状态 0:不输出1:输出
|
||||
// B0 全色状态 0:不输出1:输出
|
||||
ImgMode byte
|
||||
SerialNo uint32 // 当前流水号
|
||||
TimeSec uint32 // 时间(秒) 量纲:1us/bit,十六进制无符号整型数
|
||||
TimeSecFrac uint32 // 秒小数
|
||||
FileNo uint8 // 文件号
|
||||
|
||||
IsValidFrmHead bool
|
||||
B0 bool
|
||||
B1 bool
|
||||
B2 bool
|
||||
B3 bool
|
||||
B4 bool
|
||||
IsLinerMatrix bool
|
||||
RowLength int
|
||||
}
|
||||
|
||||
func (afh *AuxFrameHead) Decode(data []byte) error {
|
||||
if len(data) < 24 {
|
||||
return errors.New("length of AuxFrameHead is not 24")
|
||||
}
|
||||
|
||||
afh.PkgHead = [4]byte{data[0], data[1], data[2], data[3]}
|
||||
afh.FillByte0 = data[4]
|
||||
afh.FrmHead = [6]byte{data[5], data[6], data[7], data[8], data[9], data[10]}
|
||||
afh.ImgMode = data[11]
|
||||
afh.B0 = (afh.ImgMode&(1<<0) != 0x0)
|
||||
afh.B1 = (afh.ImgMode&(1<<1) != 0x0)
|
||||
afh.B2 = (afh.ImgMode&(1<<2) != 0x0)
|
||||
afh.B3 = (afh.ImgMode&(1<<3) != 0x0)
|
||||
afh.B4 = (afh.ImgMode&(1<<4) != 0x0)
|
||||
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.FileNo = data[23]
|
||||
|
||||
afh.RowLength = afh.LengthOfRow()
|
||||
afh.IsValidFrmHead = afh.CheckFrmHead()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 计算一行数据长度:帧头+辅助数据+图像数据
|
||||
func (afh AuxFrameHead) LengthOfRow() int {
|
||||
if !afh.IsLinerMatrix {
|
||||
return 14344
|
||||
}
|
||||
|
||||
length := 64 // 帧头+辅助数据长度
|
||||
if afh.B0 {
|
||||
length += 19040
|
||||
}
|
||||
if afh.B1 {
|
||||
length += 1192
|
||||
}
|
||||
if afh.B2 {
|
||||
length += 1192
|
||||
}
|
||||
if afh.B3 {
|
||||
length += 1192
|
||||
}
|
||||
if afh.B4 {
|
||||
length += 1192
|
||||
}
|
||||
|
||||
return length
|
||||
}
|
||||
|
||||
func (afh AuxFrameHead) CheckFrmHead() bool {
|
||||
if afh.FrmHead[0] == 0xEB && afh.FrmHead[1] == 0x90 &&
|
||||
afh.FrmHead[2] == 0xEB && afh.FrmHead[3] == 0x90 &&
|
||||
afh.FrmHead[4] == 0xEB && afh.FrmHead[5] == 0x90 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 中心机辅助数据 512 字节
|
||||
type AuxCenterMachine struct {
|
||||
}
|
||||
|
||||
// 焦面电箱辅助数据 128 字节
|
||||
type AuxFocalBox struct {
|
||||
}
|
||||
|
||||
// 从传输帧文件中分离辅助数据,分别存储到辅助数据文件 _AUX.dat 和图像数据文件 _IMG_{波谱}.dat 中
|
||||
func (p *Processor) SeprateAuxAndImgData(sDataFile string) error {
|
||||
// 打开传输帧文件 - 一次读入内存
|
||||
sData, err := os.ReadFile(sDataFile)
|
||||
if err != nil {
|
||||
log.Println("read data from", sDataFile, "error:", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("seprate aux and img data from", sDataFile)
|
||||
|
||||
name := filepath.Base(sDataFile)
|
||||
name = strings.TrimRight(name, filepath.Ext(name))
|
||||
|
||||
aux0 := filepath.Dir(sDataFile) + "/" + name + "_AUX0.dat"
|
||||
os.Remove(aux0)
|
||||
faux0, _ := os.OpenFile(aux0, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
waux0 := bufio.NewWriter(faux0)
|
||||
defer waux0.Flush()
|
||||
defer faux0.Close()
|
||||
|
||||
aux1 := filepath.Dir(sDataFile) + "/" + name + "_AUX1.dat"
|
||||
os.Remove(aux1)
|
||||
faux1, _ := os.OpenFile(aux1, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
waux1 := bufio.NewWriter(faux1)
|
||||
defer waux1.Flush()
|
||||
defer faux1.Close()
|
||||
|
||||
pan := filepath.Dir(sDataFile) + "/" + name + "_IMG_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(filepath.Dir(sDataFile)+"/"+name+"_IMG_PAN.HDR", &panEnviHdr)
|
||||
defer wpanHdr.Close()
|
||||
|
||||
// 先按单波段存储,再按波段组合存储为 BSQ 格式的 MSS
|
||||
mss := filepath.Dir(sDataFile) + "/" + name + "_IMG_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(filepath.Dir(sDataFile)+"/"+name+"_IMG_MSS.HDR", &mssEnviHdr)
|
||||
defer wmssHdr.Close()
|
||||
|
||||
var afh AuxFrameHead
|
||||
dataLen := len(sData)
|
||||
for i := 0; i < dataLen; {
|
||||
if i+4 > dataLen {
|
||||
logrus.Println("end of data, dataLen:", dataLen, "i:", i)
|
||||
break
|
||||
}
|
||||
|
||||
// 包头
|
||||
if sData[i] == 0xD1 && sData[i+1] == 0x5B && sData[i+2] == 0xD1 && sData[i+3] == 0x5B {
|
||||
log.Debug("find package head: 0xD15BD15B")
|
||||
} else {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
// 解析帧
|
||||
if i+24 > dataLen {
|
||||
log.Info("length of frame head is not engough for frame head")
|
||||
break
|
||||
}
|
||||
afh.Decode(sData[i : i+24])
|
||||
// pp.Println(afh)
|
||||
|
||||
if !afh.IsValidFrmHead {
|
||||
log.Info("invalid frame head of original raw data")
|
||||
break
|
||||
}
|
||||
|
||||
// 目前只支持线阵模式
|
||||
if !afh.IsLinerMatrix {
|
||||
log.Error("not liner matrix mode, only support liner matrix mode")
|
||||
break
|
||||
}
|
||||
|
||||
// 读取一行数据 sData[i : i+afh.RowLength]
|
||||
if i+afh.RowLength > dataLen {
|
||||
log.Info("length of row data is not enough for row length:", afh.RowLength)
|
||||
break
|
||||
}
|
||||
|
||||
// 存储辅助数据到临时文件
|
||||
dataIndex := i + 24
|
||||
waux0.Write(sData[dataIndex : dataIndex+8]) // 8字节焦面电箱辅助数据
|
||||
dataIndex += 8
|
||||
waux1.Write(sData[dataIndex : dataIndex+32]) // 32字节中心机辅助数据
|
||||
dataIndex += 32
|
||||
|
||||
// 存储图像数据到临时文件 - 以 ENVI BSQ 格式存储,同时提供 HDR 描述文件
|
||||
if afh.B0 {
|
||||
wpan.Write(sData[dataIndex : dataIndex+19040])
|
||||
dataIndex += 19040
|
||||
panEnviHdr.Lines += 1
|
||||
}
|
||||
|
||||
if afh.B1 {
|
||||
wmss.Write(sData[dataIndex : dataIndex+1192])
|
||||
dataIndex += 1192
|
||||
mssEnviHdr.Lines += 1
|
||||
}
|
||||
if afh.B2 {
|
||||
wmss.Write(sData[dataIndex : dataIndex+1192])
|
||||
dataIndex += 1192
|
||||
}
|
||||
if afh.B3 {
|
||||
wmss.Write(sData[dataIndex : dataIndex+1192])
|
||||
dataIndex += 1192
|
||||
}
|
||||
if afh.B4 {
|
||||
wmss.Write(sData[dataIndex : dataIndex+1192])
|
||||
dataIndex += 1192
|
||||
}
|
||||
i = dataIndex // 完成一行数据解析
|
||||
}
|
||||
|
||||
panEnviHdr.Samples = 9520
|
||||
panEnviHdr.Bands = 1
|
||||
wpanHdr.Write([]byte(panEnviHdr.String()))
|
||||
mssEnviHdr.Lines = mssEnviHdr.Lines / 4 // 多光谱波段分别在 4 行中传输
|
||||
mssEnviHdr.Bands = 1
|
||||
mssEnviHdr.Samples = 2384 * 4
|
||||
wmssHdr.Write([]byte(mssEnviHdr.String()))
|
||||
|
||||
return nil
|
||||
}
|
||||
69
envi.go
Normal file
69
envi.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html"
|
||||
|
||||
"io"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type BSQWriter struct {
|
||||
filepath string
|
||||
fio *os.File
|
||||
w io.Writer
|
||||
content *EnviHdr
|
||||
}
|
||||
|
||||
var HDRTemplate = `ENVI
|
||||
description = {
|
||||
File Imported into ENVI.}
|
||||
samples = {{.Samples}}
|
||||
lines = {{.Lines}}
|
||||
bands = {{.Bands}}
|
||||
header offset = 0
|
||||
file type = ENVI Standard
|
||||
data type = 12
|
||||
interleave = bsq
|
||||
sensor type = Unknown
|
||||
byte order = 0
|
||||
wavelength units = Unknown`
|
||||
|
||||
// https://www.nv5geospatialsoftware.com/docs/ENVIHeaderFiles.html
|
||||
type EnviHdr struct {
|
||||
Samples int // samples (pixels) each line
|
||||
Lines int
|
||||
Bands int
|
||||
}
|
||||
|
||||
func (h *EnviHdr) String() string {
|
||||
var t *template.Template
|
||||
t = template.New("template")
|
||||
t, err := t.Parse(HDRTemplate)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
t.Execute(buf, h)
|
||||
buf = bytes.NewBufferString(html.UnescapeString(buf.String()))
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func NewBSQWriter(filepath string, content *EnviHdr) (*BSQWriter, error) {
|
||||
fio, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
w := fio
|
||||
return &BSQWriter{filepath, fio, w, content}, nil
|
||||
}
|
||||
|
||||
func (w *BSQWriter) Write(data []byte) (int, error) {
|
||||
return w.w.Write(data)
|
||||
}
|
||||
|
||||
func (w *BSQWriter) Close() error {
|
||||
return w.fio.Close()
|
||||
}
|
||||
8
go.mod
8
go.mod
@@ -2,10 +2,18 @@ module starwiz.cn/sjy01/preprocessing
|
||||
|
||||
go 1.21.0
|
||||
|
||||
require github.com/k0kubun/pp v3.0.1+incompatible
|
||||
|
||||
require (
|
||||
github.com/duke-git/lancet/v2 v2.3.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
)
|
||||
|
||||
22
go.sum
22
go.sum
@@ -1,14 +1,36 @@
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/duke-git/lancet/v2 v2.3.0 h1:Ztie0qOnC4QgGYYqmpmQxbxkPcm54kqFXj1bwhiV8zg=
|
||||
github.com/duke-git/lancet/v2 v2.3.0/go.mod h1:zGa2R4xswg6EG9I6WnyubDbFO/+A/RROxIbXcwryTsc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
|
||||
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
|
||||
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
15
main.go
15
main.go
@@ -16,14 +16,19 @@ var rootCmd = &cobra.Command{
|
||||
Long: `Preprocessing tools for SJY01 dataset`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("preprocessing tools for SJY01 dataset")
|
||||
p := Params{
|
||||
InputData: "demo/050722.dat",
|
||||
params := Params{
|
||||
InputData: "demo/4545.dat",
|
||||
OutputPath: "demo/output",
|
||||
TempPath: "demo/temp",
|
||||
DataId: "050722",
|
||||
DataId: "004545",
|
||||
}
|
||||
// preprocess(&p)
|
||||
exractImageData(&p)
|
||||
p := NewProcessor(¶ms)
|
||||
p.ExtractAosData()
|
||||
dats, _ := p.ExtractOriginalImageData()
|
||||
for _, d := range dats {
|
||||
p.SeprateAuxAndImgData(d)
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
176
process.go
176
process.go
@@ -1,179 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
const (
|
||||
AOSFrameLength = 1024
|
||||
)
|
||||
|
||||
var AOSSyncWord = []byte{0x1A, 0xCF, 0xFC, 0x1D}
|
||||
var ImageFrameHead = 0xE77EE77E
|
||||
|
||||
|
||||
func preprocess(params *Params) error {
|
||||
// extract data from aos frame
|
||||
fi, err := os.Open(params.InputData)
|
||||
if err != nil {
|
||||
log.Println("exract data from", params.InputData, "error:", err.Error())
|
||||
return err
|
||||
}
|
||||
defer fi.Close()
|
||||
|
||||
name := filepath.Base(params.InputData)
|
||||
aosDataFile := filepath.Join(params.TempPath, "aos_data_"+name)
|
||||
foData, err := os.OpenFile(aosDataFile,
|
||||
os.O_RDWR|os.O_CREATE|os.O_APPEND, 0777)
|
||||
if err != nil {
|
||||
fmt.Println("create data err", err.Error())
|
||||
return err
|
||||
}
|
||||
defer foData.Close()
|
||||
wData := bufio.NewWriter(foData)
|
||||
|
||||
var validFrameCnt int
|
||||
var errFrameCnt int
|
||||
|
||||
iBuf := make([]byte, AOSFrameLength)
|
||||
r := bufio.NewReader(fi)
|
||||
for {
|
||||
correct := true
|
||||
nI, err := r.Read(iBuf)
|
||||
if err != nil && err != io.EOF {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if nI < AOSFrameLength || err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
iTag := iBuf[0:4]
|
||||
if iTag[0] == 0x1A && iTag[1] == 0xCF && iTag[2] == 0xFC && iTag[3] == 0x1D {
|
||||
if err := ldpcCheck(iBuf); err != nil {
|
||||
errFrameCnt++
|
||||
correct = false
|
||||
} else {
|
||||
validFrameCnt++
|
||||
}
|
||||
} else {
|
||||
correct = false
|
||||
errFrameCnt++
|
||||
}
|
||||
|
||||
if !correct {
|
||||
continue
|
||||
}
|
||||
|
||||
data := iBuf[10:894]
|
||||
wData.Write(data)
|
||||
}
|
||||
|
||||
log.Println("valid frame cnt:", validFrameCnt)
|
||||
log.Println("err frame cnt:", errFrameCnt)
|
||||
|
||||
return nil
|
||||
type Processor struct {
|
||||
params *Params
|
||||
}
|
||||
|
||||
func ldpcCheck(frame []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func exractImageData(params *Params) ([]string, error) {
|
||||
var sData []string
|
||||
name := filepath.Base(params.InputData)
|
||||
aosDataFile := filepath.Join(params.TempPath, "aos_data_"+name)
|
||||
|
||||
aosData, err := os.ReadFile(aosDataFile)
|
||||
if err != nil {
|
||||
log.Println("read data from", aosDataFile, "error:", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snRange := map[int][]int{}
|
||||
datSet := map[int][]byte{}
|
||||
|
||||
var i int
|
||||
for i < len(aosData) {
|
||||
if i+4 > len(aosData) {
|
||||
break
|
||||
}
|
||||
|
||||
if aosData[i] == 0xE7 && aosData[i+1] == 0x7E && aosData[i+2] == 0xE7 && aosData[i+3] == 0x7E {
|
||||
i += 4 // <- 帧头
|
||||
|
||||
serialNum := binary.BigEndian.Uint32(aosData[i : i+4])
|
||||
i += 4 // <- 流水号
|
||||
i += 2 // <- 保留位
|
||||
i += 2 // <- 密钥库索引号
|
||||
i += 1 // <- 明密标志
|
||||
|
||||
flag := aosData[i]
|
||||
i += 1 // <-帧标志
|
||||
|
||||
fileno := int(aosData[i])
|
||||
snRange[fileno] = append(snRange[fileno], int(serialNum))
|
||||
i += 1 // <- 文件号
|
||||
|
||||
i += 1 // <- 保留
|
||||
|
||||
if i+ImageFrameDataLength > len(aosData) {
|
||||
log.Println("frame length error")
|
||||
break
|
||||
}
|
||||
|
||||
// 只保留非空帧
|
||||
if flag != 0x55 {
|
||||
datSet[fileno] = append(datSet[fileno], aosData[i:i+ImageFrameDataLength]...)
|
||||
}
|
||||
|
||||
i += ImageFrameDataLength // <- 图像数据
|
||||
if i > len(aosData) {
|
||||
log.Println("frame length error")
|
||||
break
|
||||
}
|
||||
|
||||
// fmt.Println("serialNum:", serialNum, "fileno:", fileno)
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
for k, v := range datSet {
|
||||
frameCnt := slice.Unique(snRange[k])
|
||||
if len(frameCnt) < 4096 {
|
||||
log.Println("fileno", k, "数据长度不足4096帧")
|
||||
continue
|
||||
}
|
||||
|
||||
s01 := filepath.Join(params.TempPath, fmt.Sprintf("%s_S%d.dat", params.DataId, k))
|
||||
fo, err := os.OpenFile(s01,
|
||||
os.O_RDWR|os.O_CREATE|os.O_APPEND, 0777)
|
||||
if err != nil {
|
||||
log.Println("create file", s01, "error:", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
w := bufio.NewWriter(fo)
|
||||
w.Write(v)
|
||||
w.Flush()
|
||||
fo.Close()
|
||||
sData = append(sData, s01)
|
||||
}
|
||||
|
||||
for k, v := range snRange {
|
||||
vv := slice.Unique(v)
|
||||
sort.Slice(vv, func(i, j int) bool { return vv[i] < vv[j] })
|
||||
fmt.Println("fileno:", k, ", sn range:", vv[0], "-", vv[len(vv)-1], "len", len(vv))
|
||||
}
|
||||
|
||||
return sData, nil
|
||||
func NewProcessor(params *Params) *Processor {
|
||||
os.MkdirAll(params.OutputPath, 0755)
|
||||
os.MkdirAll(params.TempPath, 0755)
|
||||
return &Processor{params: params}
|
||||
}
|
||||
|
||||
18
raw.go
Normal file
18
raw.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
// 图像数据帧头信息、辅助数据以及图像数据组成,
|
||||
// 帧头信息长度为24字节,
|
||||
// 辅助数据总共640字节,分16行传输,每行传输40字节
|
||||
// 其中40字节中包含8字节焦面电箱辅助数据以及32节字的中心机辅助数据
|
||||
// 图像数据 每个像素16bit
|
||||
// 线阵模式每 16 行一组,可拼出 640 字节辅助数据
|
||||
type LineMatrixRawRow struct {
|
||||
FrameHeader [24]byte // 帧头信息
|
||||
AuxFocalBox [8]byte // 焦面电箱辅助数据
|
||||
AuxCenterMachine [32]byte // 中心机辅助数据
|
||||
B0Data []byte // 全色图像数据 19040 字节,9520 像素
|
||||
B1Data []byte // 多光谱1图像数据 1192 字节,每 4 行一组,共 4768 字节,2384 像素
|
||||
B2Data []byte // 多光谱2图像数据 1192 字节,每 4 行一组,共 4768 字节,2384 像素
|
||||
B3Data []byte // 多光谱3图像数据 1192 字节,每 4 行一组,共 4768 字节,2384 像素
|
||||
B4Data []byte // 多光谱4图像数据 1192 字节,每 4 行一组,共 4768 字节,2384 像素
|
||||
}
|
||||
12
spectral_img.go
Normal file
12
spectral_img.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
type SpectralImage struct {
|
||||
Spectrum string // PAN(B0) B1 B2 B3 B4
|
||||
H uint32 // 9520 像素 2(Margin) + 48(OB) + 38(Margin) + 9344(Effective Pixels) + 38(Margin) + 48(OB) + 2(Margin)
|
||||
V uint32 // 7056 像素 2(Margin) + 12(OB) + 18(Margin) + 20(Margin) + 7000(Effective Pixels) + 4(Margin)
|
||||
Pixels [][]*Pixel
|
||||
}
|
||||
|
||||
type Pixel struct {
|
||||
Bits [2]byte // 16bit
|
||||
}
|
||||
100
trans_frame.go
100
trans_frame.go
@@ -1,7 +1,21 @@
|
||||
package main
|
||||
|
||||
const ImageFrameHeadLength = 16
|
||||
const ImageFrameDataLength = 8176
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
const TransImageFrameLength = 8192
|
||||
const TransImageFrameHeadLength = 16
|
||||
const TransImageFrameDataLength = 8176
|
||||
const ImageFrameHead = 0xE77EE77E
|
||||
|
||||
// 智能载荷电箱与数传单机之间图像数据传输帧格式
|
||||
type TransFrame struct {
|
||||
@@ -11,13 +25,13 @@ type TransFrame struct {
|
||||
KeyIndex uint16 // 密钥库索引号 大端序
|
||||
SecretFlag byte // 明密标志 0x55 明传 0xAA 密传
|
||||
FrameFlag byte // 帧类型 0x00:智能载荷电箱有效帧 0x55: 智能载荷电箱空帧
|
||||
FileNo byte // 文件编号
|
||||
FileNo uint8 // 文件编号
|
||||
Reserved1 byte // 保留字节 0x00
|
||||
Data [8176]byte
|
||||
Data []byte // 数据区 8176字节
|
||||
}
|
||||
|
||||
func (t *TransFrame) Decode(frame []byte) {
|
||||
if len(frame) < ImageFrameHeadLength+ImageFrameDataLength {
|
||||
if len(frame) < TransImageFrameLength {
|
||||
return
|
||||
}
|
||||
copy(t.Header[:], frame[:4])
|
||||
@@ -28,5 +42,79 @@ func (t *TransFrame) Decode(frame []byte) {
|
||||
t.FrameFlag = frame[13]
|
||||
t.FileNo = frame[14]
|
||||
t.Reserved1 = frame[15]
|
||||
copy(t.Data[:], frame[16:])
|
||||
t.Data = append(t.Data, frame[16:8192]...)
|
||||
}
|
||||
|
||||
// 提取图像传输帧中的原始图像数据
|
||||
func (p *Processor) ExtractOriginalImageData() ([]string, error) {
|
||||
var sData []string
|
||||
name := filepath.Base(p.params.InputData)
|
||||
aosDataFile := filepath.Join(p.params.TempPath, "aos_data_"+name)
|
||||
|
||||
aosData, err := os.ReadFile(aosDataFile)
|
||||
if err != nil {
|
||||
log.Println("read data from", aosDataFile, "error:", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snRange := map[int][]uint32{}
|
||||
datSet := map[int][]byte{}
|
||||
|
||||
var i int
|
||||
for i < len(aosData) {
|
||||
if i+4 > len(aosData) {
|
||||
log.Println("end of trans frame data")
|
||||
break
|
||||
}
|
||||
|
||||
if aosData[i] == 0xE7 && aosData[i+1] == 0x7E && aosData[i+2] == 0xE7 && aosData[i+3] == 0x7E {
|
||||
if i+TransImageFrameLength > len(aosData) {
|
||||
log.Println("trans frame length error")
|
||||
break
|
||||
}
|
||||
|
||||
var tf TransFrame
|
||||
tf.Decode(aosData[i : i+TransImageFrameLength])
|
||||
fileno := int(tf.FileNo)
|
||||
snRange[fileno] = append(snRange[fileno], tf.SNo)
|
||||
|
||||
// 只保留非空帧
|
||||
if tf.FrameFlag != 0x55 && fileno != 0 {
|
||||
datSet[fileno] = append(datSet[fileno], tf.Data...)
|
||||
}
|
||||
|
||||
i += TransImageFrameLength
|
||||
continue
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
for k, v := range snRange {
|
||||
vv := slice.Unique(v)
|
||||
sort.Slice(vv, func(i, j int) bool { return vv[i] < vv[j] })
|
||||
fmt.Println("fileno:", k, ", sn range:", vv[0], "-", vv[len(vv)-1], "len", len(vv))
|
||||
}
|
||||
|
||||
for k, v := range datSet {
|
||||
frameCnt := slice.Unique(snRange[k])
|
||||
if len(frameCnt) < 4096 {
|
||||
log.Println("fileno", k, "数据长度不足4096帧")
|
||||
continue
|
||||
}
|
||||
|
||||
s01 := filepath.Join(p.params.TempPath, fmt.Sprintf("%s_S%d.dat", p.params.DataId, k))
|
||||
fo, err := os.OpenFile(s01,
|
||||
os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
log.Println("create file", s01, "error:", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
w := bufio.NewWriter(fo)
|
||||
w.Write(v)
|
||||
w.Flush()
|
||||
fo.Close()
|
||||
sData = append(sData, s01)
|
||||
}
|
||||
|
||||
return sData, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user