177 lines
4.2 KiB
Go
177 lines
4.2 KiB
Go
package utils
|
||
|
||
import (
|
||
"time"
|
||
|
||
"github.com/airbusgeo/godal"
|
||
log "github.com/sirupsen/logrus"
|
||
"starwiz.cn/sjy01/image-proc/pkg/calculator"
|
||
|
||
"gocv.io/x/gocv"
|
||
)
|
||
|
||
func SavePanToGDALGTiff(pan gocv.Mat, topLeftX, topLeftY float64, tiffFile string, resolution float64) error {
|
||
// log.Println("Saving PAN image to TIFF file:", tiffFile)
|
||
|
||
width := pan.Cols()
|
||
height := pan.Rows()
|
||
|
||
ds, err := godal.Create(godal.GTiff, tiffFile, 1, godal.UInt16, width, height)
|
||
if err != nil {
|
||
log.Error("Error creating TIFF file: ", err)
|
||
return err
|
||
}
|
||
defer ds.Close()
|
||
|
||
// setGeoTransform(ds, topLeftX, topLeftY, resolution)
|
||
ds.SetMetadata("NBITS", "16")
|
||
|
||
// 将通道的数据转换为uint16数组
|
||
data := make([]uint16, width*height)
|
||
for y := 0; y < height; y++ {
|
||
for x := 0; x < width; x++ {
|
||
data[y*width+x] = uint16(pan.GetShortAt(y, x))
|
||
}
|
||
}
|
||
|
||
band := ds.Bands()[0]
|
||
band.SetColorInterp(godal.CIGray)
|
||
err = band.IO(godal.IOWrite,
|
||
0, 0,
|
||
data,
|
||
width, height,
|
||
godal.PixelSpacing(2),
|
||
godal.LineSpacing(width*2))
|
||
if err != nil {
|
||
log.Error("Failed to write data to band:", err)
|
||
return err
|
||
}
|
||
|
||
log.Info("Saved image to ", tiffFile)
|
||
|
||
return nil
|
||
}
|
||
|
||
func SaveBGRToGDALGTiff(bgr gocv.Mat,
|
||
bands int,
|
||
topLeftX, topLeftY float64,
|
||
resolution float64,
|
||
colorInterps []godal.ColorInterp, tiffFile string) error {
|
||
width := bgr.Cols()
|
||
height := bgr.Rows()
|
||
|
||
// 创建一个二维切片来存储图像数据
|
||
data := make([][]uint16, bands)
|
||
for i := range data {
|
||
data[i] = make([]uint16, width*height)
|
||
}
|
||
|
||
// 从gocv.Mat中提取数据
|
||
for y := 0; y < height; y++ {
|
||
for x := 0; x < width; x++ {
|
||
for b := 0; b < bands; b++ {
|
||
data[b][y*width+x] = uint16(bgr.GetShortAt(y, x*bands+b))
|
||
}
|
||
}
|
||
}
|
||
|
||
ds, err := godal.Create(godal.GTiff,
|
||
tiffFile,
|
||
bands,
|
||
godal.UInt16,
|
||
width, height)
|
||
if err != nil {
|
||
log.Error("Error creating TIFF file: ", err)
|
||
return err
|
||
}
|
||
defer ds.Close()
|
||
|
||
// ds.SetMetadata("NBITS", "16")
|
||
// setGeoTransform(ds, topLeftX, topLeftY, resolution)
|
||
|
||
for b := 0; b < bands; b++ {
|
||
band := ds.Bands()[b]
|
||
band.SetColorInterp(colorInterps[b])
|
||
err := band.IO(godal.IOWrite,
|
||
0, 0,
|
||
data[b],
|
||
width, height,
|
||
godal.PixelSpacing(2),
|
||
godal.LineSpacing(width*2))
|
||
if err != nil {
|
||
log.Error("Failed to write data to band:", err)
|
||
return err
|
||
}
|
||
}
|
||
|
||
log.Info("Saved BGR MSS to ", tiffFile)
|
||
|
||
return nil
|
||
}
|
||
|
||
func setGeoTransform(ds *godal.Dataset, topLeftLng, topLeftLat, resolution float64) {
|
||
// 转换分辨率(米到度)
|
||
resLat := resolution / calculator.MetersPerDegreeLatitude
|
||
resLng := calculator.MetersToDegreesLongitude(resolution, topLeftLat)
|
||
// 设置地理变换(假设左上角坐标为(0,0),PAN每个像素分辨率为1.2米)
|
||
geotransform := [6]float64{
|
||
topLeftLng, // top left x
|
||
resLng, // w-e pixel resolution
|
||
0, // rotation, 0 if image is "north up"
|
||
topLeftLat, // top left y
|
||
0, // rotation, 0 if image is "north up"
|
||
-resLat, // n-s pixel resolution (negative value)
|
||
}
|
||
err := ds.SetGeoTransform(geotransform)
|
||
if err != nil {
|
||
log.Errorf("Failed to set GeoTransform: %v", err)
|
||
return
|
||
}
|
||
|
||
// 设置投影为 WGS84
|
||
srs, err := godal.NewSpatialRefFromEPSG(4326) // gdal.CreateSpatialReference("")
|
||
if err != nil {
|
||
log.Errorf("Failed to set spatial reference: %v", err)
|
||
return
|
||
}
|
||
|
||
projWKT, err := srs.WKT()
|
||
if err != nil {
|
||
log.Errorf("Failed to convert spatial reference to WKT: %v", err)
|
||
return
|
||
}
|
||
|
||
err = ds.SetProjection(projWKT)
|
||
if err != nil {
|
||
log.Errorf("Failed to set projection: %v", err)
|
||
}
|
||
|
||
// 设置一些常见的元数据(可选)
|
||
ds.SetMetadata("TIFFTAG_DATETIME", time.Now().String())
|
||
ds.SetMetadata("TIFFTAG_SOFTWARE", "StarWiz-SJY01-IMAGE-PROC")
|
||
}
|
||
|
||
func ReadTiff(tifFile string) ([][][]float32, error) {
|
||
hDataset, err := godal.Open(tifFile)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
var data [][][]float32
|
||
for _, band := range hDataset.Bands() {
|
||
structure := band.Structure()
|
||
var dataBand [][]float32
|
||
for y := 1; y <= structure.SizeY; y++ {
|
||
scanline := make([]float32, structure.SizeX)
|
||
err = band.Read(0, y, scanline, structure.SizeX, 1)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
dataBand = append(dataBand, scanline)
|
||
}
|
||
|
||
data = append(data, dataBand)
|
||
}
|
||
return data, nil
|
||
}
|