gitee.com/h79/goutils@v1.22.10/common/images/dct.go (about) 1 package images 2 3 import ( 4 "math" 5 "sync" 6 ) 7 8 // DCT1D function returns result of DCT-II. 9 // DCT type II, unscaled. Algorithm by Byeong Gi Lee, 1984. 10 func DCT1D(input []float64) []float64 { 11 temp := make([]float64, len(input)) 12 forwardTransform(input, temp, len(input)) 13 return input 14 } 15 16 func forwardTransform(input, temp []float64, Len int) { 17 if Len == 1 { 18 return 19 } 20 21 halfLen := Len / 2 22 for i := 0; i < halfLen; i++ { 23 x, y := input[i], input[Len-1-i] 24 temp[i] = x + y 25 temp[i+halfLen] = (x - y) / (math.Cos((float64(i)+0.5)*math.Pi/float64(Len)) * 2) 26 } 27 forwardTransform(temp, input, halfLen) 28 forwardTransform(temp[halfLen:], input, halfLen) 29 for i := 0; i < halfLen-1; i++ { 30 input[i*2+0] = temp[i] 31 input[i*2+1] = temp[i+halfLen] + temp[i+halfLen+1] 32 } 33 input[Len-2], input[Len-1] = temp[halfLen-1], temp[Len-1] 34 } 35 36 // DCT2D function returns a result of DCT2D by using the seperable property. 37 func DCT2D(input [][]float64, w int, h int) [][]float64 { 38 output := make([][]float64, h) 39 for i := range output { 40 output[i] = make([]float64, w) 41 } 42 // 加快速度 43 wg := new(sync.WaitGroup) 44 for i := 0; i < h; i++ { 45 wg.Add(1) 46 go func(i int) { 47 cols := DCT1D(input[i]) 48 output[i] = cols 49 wg.Done() 50 }(i) 51 } 52 wg.Wait() 53 54 for i := 0; i < w; i++ { 55 wg.Add(1) 56 in := make([]float64, h) 57 go func(i int) { 58 for j := 0; j < h; j++ { 59 in[j] = output[j][i] 60 } 61 rows := DCT1D(in) 62 for j := 0; j < len(rows); j++ { 63 output[j][i] = rows[j] 64 } 65 wg.Done() 66 }(i) 67 } 68 wg.Wait() 69 return output 70 }