CV_Sobel
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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],
|
||||
®isteredMSS,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user