Files
sjy01-image-proc/pkg/rrc/rrc.go
nuknal 268076017e RRC
2024-06-13 20:33:42 +08:00

141 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package rrc
import (
"os"
log "github.com/sirupsen/logrus"
"gocv.io/x/gocv"
)
// Relative Radiation Correction
// 采用在轨统计定标方法。利用卫星在轨后获取的常规影像数据,统计每个探元出现的灰度频次。
const (
PANCameraProbeNum = 9344 // 全色探元数
MSSCameraProbeNum = 2336 // 多光谱探元数
MaxGrayLevel = 65536
)
type RRC struct {
PANDataSet []string
MSSDataSet []string
Histograms [5]BandHistogram
}
type BandHistogram struct {
width int // 探元数
N_i []int // N_i 探元像素总数 PAN 0-9343 MSS 0-2335
n_ik [][]int // n_ik 第i探元灰度等级为k的像素数统计 PAN 9343 x 65536 MSS 2335 x 65536
p_ik [][]float64 // p_ik = n_ik / N_i 探元灰度概率密度 PAN 9343 x 65536 MSS 2335 x 65536
m_l []int64 // 具有灰度等级l的像素总数 l = 0-65535
M int64 // 参与直方图统计的总像素数
P_l []float64 // P_l = m_l/M 所有探元的期望直方图灰度等级为l的概率密度
S_ik [][]float64 // S_ik = sum(p_ij),j=0..k 第i个探元直方图灰度等级k的累积概率密度
V_l []float64 // V_l = sum(P_j),j=0..l // 期望直方图灰度级l对应的累积概率密度
Tij [][]float64 // 第i个像元的j灰度等级对应的新的灰度值用于修正图像
}
func (hist *BandHistogram) init(width int) {
hist.width = width
hist.M = 0
hist.N_i = make([]int, width)
hist.n_ik = make([][]int, width)
hist.p_ik = make([][]float64, width)
hist.m_l = make([]int64, MaxGrayLevel)
hist.P_l = make([]float64, MaxGrayLevel)
hist.S_ik = make([][]float64, width)
hist.V_l = make([]float64, MaxGrayLevel)
hist.Tij = make([][]float64, width)
for i := 0; i < width; i++ {
hist.n_ik[i] = make([]int, MaxGrayLevel)
hist.p_ik[i] = make([]float64, MaxGrayLevel)
hist.S_ik[i] = make([]float64, MaxGrayLevel)
hist.Tij[i] = make([]float64, MaxGrayLevel)
}
}
// 统计探元灰度的累积概率密度
func (rrc *RRC) StatisticalPAN(l0 string) error {
data, err := os.ReadFile(l0)
if err != nil {
return err
}
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 err
}
hist := BandHistogram{}
hist.init(PANCameraProbeNum)
rrc.statistical(img, &hist)
rrc.compute(&hist)
rrc.output(&hist, "pan_gray_table.tif")
return nil
}
func (rrc *RRC) statistical(img gocv.Mat, hist *BandHistogram) error {
hist.M += int64(img.Rows() * img.Cols())
for i := 0; i < hist.width; i++ {
hist.N_i[i] += img.Rows()
}
for y := 0; y < img.Rows(); y++ {
for x := 0; x < img.Cols(); x++ {
gray := uint16(img.GetShortAt(x, y))
hist.n_ik[x][gray]++
}
}
for gray := 0; gray < MaxGrayLevel; gray++ {
for i := 0; i < hist.width; i++ {
hist.m_l[gray] += int64(hist.n_ik[i][gray])
}
}
return nil
}
func (rrc *RRC) compute(hist *BandHistogram) error {
width := len(hist.N_i)
for i := 0; i < width; i++ {
for k := 0; k < MaxGrayLevel; k++ {
hist.p_ik[i][k] = float64(hist.n_ik[i][k]) / float64(hist.N_i[i])
}
}
for gray := 0; gray < MaxGrayLevel; gray++ {
hist.P_l[gray] = float64(hist.m_l[gray]) / float64(hist.M)
}
for i := 0; i < width; i++ {
for k := 0; k < MaxGrayLevel; k++ {
hist.S_ik[i][k] = 0
for j := 0; j <= k; j++ {
hist.S_ik[i][k] += hist.p_ik[i][j]
}
}
}
for gray := 0; gray < MaxGrayLevel; gray++ {
hist.V_l[gray] = 0
for j := 0; j <= gray; j++ {
hist.V_l[gray] += hist.P_l[j]
}
}
return nil
}
func (rrc *RRC) output(hist *BandHistogram, referenceTIF string) error {
return nil
}