accelerate-examples-1.2.0.0: examples/fft/src-acc/HighPass.hs
{-# LANGUAGE NoImplicitPrelude #-}
module HighPass
where
import Data.Array.Accelerate as A
import Data.Array.Accelerate.IO.Codec.BMP as A
import Data.Array.Accelerate.Data.Colour.RGBA as A
import Data.Array.Accelerate.Math.FFT as A
import Data.Array.Accelerate.Math.DFT.Centre as A
import Data.Array.Accelerate.Data.Complex as A
highpassFFT :: Int -> Acc (Array DIM2 RGBA32) -> Acc (Array DIM2 RGBA32)
highpassFFT cutoff img = img'
where
(r,g,b,a) = A.unzip4
$ A.map (\c -> let RGBA x y z w = unlift c :: RGBA (Exp Word8)
in lift (x,y,z,w) :: Exp (Word8, Word8, Word8, Word8))
$ A.map unpackRGBA8 img
r' = transform cutoff r
g' = transform cutoff g
b' = transform cutoff b
--
img' = A.zipWith4 (\x y z w -> packRGBA8 . lift $ RGBA x y z w) r' g' b' a
transform :: Int -> Acc (Array DIM2 Word8) -> Acc (Array DIM2 Word8)
transform cutoff' arrReal = arrResult
where
cutoff = the (unit (constant cutoff'))
arrComplex :: Acc (Array DIM2 (Complex Float))
arrComplex = A.map (\r -> lift (A.fromIntegral r :+ constant 0)) arrReal
-- Do the 2D transform
arrCentered = centre2D arrComplex
arrFreq = fft2D Forward arrCentered
-- Zap out the low-frequency components
Z :. h :. w = unlift (shape arrReal)
centreX = w `div` 2
centreY = h `div` 2
zap ix = let (Z :. y :. x) = unlift ix
inx = x > centreX - cutoff && x A.< centreX + cutoff
iny = y > centreY - cutoff && y A.< centreY + cutoff
in
inx && iny ? (constant (0 :+ 0), arrFreq A.! ix)
arrFilt = A.generate (A.shape arrFreq) zap
-- Do the inverse transform to get back to image space
arrInv = fft2D Inverse arrFilt
-- The magnitude of the transformed array
arrResult = A.map (A.truncate . magnitude) arrInv