diff --git a/cmd/test.go b/cmd/test.go index bd7d096..b3d448c 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -1,8 +1,6 @@ package main import ( - "strconv" - "github.com/airbusgeo/godal" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -29,10 +27,20 @@ var testCmd = &cobra.Command{ } mv := gocv.Split(*input0_mat) - for i := 0; i < len(mv); i++ { - out := producer.CV_Sobel(mv[i]) - utils.SavePanToGDALGTiff(out, 0, 0, "data/temp/out_"+strconv.Itoa(i)+".tif", 1.3) + // for i := 0; i < len(mv); i++ { + // out := producer.CV_Sobel(mv[i]) + // utils.SavePanToGDALGTiff(out, 0, 0, "data/temp/out_"+strconv.Itoa(i)+".tif", 1.3) + // } + for i := 1; i < len(mv); i++ { + mv[i] = producer.CV_ECCAlign(mv[0], mv[i]) } + + out := gocv.NewMat() + mv[0].ConvertTo(&mv[0], gocv.MatTypeCV16U) + gocv.Merge(mv, &out) + utils.SaveBGRToGDALGTiff(out, 4, 0, 0, 5.2, + []godal.ColorInterp{godal.CIBlue, godal.CIGreen, godal.CIRed, godal.CIUndefined}, + "data/temp/ecc.tif") }, } diff --git a/pkg/producer/ecc_align.go b/pkg/producer/ecc_align.go index 4e7ea61..bba9e9e 100644 --- a/pkg/producer/ecc_align.go +++ b/pkg/producer/ecc_align.go @@ -1,3 +1,54 @@ package producer +import ( + "image" + + log "github.com/sirupsen/logrus" + "gocv.io/x/gocv" +) + // align the image via Enhanced Correlation Coefficient (ECC) algorithm + +func CV_ECCAlign(templateImage, inputImage gocv.Mat) gocv.Mat { + warpMode := gocv.MotionHomography + var warpMatrix gocv.Mat + switch warpMode { + case gocv.MotionHomography: + warpMatrix = gocv.NewMatWithSize(3, 3, gocv.MatTypeCV32FC1) + default: + warpMatrix = gocv.NewMatWithSize(2, 3, gocv.MatTypeCV32FC1) + } + for i := 0; i < warpMatrix.Rows(); i++ { + warpMatrix.SetFloatAt(i, i, 1.0) + } + + criteria := gocv.NewTermCriteria(gocv.Count+gocv.EPS, 1000, 0.0001) + + var mask = gocv.NewMat() + templateImage.ConvertTo(&templateImage, gocv.MatTypeCV32FC1) + inputImage.ConvertTo(&inputImage, gocv.MatTypeCV32FC1) + log.Info("cv::findTransformECC...") + retval := gocv.FindTransformECC(templateImage, inputImage, &warpMatrix, warpMode, criteria, mask, 5) + log.Info("cv::findTransformECC ret:", retval) + + var aligned = gocv.NewMat() + sz := image.Point{inputImage.Cols(), inputImage.Rows()} + if warpMode == gocv.MotionHomography { + gocv.WarpPerspective(inputImage, &aligned, warpMatrix, sz) + } else { + gocv.WarpAffine(inputImage, &aligned, warpMatrix, sz) + } + + aligned.ConvertTo(&aligned, gocv.MatTypeCV16U) + templateImage.ConvertTo(&templateImage, gocv.MatTypeCV16U) + inputImage.ConvertTo(&inputImage, gocv.MatTypeCV16U) + return aligned +} + +func (r *ImgProc) DoECCAlign() error { + r.registeredMssImages[0] = r.MssImages[0].Clone() + for i := 1; i < len(r.MssImages); i++ { + r.registeredMssImages[i] = CV_ECCAlign(r.registeredMssImages[0], r.MssImages[i]) + } + return nil +} diff --git a/pkg/producer/image_registration.go b/pkg/producer/image_registration.go index e84af09..5693038 100644 --- a/pkg/producer/image_registration.go +++ b/pkg/producer/image_registration.go @@ -297,7 +297,7 @@ func (r *ImgProc) doPhaseCorrelation(base gocv.Mat, mssBlock := mssImages[band].Region(rect) // 处理每个分块 - phaseShift, response := r.calculateBlockPhaseShift(panBlock, mssBlock) + phaseShift, response := CV_PhaseCorrelate(panBlock, mssBlock) shiftM.dx = phaseShift.X shiftM.dy = phaseShift.Y shiftM.response = response diff --git a/pkg/producer/phase_correlation.go b/pkg/producer/phase_correlation.go index 5f8ff46..a078351 100644 --- a/pkg/producer/phase_correlation.go +++ b/pkg/producer/phase_correlation.go @@ -22,7 +22,7 @@ type Block struct { coord image.Point // top-left corner of the block in the original image } -func (r *ImgProc) calculateBlockPhaseShift(panBlock, mssBlock gocv.Mat) (gocv.Point2f, float64) { +func CV_PhaseCorrelate(panBlock, mssBlock gocv.Mat) (gocv.Point2f, float64) { pan := gocv.NewMat() mss := gocv.NewMat()