现在多光谱内配准,然后再和全色配准
This commit is contained in:
@@ -22,9 +22,9 @@ const (
|
||||
PixelBytes = 2
|
||||
PanWidth = payload.PAN_PIXEL_WIDTH // 像素宽度
|
||||
MssWidth = payload.MSS_PIXEL_WIDTH
|
||||
BlockNH = 4
|
||||
BlockNW = 8
|
||||
OverlappedBlockLines = 3000 // 重叠块的行数
|
||||
BlockNH = 8
|
||||
BlockNW = 4
|
||||
OverlappedBlockLines = 1000 // 重叠块的行数
|
||||
DownSampled ResampleMethod = "down_sample_pan"
|
||||
UpSampled ResampleMethod = "up_sample_mss"
|
||||
PanResolution = 1.3 // mm/pixel
|
||||
@@ -170,12 +170,31 @@ func (r *Registrator) CalcDownPhaseCorrelation() error {
|
||||
blockHeight := r.MssHeight / BlockNH
|
||||
blockWidth := r.MssWidth / BlockNW
|
||||
|
||||
return r.calcPhaseCorrelation(downsampledPanImage, r.MssImages, r.MssHeight, r.MssWidth, blockHeight, blockWidth)
|
||||
// 在 MSS 4 个波段上进行配准
|
||||
err := r.doMSSPhaseCorrelation(r.MssImages[0],
|
||||
[]gocv.Mat{r.MssImages[0], r.MssImages[1], r.MssImages[2], r.MssImages[3]},
|
||||
r.MssHeight, r.MssWidth, blockHeight, blockWidth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.DoMSSCoRegistration()
|
||||
|
||||
// 基于 PAN 图像进行配准
|
||||
r.phaseShifts[0] = make([]PhaseShiftM, 0)
|
||||
r.deltaXCoeffs[0] = make([]float64, 0)
|
||||
r.deltaYCoeffs[0] = make([]float64, 0)
|
||||
err = r.doMSSPhaseCorrelation(downsampledPanImage,
|
||||
[]gocv.Mat{r.registeredMssImages[0]},
|
||||
r.MssHeight, r.MssWidth, blockHeight, blockWidth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.DoPANCoRegistration()
|
||||
}
|
||||
|
||||
// 将MSS升采样采样后计算相位相关的偏移量
|
||||
func (r *Registrator) CalcUpPhaseCorrelation() error {
|
||||
log.Fatal("unsuppotted up-resample method")
|
||||
// 确保 MSS 高度是 PAN 高度的 1/4
|
||||
if r.MssHeight*4 != r.PanHeight {
|
||||
err := fmt.Errorf("MSS height is not 1/4 of PAN height, invalid raw file")
|
||||
@@ -183,11 +202,19 @@ func (r *Registrator) CalcUpPhaseCorrelation() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将PAN将采样作为轮廓匹配基准图像
|
||||
var upsampledMssImages [MssBands]gocv.Mat
|
||||
// 在 MSS 4 个波段上进行配准
|
||||
err := r.doMSSPhaseCorrelation(r.MssImages[0],
|
||||
[]gocv.Mat{r.MssImages[0], r.MssImages[1], r.MssImages[2], r.MssImages[3]},
|
||||
r.MssHeight, r.MssWidth, r.MssHeight/BlockNH, r.MssWidth/BlockNW)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.DoMSSCoRegistration()
|
||||
|
||||
upsampledMssImages := make([]gocv.Mat, MssBands)
|
||||
for i := 0; i < MssBands; i++ {
|
||||
upsampledMssImages[i] = gocv.NewMat()
|
||||
gocv.Resize(r.MssImages[i], &upsampledMssImages[i],
|
||||
gocv.Resize(r.registeredMssImages[i], &upsampledMssImages[i],
|
||||
image.Point{X: r.PanWidth, Y: r.PanHeight}, 0, 0, gocv.InterpolationCubic)
|
||||
}
|
||||
|
||||
@@ -199,15 +226,23 @@ func (r *Registrator) CalcUpPhaseCorrelation() error {
|
||||
|
||||
log.Infof("blockHeight=%d, blockWidth=%d", blockHeight, blockWidth)
|
||||
|
||||
return r.calcPhaseCorrelation(r.PanImage, upsampledMssImages, r.PanHeight, r.PanWidth, blockHeight, blockWidth)
|
||||
// 基于 PAN 图像进行配准
|
||||
err = r.doMSSPhaseCorrelation(r.PanImage,
|
||||
[]gocv.Mat{upsampledMssImages[0]},
|
||||
r.MssHeight, r.MssWidth, blockHeight, blockWidth)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Registrator) calcPhaseCorrelation(panImage gocv.Mat,
|
||||
mssImages [4]gocv.Mat,
|
||||
func (r *Registrator) doMSSPhaseCorrelation(base gocv.Mat,
|
||||
mssImages []gocv.Mat,
|
||||
height, width,
|
||||
blockHeight, blockWidth int) error {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for band := 0; band < len(mssImages); band++ {
|
||||
r.phaseShifts[band] = make([]PhaseShiftM, 0)
|
||||
}
|
||||
|
||||
for bh := 0; bh < BlockNH; bh++ {
|
||||
for bw := 0; bw < BlockNW; bw++ {
|
||||
wg.Add(1)
|
||||
@@ -238,8 +273,8 @@ func (r *Registrator) calcPhaseCorrelation(panImage gocv.Mat,
|
||||
x1, y1,
|
||||
)
|
||||
|
||||
panBlock := panImage.Region(rect)
|
||||
for band := 0; band < MssBands; band++ {
|
||||
panBlock := base.Region(rect)
|
||||
for band := 0; band < len(mssImages); band++ {
|
||||
log.Debug("processing band:", band+1, ",block:", bh, rect)
|
||||
mssBlock := mssImages[band].Region(rect)
|
||||
|
||||
@@ -262,7 +297,7 @@ func (r *Registrator) calcPhaseCorrelation(panImage gocv.Mat,
|
||||
|
||||
wg.Wait()
|
||||
|
||||
for i := 0; i < MssBands; i++ {
|
||||
for i := 0; i < len(mssImages); i++ {
|
||||
for _, shift := range r.phaseShifts[i] {
|
||||
if shift.response > 0.4 || shift.dx > 8 || shift.dy > 8 {
|
||||
log.Debugf("Band %d, block %d, dx=%f, dy=%f, response=%f",
|
||||
@@ -271,7 +306,7 @@ func (r *Registrator) calcPhaseCorrelation(panImage gocv.Mat,
|
||||
}
|
||||
}
|
||||
|
||||
return r.calcDeltaCoeffs()
|
||||
return r.calcMSSDeltaCoeffs(len(mssImages))
|
||||
}
|
||||
|
||||
func (r *Registrator) Clean() {
|
||||
@@ -287,9 +322,9 @@ func (r *Registrator) Clean() {
|
||||
r.rgbirImage.Close()
|
||||
}
|
||||
|
||||
func (r *Registrator) calcDeltaCoeffs() error {
|
||||
func (r *Registrator) calcMSSDeltaCoeffs(bands int) error {
|
||||
// 计算每个通道的delta多项式拟合系数
|
||||
for i := 0; i < MssBands; i++ {
|
||||
for i := 0; i < bands; i++ {
|
||||
var cx []float64
|
||||
var dx []float64
|
||||
var dy []float64
|
||||
@@ -330,7 +365,7 @@ func (r *Registrator) calcDeltaCoeffs() error {
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < MssBands; i++ {
|
||||
for i := 0; i < bands; i++ {
|
||||
if len(r.deltaXCoeffs[i]) < 2 || len(r.deltaYCoeffs[i]) < 3 {
|
||||
continue
|
||||
}
|
||||
@@ -344,10 +379,10 @@ func (r *Registrator) calcDeltaCoeffs() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registrator) DoCoRegistration() error {
|
||||
func (r *Registrator) DoMSSCoRegistration() error {
|
||||
for band := 0; band < MssBands; band++ {
|
||||
if len(r.deltaXCoeffs[band]) < 2 || len(r.deltaYCoeffs[band]) < 3 {
|
||||
log.Error("delta coefficients not calculated, skip co-registration")
|
||||
log.Errorf("delta coefficients not calculated, skip co-registration %d", band)
|
||||
r.registeredMssImages[band] = r.MssImages[band].Clone()
|
||||
continue
|
||||
}
|
||||
@@ -367,12 +402,6 @@ func (r *Registrator) DoCoRegistration() error {
|
||||
dy = r.deltaYCoeffs[band][2]*float64(x*x) + r.deltaYCoeffs[band][1]*float64(x) + r.deltaYCoeffs[band][0] + float64(y)
|
||||
}
|
||||
|
||||
// if band+1 == 4 {
|
||||
// fmt.Println("band:", band+1, "x:", x, "map_x:", mx, "y:", y, "map_y:", my)
|
||||
// }
|
||||
|
||||
// mapX.SetFloatAt(y, x, float32(x)+float32(r.deltaXCoeffs[band][0]))
|
||||
// mapY.SetFloatAt(y, x, float32(y)+float32(r.deltaYCoeffs[band][0]))
|
||||
mapX.SetFloatAt(y, x, float32(dx))
|
||||
mapY.SetFloatAt(y, x, float32(dy))
|
||||
}
|
||||
@@ -392,8 +421,58 @@ func (r *Registrator) DoCoRegistration() error {
|
||||
}
|
||||
|
||||
// 裁掉末尾的的 MSS 480 行 和 PAN 的 480*4 行
|
||||
r.PanHeight -= 480 * 4
|
||||
r.MssHeight -= 480
|
||||
r.PanHeight -= 360 * 4
|
||||
r.MssHeight -= 360
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registrator) DoPANCoRegistration() error {
|
||||
if len(r.deltaXCoeffs[0]) < 2 || len(r.deltaYCoeffs[0]) < 3 {
|
||||
log.Error("delta coefficients not calculated, skip co-registration")
|
||||
return nil
|
||||
}
|
||||
|
||||
mapX := gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV32FC1)
|
||||
defer mapX.Close()
|
||||
mapY := gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV32FC1)
|
||||
defer mapY.Close()
|
||||
|
||||
for y := 0; y < r.MssHeight; y++ {
|
||||
for x := 0; x < r.MssWidth; x++ {
|
||||
var dx, dy float64
|
||||
if r.resampleMethod == UpSampled {
|
||||
xx := float64(x * MssBands)
|
||||
yy := float64(y * MssBands)
|
||||
dx = (r.deltaXCoeffs[0][1]*float64(xx) + r.deltaXCoeffs[0][0] + xx) / MssBands
|
||||
dy = (r.deltaYCoeffs[0][2]*float64(xx*xx) + r.deltaYCoeffs[0][1]*float64(xx) + r.deltaYCoeffs[0][0] + yy) / MssBands
|
||||
} else {
|
||||
dx = r.deltaXCoeffs[0][1]*float64(x) + r.deltaXCoeffs[0][0] + float64(x)
|
||||
dy = r.deltaYCoeffs[0][2]*float64(x*x) + r.deltaYCoeffs[0][1]*float64(x) + r.deltaYCoeffs[0][0] + float64(y)
|
||||
}
|
||||
|
||||
mapX.SetFloatAt(y, x, float32(dx))
|
||||
mapY.SetFloatAt(y, x, float32(dy))
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("co-registration for MSS (Align with PAN)")
|
||||
for i := 0; i < MssBands; i++ {
|
||||
log.Infof("r.registeredMssImages[%d]: %v", i, r.registeredMssImages[i].Size())
|
||||
registeredMSS := gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV16UC1)
|
||||
gocv.Remap(r.registeredMssImages[i],
|
||||
®isteredMSS,
|
||||
&mapX, &mapY,
|
||||
gocv.InterpolationCubic,
|
||||
gocv.BorderConstant,
|
||||
color.RGBA{0, 0, 0, 0})
|
||||
|
||||
r.registeredMssImages[i].Close()
|
||||
r.registeredMssImages[i] = registeredMSS
|
||||
}
|
||||
// 裁掉末尾的的 MSS 480 行 和 PAN 的 480*4 行
|
||||
r.PanHeight -= 120 * 4
|
||||
r.MssHeight -= 120
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user