package producer import ( "image" "os" "os/exec" "path/filepath" "strings" log "github.com/sirupsen/logrus" "gocv.io/x/gocv" ) const ( GDALPansharpenCommand = "gdal_pansharpen.py {{.PANGTiff}} {{.MSSGTiff}} {{.FUSGTiff}} -r cubic -of GTiff" ) // IHS 变换是一种将 RGB 空间转换为亮度、色调和饱和度的变换方法 func PansharpenIHS(panImage, mssImage gocv.Mat) gocv.Mat { log.Println("start pansharpen IHS") mss32F := gocv.NewMat() mssImage.ConvertTo(&mss32F, gocv.MatTypeCV32FC4) // 调整 MSS 图像的大小到与 PAN 图像相同的大小 log.Println("resize mss to pan size") mssResized := gocv.NewMat() defer mssResized.Close() gocv.Resize(mss32F, &mssResized, image.Point{X: panImage.Cols(), Y: panImage.Rows()}, 0, 0, gocv.InterpolationCubic) // 将 MSS 图像从 BGR 转换为 HLS mssHLS := gocv.NewMat() defer mssHLS.Close() gocv.CvtColor(mssResized, &mssHLS, gocv.ColorBGRToHLS) // 分离 HLS 通道 只有3个通道 // Hue // Lightness // Saturation hlsChannels := gocv.Split(mssHLS) // 使用 PAN 图像替换亮度分量(Intensity) // hlsChannels[1] = pan32 // 将 PAN 图像转换为与 HLS 亮度分量相同的范围 panFloat := gocv.NewMat() defer panFloat.Close() panImage.ConvertTo(&panFloat, gocv.MatTypeCV32F) log.Println("normalize pan to 0-255") gocv.Normalize(panFloat, &panFloat, 0, 255, gocv.NormMinMax) hlsFloat := gocv.NewMat() defer hlsFloat.Close() hlsChannels[1].ConvertTo(&hlsFloat, gocv.MatTypeCV32F) gocv.Normalize(hlsFloat, &hlsFloat, 0, 255, gocv.NormMinMax) // 替换亮度分量 hlsChannels[1] = panFloat // 合并通道 gocv.Merge(hlsChannels, &mssHLS) // 将图像从 HLS 转换回 BGR fusedImage := gocv.NewMat() defer fusedImage.Close() log.Println("cvt color from HLS to BGR") gocv.CvtColor(mssHLS, &fusedImage, gocv.ColorHLSToBGR) // 交换 B 和 R 通道 channels := gocv.Split(fusedImage) defer channels[0].Close() // B defer channels[1].Close() // G defer channels[2].Close() // R // 交换 B 和 R 通道 swappedChannels := []gocv.Mat{channels[2], channels[1], channels[0]} gocv.Merge(swappedChannels, &fusedImage) fused16U := gocv.NewMat() fusedImage.ConvertTo(&fused16U, gocv.MatTypeCV16UC3) return fused16U } func GDALPansharpen(panTiff, mssTiff, fusedTiff string) error { os.MkdirAll(filepath.Dir(fusedTiff), 0755) // pansharpenCmd := exec.Command("gdal_pansharpen.py", "-w 0.6 -w 0.1 -w 0.3 -w 0 -b 3 -b 2 -b 1", panTiff, mssTiff, fusedTIff, "-r cubic", "-of GTiff") pansharpenCmd := exec.Command("gdal_pansharpen.py", "-w", "0.4", "-w", "0.2", "-w", "0.4", "-w", "0", "-b", "3", "-b", "2", "-b", "1", "-r", "cubic", "-of", "GTiff", panTiff, mssTiff, fusedTiff) log.Println("Run Command: ", pansharpenCmd.String()) pansharpenCmd.Stdout = os.Stdout pansharpenCmd.Stderr = os.Stderr return pansharpenCmd.Run() } func GDALTranslate(srcTiff, dstJPG string) error { if dstJPG == "" { dstJPG = strings.TrimSuffix(srcTiff, ".tiff") + ".jpg" } // gdal_translate -of JPEG -outsize 50% 50% -r bilinear input.tif output.jpg cmd := exec.Command("gdal_translate", "-of", "JPEG", srcTiff, dstJPG) log.Println("Run Command: ", cmd.String()) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }