Kernel simplified
This commit is contained in:
parent
eaf9383af0
commit
3fc31c95cc
45
filters.go
45
filters.go
|
@ -23,12 +23,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// color.RGBA64 as array
|
// color.RGBA64 as array
|
||||||
type RGBA [4]uint16
|
type rgba16 [4]uint16
|
||||||
|
|
||||||
// build RGBA from an arbitrary color
|
// build RGBA from an arbitrary color
|
||||||
func toRGBA(c color.Color) RGBA {
|
func toRGBA(c color.Color) rgba16 {
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
return RGBA{uint16(r), uint16(g), uint16(b), uint16(a)}
|
return rgba16{uint16(r), uint16(g), uint16(b), uint16(a)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clampToUint16(x float32) (y uint16) {
|
func clampToUint16(x float32) (y uint16) {
|
||||||
|
@ -41,15 +41,17 @@ func clampToUint16(x float32) (y uint16) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func convolution1d(x float32, kernel func(float32, int) float32, p []RGBA) (c RGBA) {
|
func convolution1d(x float32, kernel func(float32) float32, p []rgba16) (c rgba16) {
|
||||||
x -= float32(int(x))
|
x -= float32(int(x))
|
||||||
|
|
||||||
|
m := float32(len(p)/2-1)
|
||||||
|
|
||||||
var k float32
|
var k float32
|
||||||
var sum float32 = 0
|
var sum float32 = 0
|
||||||
l := [4]float32{0.0, 0.0, 0.0, 0.0}
|
l := [4]float32{0.0, 0.0, 0.0, 0.0}
|
||||||
|
|
||||||
for j := range p {
|
for j := range p {
|
||||||
k = kernel(x, j)
|
k = kernel(x+m-float32(j))
|
||||||
sum += k
|
sum += k
|
||||||
for i := range c {
|
for i := range c {
|
||||||
l[i] += float32(p[j][i]) * k
|
l[i] += float32(p[j][i]) * k
|
||||||
|
@ -61,11 +63,11 @@ func convolution1d(x float32, kernel func(float32, int) float32, p []RGBA) (c RG
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func filter(x, y float32, img image.Image, n int, kernel func(x float32, j int) float32) color.RGBA64 {
|
func filter(x, y float32, img image.Image, n int, kernel func(x float32) float32) color.RGBA64 {
|
||||||
xf, yf := int(x)-n/2+1, int(y)-n/2+1
|
xf, yf := int(x)-n/2+1, int(y)-n/2+1
|
||||||
|
|
||||||
row := make([]RGBA, n)
|
row := make([]rgba16, n)
|
||||||
col := make([]RGBA, n)
|
col := make([]rgba16, n)
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
|
@ -82,8 +84,8 @@ func filter(x, y float32, img image.Image, n int, kernel func(x float32, j int)
|
||||||
// Approximates a value by returning the value of the nearest point.
|
// Approximates a value by returning the value of the nearest point.
|
||||||
func NearestNeighbor(x, y float32, img image.Image) color.RGBA64 {
|
func NearestNeighbor(x, y float32, img image.Image) color.RGBA64 {
|
||||||
n := 2
|
n := 2
|
||||||
kernel := func(x float32, j int) (y float32) {
|
kernel := func(x float32) (y float32) {
|
||||||
if x+0.5 >= float32(j) && x+0.5 < float32(j)+1 {
|
if x >= -0.5 && x < 0.5 {
|
||||||
y = 1
|
y = 1
|
||||||
} else {
|
} else {
|
||||||
y = 0
|
y = 0
|
||||||
|
@ -96,9 +98,8 @@ func NearestNeighbor(x, y float32, img image.Image) color.RGBA64 {
|
||||||
// Bicubic interpolation
|
// Bicubic interpolation
|
||||||
func Bilinear(x, y float32, img image.Image) color.RGBA64 {
|
func Bilinear(x, y float32, img image.Image) color.RGBA64 {
|
||||||
n := 2
|
n := 2
|
||||||
kernel := func(x float32, j int) float32 {
|
kernel := func(x float32) float32 {
|
||||||
xa := float32(math.Abs(float64(x - float32(j))))
|
return 1 - float32(math.Abs(float64(x)))
|
||||||
return 1 - xa
|
|
||||||
}
|
}
|
||||||
return filter(x, y, img, n, kernel)
|
return filter(x, y, img, n, kernel)
|
||||||
}
|
}
|
||||||
|
@ -106,12 +107,12 @@ func Bilinear(x, y float32, img image.Image) color.RGBA64 {
|
||||||
// Bicubic interpolation
|
// Bicubic interpolation
|
||||||
func Bicubic(x, y float32, img image.Image) color.RGBA64 {
|
func Bicubic(x, y float32, img image.Image) color.RGBA64 {
|
||||||
n := 4
|
n := 4
|
||||||
kernel := func(x float32, j int) (y float32) {
|
kernel := func(x float32) (y float32) {
|
||||||
xa := float32(math.Abs(float64(x - float32(j-1))))
|
absX := float32(math.Abs(float64(x)))
|
||||||
if xa <= 1 {
|
if absX <= 1 {
|
||||||
y = 1.5*xa*xa*xa - 2.5*xa*xa + 1
|
y = absX*absX*(1.5*absX-2.5) + 1
|
||||||
} else {
|
} else {
|
||||||
y = -0.5*xa*xa*xa + 2.5*xa*xa - 4*xa + 2
|
y = absX*(absX*(2.5-0.5*absX)-4) + 2
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -121,8 +122,8 @@ func Bicubic(x, y float32, img image.Image) color.RGBA64 {
|
||||||
// Lanczos interpolation (a=2).
|
// Lanczos interpolation (a=2).
|
||||||
func Lanczos2(x, y float32, img image.Image) color.RGBA64 {
|
func Lanczos2(x, y float32, img image.Image) color.RGBA64 {
|
||||||
n := 4
|
n := 4
|
||||||
kernel := func(x float32, j int) float32 {
|
kernel := func(x float32) float32 {
|
||||||
return float32(Sinc(float64(x-float32(j-1)))) * float32(Sinc(float64((x-float32(j-1))/float32(2))))
|
return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(2))))
|
||||||
}
|
}
|
||||||
return filter(x, y, img, n, kernel)
|
return filter(x, y, img, n, kernel)
|
||||||
}
|
}
|
||||||
|
@ -130,8 +131,8 @@ func Lanczos2(x, y float32, img image.Image) color.RGBA64 {
|
||||||
// Lanczos interpolation (a=3).
|
// Lanczos interpolation (a=3).
|
||||||
func Lanczos3(x, y float32, img image.Image) color.RGBA64 {
|
func Lanczos3(x, y float32, img image.Image) color.RGBA64 {
|
||||||
n := 6
|
n := 6
|
||||||
kernel := func(x float32, j int) float32 {
|
kernel := func(x float32) float32 {
|
||||||
return float32(Sinc(float64(x-float32(j-2)))) * float32(Sinc(float64((x-float32(j-2))/float32(3))))
|
return float32(Sinc(float64(x))) * float32(Sinc(float64((x)/float32(3))))
|
||||||
}
|
}
|
||||||
return filter(x, y, img, n, kernel)
|
return filter(x, y, img, n, kernel)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ func init() {
|
||||||
|
|
||||||
func Test_Nearest(t *testing.T) {
|
func Test_Nearest(t *testing.T) {
|
||||||
m := Resize(6, 0, img, NearestNeighbor)
|
m := Resize(6, 0, img, NearestNeighbor)
|
||||||
if m.At(2, 2) != m.At(3, 3) {
|
if m.At(2, 2) == m.At(3, 3) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user