diff --git a/cmd/test.go b/cmd/test.go new file mode 100644 index 0000000..6d3d56d --- /dev/null +++ b/cmd/test.go @@ -0,0 +1,43 @@ +package main + +import ( + "strconv" + + "github.com/airbusgeo/godal" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "gocv.io/x/gocv" + "starwiz.cn/sjy01/image-proc/pkg/producer" + "starwiz.cn/sjy01/image-proc/pkg/utils" +) + +var ( + input0 string +) + +var testCmd = &cobra.Command{ + Use: "test", + Short: "test command", + Long: `test command`, + Run: func(cmd *cobra.Command, args []string) { + godal.RegisterAll() + + input0_mat, err := utils.ReadTifftoMat(input0) + if err != nil { + logrus.Error(err) + return + } + + mv := gocv.Split(*input0_mat) + for i := 0; i < len(mv); i++ { + out := producer.FindEdges(mv[i]) + utils.SavePanToGDALGTiff(out, 0, 0, "data/temp/out_"+strconv.Itoa(i)+".tif", 1.3) + } + }, +} + +func init() { + rootCmd.AddCommand(testCmd) + + testCmd.Flags().StringVarP(&input0, "input0", "i", "/Users/lan/workspace/sjy01/image-proc/data/002438/L1A/ROI_7000_10500/MSS/SJY01_MSS_20241014_121246_002438_018_ROI_7000_10500_L1A.tiff", "input0") +} diff --git a/config/config.yaml b/config/config.yaml index 00572f8..d220b8a 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -11,8 +11,8 @@ coregistration: fus_band_order: "RGB" radiation: - pan_remove_hf_noise: false - mss_remove_hf_noise: false + pan_remove_hf_noise: true + mss_remove_hf_noise: true hf_radius_ratio: 0.49 min_hist_level: 0.3 max_hist_level: 0.6 diff --git a/go.mod b/go.mod index a81e9b2..b1e66bc 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,13 @@ require ( github.com/duke-git/lancet/v2 v2.3.1 github.com/dustin/go-humanize v1.0.1 github.com/fsnotify/fsnotify v1.7.0 + github.com/hebl/gofa v1.19.1 github.com/mjibson/go-dsp v0.0.0-20180508042940-11479a337f12 github.com/nuknal/goNum v0.0.0-20240712030226-6452806523e8 github.com/paulmach/orb v0.11.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/viper v1.18.2 + github.com/starainrt/astro v0.0.0-20240209133137-7fd9deb71470 gocv.io/x/gocv v0.36.1 gonum.org/v1/plot v0.14.0 ) @@ -30,7 +32,6 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hebl/gofa v1.19.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jonboulle/clockwork v0.4.0 // indirect github.com/lestrrat-go/strftime v1.0.6 // indirect @@ -50,7 +51,6 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/starainrt/astro v0.0.0-20240209133137-7fd9deb71470 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.mongodb.org/mongo-driver v1.11.4 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect @@ -80,7 +80,6 @@ require ( github.com/spf13/cobra v1.8.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect gonum.org/v1/gonum v0.15.0 ) diff --git a/go.sum b/go.sum index 98e24c5..0884278 100644 --- a/go.sum +++ b/go.sum @@ -1508,7 +1508,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/pkg/fusion/nndiffuse_pan_sharpening.go b/pkg/fusion/nndiffuse_pan_sharpening.go new file mode 100644 index 0000000..48a1b0d --- /dev/null +++ b/pkg/fusion/nndiffuse_pan_sharpening.go @@ -0,0 +1,5 @@ +package fusion + +// https://www.nv5geospatialsoftware.com/docs/nndiffusepansharpening.html +// Sun, W., B. Chen, and D.W. Messinger. +// "Nearest Neighbor Diffusion Based Pan Sharpening Algorithm for Spectral Images." Optical Engineering 53, no. 1 (2014). diff --git a/pkg/producer/ecc_align.go b/pkg/producer/ecc_align.go new file mode 100644 index 0000000..4e7ea61 --- /dev/null +++ b/pkg/producer/ecc_align.go @@ -0,0 +1,3 @@ +package producer + +// align the image via Enhanced Correlation Coefficient (ECC) algorithm diff --git a/pkg/producer/edge_phase_correlation.go b/pkg/producer/edge_phase_correlation.go new file mode 100644 index 0000000..cba08b0 --- /dev/null +++ b/pkg/producer/edge_phase_correlation.go @@ -0,0 +1,22 @@ +package producer + +import ( + "fmt" + + "gocv.io/x/gocv" +) + +// https://medium.com/radix-ai-blog/banishing-the-jitters-stabilizing-satellite-imagery-with-opencvs-phase-correlation-3ba2dc6ac096 + +// tackle the brightness and contrast problem +// by performing phase correlation on detected +// edges instead of the raw image + +func FindEdges(img gocv.Mat) gocv.Mat { + img0 := gocv.IMRead("/Users/lan/workspace/sjy01/image-proc/data/052022/010/PAN/SJY01_PAN_20240520_115428_052022_103_010_L1A.tiff", gocv.IMReadUnchanged) + fmt.Println(img0.Cols(), img0.Rows(), img0.Type().String()) + img0.ConvertTo(&img0, gocv.MatTypeCV8U) + dst := gocv.NewMat() + gocv.Canny(img0, &dst, 100, 200) + return dst +} diff --git a/pkg/producer/phase_correlation.go b/pkg/producer/phase_correlation.go index d43e317..9e96514 100644 --- a/pkg/producer/phase_correlation.go +++ b/pkg/producer/phase_correlation.go @@ -2,7 +2,6 @@ package producer import ( "image" - "math" log "github.com/sirupsen/logrus" "gocv.io/x/gocv" @@ -41,69 +40,3 @@ func (r *Registrator) calculateBlockPhaseShift(panBlock, mssBlock gocv.Mat) (goc return shift, response } - -func (r *Registrator) DoMssPhaseShift() error { - // 使用平均偏移量来做平移变换 - for band := 0; band < MssBands; band++ { - var efficientShiftM int - var xTotal, yTotal float32 - for _, shift := range r.phaseShifts[band] { - if math.IsNaN(float64(shift.dx)) || math.IsNaN(float64(shift.dy)) { - continue - } - efficientShiftM += 1 - xTotal += shift.dx - yTotal += shift.dy - } - dx := xTotal / float32(efficientShiftM) - dy := yTotal / float32(efficientShiftM) - log.Println("Band", band+1, "average shift:", dx, dy, "efficientShiftM:", efficientShiftM) - - translationMat := gocv.NewMatWithSize(2, 3, gocv.MatTypeCV32F) - defer translationMat.Close() - - translationMat.SetFloatAt(0, 0, 1) - translationMat.SetFloatAt(0, 1, 0) - translationMat.SetFloatAt(0, 2, dx) - translationMat.SetFloatAt(1, 0, 0) - translationMat.SetFloatAt(1, 1, 1) - translationMat.SetFloatAt(1, 2, dy) - - alignedMss := gocv.NewMatWithSize(r.MssHeight, r.MssWidth, gocv.MatTypeCV32FC1) - defer alignedMss.Close() - - cvtMss := gocv.NewMat() - defer cvtMss.Close() - - r.MssImages[band].ConvertTo(&cvtMss, gocv.MatTypeCV32FC1) - // 手动平移像素 - outY := math.MaxInt - for y := 0; y < r.MssHeight; y++ { - for x := 0; x < r.MssWidth; x++ { - // 计算新的坐标 - newX := x + int(dx) - newY := y + int(dy) - - // 如果新坐标在图像范围内,进行像素值赋值 - if newX >= 0 && newX < r.MssWidth && newY >= 0 && newY < r.MssHeight { - alignedMss.SetFloatAt(y, x, cvtMss.GetFloatAt(newY, newX)) - } else { - // 如果新坐标不在图像范围内,设置为黑色 - alignedMss.SetFloatAt(y, x, 0) - if outY > y { - outY = y - log.Println("Warning: pixel out of range", x, y) - } - } - } - } - - // gocv.WarpAffine(cvtMss, &alignedMss, translationMat, image.Pt(cvtMss.Size()[1], cvtMss.Size()[0])) - r.registeredMssImages[band] = gocv.NewMat() - alignedMss.ConvertTo(&r.registeredMssImages[band], gocv.MatTypeCV16U) - - log.Println("Band", band+1, "registeredMssImages size:", r.registeredMssImages[band].Size()) - } - - return nil -}