202 lines
4.2 KiB
Go
202 lines
4.2 KiB
Go
package rrc
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"gocv.io/x/gocv"
|
|
"starwiz.cn/sjy01/image-proc/pkg/payload"
|
|
"starwiz.cn/sjy01/image-proc/pkg/utils"
|
|
)
|
|
|
|
// Relative Radiation Correction
|
|
// 采用在轨统计定标方法。利用卫星在轨后获取的常规影像数据,统计每个探元出现的灰度频次。
|
|
|
|
const (
|
|
PANCameraProbeNum = payload.PAN_PIXEL_WIDTH // 全色探元数
|
|
MSSCameraProbeNum = payload.MSS_PIXEL_WIDTH // 多光谱探元数
|
|
MaxGrayLevel = 65536 // 16bit像素值
|
|
)
|
|
|
|
type RRC struct {
|
|
LUTOutDir string
|
|
Histograms [5]ProbeHistogram
|
|
}
|
|
|
|
func NewRRC(dir string) *RRC {
|
|
r := RRC{LUTOutDir: dir}
|
|
r.Histograms[0].init(PANCameraProbeNum)
|
|
for i := 1; i < 5; i++ {
|
|
r.Histograms[i].init(MSSCameraProbeNum)
|
|
}
|
|
|
|
os.MkdirAll(r.LUTOutDir, 0755)
|
|
|
|
return &r
|
|
}
|
|
|
|
func (rrc *RRC) Statistical(dsPAN, dsMSS string) error {
|
|
rrc.StatisticalPAN(dsPAN)
|
|
rrc.StatisticalMSS(dsMSS)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (rrc *RRC) Close() {}
|
|
|
|
// 基于探元直方图匹配的CBERS01星CCD数据相对辐射校正方法 [潘志强, 2005]
|
|
// 统计探元灰度的累积概率密度
|
|
func (rrc *RRC) StatisticalPAN(dsfile string) error {
|
|
utils.PrintMemStats()
|
|
f, err := os.Open(dsfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
var files []string
|
|
for scanner.Scan() {
|
|
files = append(files, scanner.Text())
|
|
}
|
|
|
|
// 并发处理
|
|
var wg sync.WaitGroup
|
|
jobs := make(chan struct{}, 5)
|
|
|
|
var mutex sync.Mutex
|
|
for _, file := range files {
|
|
wg.Add(1)
|
|
go func(l0 string) {
|
|
defer wg.Done()
|
|
|
|
jobs <- struct{}{}
|
|
defer func() { <-jobs }()
|
|
|
|
log.Println("statistical PAN RAW: ", l0)
|
|
data, err := os.ReadFile(l0)
|
|
if err != nil {
|
|
log.Error("Error reading file: ", err)
|
|
return
|
|
}
|
|
|
|
height := len(data) / (PANCameraProbeNum * 2)
|
|
img, err := gocv.NewMatFromBytes(height, PANCameraProbeNum, gocv.MatTypeCV16U, data)
|
|
if err != nil {
|
|
log.Error("Error creating Mat from bytes: ", err)
|
|
return
|
|
}
|
|
|
|
var hist ProbeHistogram
|
|
hist.init0(PANCameraProbeNum)
|
|
hist.statistical(img)
|
|
img.Close()
|
|
|
|
mutex.Lock()
|
|
|
|
log.Println("sum PAN histogram...")
|
|
rrc.Histograms[0].sum([]*ProbeHistogram{&hist})
|
|
hist.free()
|
|
runtime.GC()
|
|
utils.PrintMemStats()
|
|
|
|
mutex.Unlock()
|
|
|
|
}(file)
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
log.Println("compute PAN histogram...")
|
|
rrc.Histograms[0].compute()
|
|
log.Println("save PAN gray table matrix.")
|
|
rrc.Histograms[0].saveLUT(filepath.Join(rrc.LUTOutDir, "B0.LUT"))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (rrc *RRC) StatisticalMSS(dsfile string) error {
|
|
utils.PrintMemStats()
|
|
f, err := os.Open(dsfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
|
|
var files []string
|
|
for scanner.Scan() {
|
|
files = append(files, scanner.Text())
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
jobs := make(chan struct{}, 5)
|
|
|
|
var mutex sync.Mutex
|
|
for _, file := range files {
|
|
wg.Add(1)
|
|
go func(l0 string) {
|
|
defer wg.Done()
|
|
jobs <- struct{}{}
|
|
defer func() { <-jobs }()
|
|
|
|
log.Println("statistical MSS RAW: ", l0)
|
|
data, err := os.ReadFile(l0)
|
|
if err != nil {
|
|
log.Error("Error reading file: ", err)
|
|
return
|
|
}
|
|
|
|
width := MSSCameraProbeNum
|
|
height := len(data) / (width * 4 * 2)
|
|
mssData := make([][]byte, 4)
|
|
for h := 0; h < height; h++ {
|
|
row := data[h*width*4*2 : (h+1)*width*4*2]
|
|
for i := 0; i < 4; i++ {
|
|
mssData[i] = append(mssData[i], row[i*width*2:(i+1)*width*2]...)
|
|
}
|
|
}
|
|
|
|
var mssImages [4]gocv.Mat
|
|
for i := 0; i < 4; i++ {
|
|
mssImages[i], err = gocv.NewMatFromBytes(height, width, gocv.MatTypeCV16U, mssData[i])
|
|
if err != nil {
|
|
log.Error("Error creating Mat from bytes: ", err)
|
|
return
|
|
}
|
|
|
|
var hist ProbeHistogram
|
|
hist.init0(MSSCameraProbeNum)
|
|
hist.statistical(mssImages[i])
|
|
mssImages[i].Close()
|
|
|
|
mutex.Lock()
|
|
|
|
log.Println("sum MSS histogram...")
|
|
rrc.Histograms[i+1].sum([]*ProbeHistogram{&hist})
|
|
hist.free()
|
|
runtime.GC()
|
|
utils.PrintMemStats()
|
|
|
|
mutex.Unlock()
|
|
}
|
|
}(file)
|
|
}
|
|
|
|
wg.Wait()
|
|
for i := 1; i < 5; i++ {
|
|
log.Println("compute MSS histogram...")
|
|
rrc.Histograms[i].compute()
|
|
log.Println("save MSS gray table matrix.")
|
|
rrc.Histograms[i].saveLUT(filepath.Join(rrc.LUTOutDir, fmt.Sprintf("B%d.LUT", i)))
|
|
}
|
|
|
|
return nil
|
|
}
|