You have two options, both involve copying the pixels. You can either use the methods provided by the Image
interface, namely At(x,y)
or you can assert the image to one of the image types provided by the image
packet and access the Pix
attribute directly.
Since you will most likely be using a Gray image, you could easily assert your image to type *image.Gray
and access the pixels directly but for the sake of abstraction I did not in my example:
inImage, _, err := image.Decode(inFile)
// error checking
bounds := inImage.Bounds()
realPixels := make([][]float64, bounds.Dy())
for y := 0; y < bounds.Dy(); y++ {
realPixels[y] = make([]float64, bounds.Dx())
for x := 0; x < bounds.Dx(); x++ {
r, _, _, _ := inImage.At(x, y).RGBA()
realPixels[y][x] = float64(r)
}
}
This way you read all the pixels of your image inImage
and store them as float64
values in a two-dimensional slice, ready to be processed by fft.FFT2Real
:
// apply discrete fourier transform on realPixels.
coeffs := fft.FFT2Real(realPixels)
// use inverse fourier transform to transform fft
// values back to the original image.
coeffs = fft.IFFT2(coeffs)
// write everything to a new image
outImage := image.NewGray(bounds)
for y := 0; y < bounds.Dy(); y++ {
for x := 0; x < bounds.Dx(); x++ {
px := uint8(cmplx.Abs(coeffs[y][x]))
outImage.SetGray(x, y, color.Gray{px})
}
}
err = png.Encode(outFile, outImage)
In the code above I applied FFT on the pixels stored in realPixels
and then, to see whether it worked, used inverse FFT on the result. The expected result is the original image.
A full example can be found here.