92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"image/color"
|
|
"image/jpeg"
|
|
"math"
|
|
"os"
|
|
)
|
|
|
|
// kf3 is a generic convolution 3x3 kernel filter that operatates on
|
|
// images of type image.Gray from the Go standard image library.
|
|
func kf3(k *[9]float64, src, dst *image.Gray) {
|
|
for y := src.Rect.Min.Y; y < src.Rect.Max.Y; y++ {
|
|
for x := src.Rect.Min.X; x < src.Rect.Max.X; x++ {
|
|
var sum float64
|
|
var i int
|
|
for yo := y - 1; yo <= y+1; yo++ {
|
|
for xo := x - 1; xo <= x+1; xo++ {
|
|
if (image.Point{xo, yo}).In(src.Rect) {
|
|
sum += k[i] * float64(src.At(xo, yo).(color.Gray).Y)
|
|
} else {
|
|
sum += k[i] * float64(src.At(x, y).(color.Gray).Y)
|
|
}
|
|
i++
|
|
}
|
|
}
|
|
dst.SetGray(x, y,
|
|
color.Gray{uint8(math.Min(255, math.Max(0, sum)))})
|
|
}
|
|
}
|
|
}
|
|
|
|
var blur = [9]float64{
|
|
1. / 9, 1. / 9, 1. / 9,
|
|
1. / 9, 1. / 9, 1. / 9,
|
|
1. / 9, 1. / 9, 1. / 9}
|
|
|
|
// blurY example function applies blur kernel to Y channel
|
|
// of YCbCr image using generic kernel filter function kf3
|
|
func blurY(src *image.YCbCr) *image.YCbCr {
|
|
dst := *src
|
|
|
|
// catch zero-size image here
|
|
if src.Rect.Max.X == src.Rect.Min.X || src.Rect.Max.Y == src.Rect.Min.Y {
|
|
return &dst
|
|
}
|
|
|
|
// pass Y channels as gray images
|
|
srcGray := image.Gray{src.Y, src.YStride, src.Rect}
|
|
dstGray := srcGray
|
|
dstGray.Pix = make([]uint8, len(src.Y))
|
|
kf3(&blur, &srcGray, &dstGray) // call generic convolution function
|
|
|
|
// complete result
|
|
dst.Y = dstGray.Pix // convolution result
|
|
dst.Cb = append([]uint8{}, src.Cb...) // Cb, Cr are just copied
|
|
dst.Cr = append([]uint8{}, src.Cr...)
|
|
return &dst
|
|
}
|
|
|
|
func main() {
|
|
// Example file used here is Lenna100.jpg from the task "Percentage
|
|
// difference between images"
|
|
f, err := os.Open("Lenna100.jpg")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
img, err := jpeg.Decode(f)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
f.Close()
|
|
y, ok := img.(*image.YCbCr)
|
|
if !ok {
|
|
fmt.Println("expected color jpeg")
|
|
return
|
|
}
|
|
f, err = os.Create("blur.jpg")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
err = jpeg.Encode(f, blurY(y), &jpeg.Options{90})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|