This commit is contained in:
nuknal
2024-10-29 16:30:02 +08:00
parent bd93e9f543
commit 9c2d93dff4
2013 changed files with 117 additions and 690917 deletions

View File

@@ -12,7 +12,8 @@ import (
// by performing phase correlation on detected
// edges instead of the raw image
func FindEdges(img0 gocv.Mat) gocv.Mat {
// SKIP: 多光谱各个波段的边缘检测结果不佳
func CV_Canny(img0 gocv.Mat) gocv.Mat {
fmt.Println(img0.Cols(), img0.Rows(), img0.Type().String())
dst8 := gocv.NewMatWithSize(img0.Rows(), img0.Cols(), gocv.MatTypeCV8U)
defer dst8.Close()
@@ -23,3 +24,20 @@ func FindEdges(img0 gocv.Mat) gocv.Mat {
dstEdge.ConvertTo(&dstEdge, gocv.MatTypeCV16U)
return dstEdge
}
func CV_Sobel(img0 gocv.Mat) gocv.Mat {
// x 方向
sobelX := gocv.NewMat()
gocv.Sobel(img0, &sobelX, gocv.MatTypeCV32F, 1, 0, 5, 1.5, 0, gocv.BorderDefault)
sobelX.ConvertTo(&sobelX, gocv.MatTypeCV16U)
// y 方向
sobelY := gocv.NewMat()
gocv.Sobel(img0, &sobelY, gocv.MatTypeCV32F, 0, 1, 5, 1.5, 0, gocv.BorderIsolated)
sobelY.ConvertTo(&sobelY, gocv.MatTypeCV16U)
// 合并
sobelXY := gocv.NewMat()
gocv.Sobel(img0, &sobelXY, gocv.MatTypeCV32F, 1, 1, 5, 1.5, 0, gocv.BorderDefault)
sobelXY.ConvertTo(&sobelXY, gocv.MatTypeCV16U)
return sobelY
}

View File

@@ -171,25 +171,41 @@ func (r *Registrator) CalcDownPhaseCorrelation() error {
blockWidth := r.MssWidth / BlockNW
// 在 MSS 4 个波段上进行配准
err := r.doMSSPhaseCorrelation(r.MssImages[0],
err := r.doPhaseCorrelation(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()
r.fileterPhaseShift([]float64{64, 64, 64, 64}, true)
r.calcMSSDeltaCoeffs(4)
r.DoMSSCoRegistration(false)
// 边缘检测后再做一次配准
// var mssEdges []gocv.Mat
// for band := 0; band < len(r.registeredMssImages); band++ {
// edge := CV_Sobel(r.registeredMssImages[band])
// mssEdges = append(mssEdges, edge)
// }
// r.doPhaseCorrelation(mssEdges[0], mssEdges,
// r.MssHeight, r.MssWidth, blockHeight, blockWidth)
// r.fileterPhaseShift([]float64{5, 5, 5, 5}, false)
// r.calcMSSDeltaCoeffs(4)
// r.DoMSSCoRegistration(true)
// 基于 PAN 图像进行配准
r.phaseShifts[0] = make([]PhaseShiftM, 0)
r.deltaXCoeffs[0] = make([]float64, 0)
r.deltaYCoeffs[0] = make([]float64, 0)
err = r.doMSSPhaseCorrelation(downsampledPanImage,
err = r.doPhaseCorrelation(downsampledPanImage,
[]gocv.Mat{r.registeredMssImages[0]},
r.MssHeight, r.MssWidth, blockHeight, blockWidth)
if err != nil {
return err
}
return r.DoPANCoRegistration()
r.fileterPhaseShift([]float64{30.0}, true)
r.calcMSSDeltaCoeffs(1)
r.DoPANCoRegistration()
return nil
}
// 将MSS升采样采样后计算相位相关的偏移量
@@ -203,13 +219,13 @@ func (r *Registrator) CalcUpPhaseCorrelation() error {
}
// 在 MSS 4 个波段上进行配准
err := r.doMSSPhaseCorrelation(r.MssImages[0],
err := r.doPhaseCorrelation(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()
r.DoMSSCoRegistration(false)
upsampledMssImages := make([]gocv.Mat, MssBands)
for i := 0; i < MssBands; i++ {
@@ -227,13 +243,13 @@ func (r *Registrator) CalcUpPhaseCorrelation() error {
log.Infof("blockHeight=%d, blockWidth=%d", blockHeight, blockWidth)
// 基于 PAN 图像进行配准
err = r.doMSSPhaseCorrelation(r.PanImage,
r.doPhaseCorrelation(r.PanImage,
[]gocv.Mat{upsampledMssImages[0]},
r.MssHeight, r.MssWidth, blockHeight, blockWidth)
return err
return r.DoPANCoRegistration()
}
func (r *Registrator) doMSSPhaseCorrelation(base gocv.Mat,
func (r *Registrator) doPhaseCorrelation(base gocv.Mat,
mssImages []gocv.Mat,
height, width,
blockHeight, blockWidth int) error {
@@ -241,6 +257,8 @@ func (r *Registrator) doMSSPhaseCorrelation(base gocv.Mat,
for band := 0; band < len(mssImages); band++ {
r.phaseShifts[band] = make([]PhaseShiftM, 0)
r.deltaXCoeffs[band] = make([]float64, 0)
r.deltaYCoeffs[band] = make([]float64, 0)
}
for bh := 0; bh < BlockNH; bh++ {
@@ -306,7 +324,7 @@ func (r *Registrator) doMSSPhaseCorrelation(base gocv.Mat,
}
}
return r.calcMSSDeltaCoeffs(len(mssImages))
return nil
}
func (r *Registrator) Clean() {
@@ -335,9 +353,9 @@ func (r *Registrator) calcMSSDeltaCoeffs(bands int) error {
}
// 经验值过滤
if shift.dy < 64.0 {
continue
}
// if shift.dy < 64.0 {
// continue
// }
effectShift++
cx = append(cx, float64(shift.Block.coord.X+shift.Block.width/2)) // MSS 块在X方向没有分块
@@ -355,12 +373,12 @@ func (r *Registrator) calcMSSDeltaCoeffs(bands int) error {
var err error
if r.deltaXCoeffs[i], err = PolynomialFit(cx, dx, 1); err != nil {
log.Error("Error fitting deltaX coeffs: ", err)
return err
continue
}
if r.deltaYCoeffs[i], err = PolynomialFit(cx, dy, 2); err != nil {
log.Error("Error fitting deltaY coeffs: ", err)
return err
continue
}
}
}
@@ -379,11 +397,13 @@ func (r *Registrator) calcMSSDeltaCoeffs(bands int) error {
return nil
}
func (r *Registrator) DoMSSCoRegistration() error {
func (r *Registrator) DoMSSCoRegistration(byEdge bool) error {
for band := 0; band < MssBands; band++ {
if len(r.deltaXCoeffs[band]) < 2 || len(r.deltaYCoeffs[band]) < 3 {
log.Errorf("delta coefficients not calculated, skip co-registration %d", band)
r.registeredMssImages[band] = r.MssImages[band].Clone()
log.Errorf("delta coefficients not calculated, skip co-registration %d", band+1)
if !byEdge {
r.registeredMssImages[band] = r.MssImages[band].Clone()
}
continue
}
@@ -408,13 +428,22 @@ func (r *Registrator) DoMSSCoRegistration() error {
}
log.Println("co-registration for band", band+1)
r.registeredMssImages[band] = gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV16UC1)
gocv.Remap(r.MssImages[band],
&r.registeredMssImages[band],
&mapX, &mapY,
gocv.InterpolationCubic,
gocv.BorderConstant,
color.RGBA{0, 0, 0, 0})
if !byEdge {
r.registeredMssImages[band] = gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV16UC1)
gocv.Remap(r.MssImages[band],
&r.registeredMssImages[band],
&mapX, &mapY,
gocv.InterpolationCubic,
gocv.BorderConstant,
color.RGBA{0, 0, 0, 0})
} else {
gocv.Remap(r.registeredMssImages[band],
&r.registeredMssImages[band],
&mapX, &mapY,
gocv.InterpolationCubic,
gocv.BorderConstant,
color.RGBA{0, 0, 0, 0})
}
mapX.Close()
mapY.Close()
@@ -458,7 +487,6 @@ func (r *Registrator) DoPANCoRegistration() error {
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],
&registeredMSS,

View File

@@ -1,8 +1,10 @@
package producer
import (
"errors"
"image"
"github.com/duke-git/lancet/v2/slice"
log "github.com/sirupsen/logrus"
"gocv.io/x/gocv"
)
@@ -40,3 +42,25 @@ func (r *Registrator) calculateBlockPhaseShift(panBlock, mssBlock gocv.Mat) (goc
return shift, response
}
func (r *Registrator) fileterPhaseShift(thredholds []float64, greaterThan bool) error {
if len(thredholds) > 4 {
return errors.New("thredholds length should be less than 4")
}
for i := 0; i < len(thredholds); i++ {
th := thredholds[i]
r.phaseShifts[i] = slice.Filter(r.phaseShifts[i], func(i int, value PhaseShiftM) bool {
if value.response > 0.999999 {
return false
}
if greaterThan {
return value.dy > float32(th)
}
return value.dy < float32(th)
})
}
return nil
}