packages feed

accelerate-examples-0.13.0.0: examples/tests/image-processing/IntegralImage.hs

{-# LANGUAGE ScopedTypeVariables, TypeOperators #-}

module IntegralImage where

import Data.Array.Accelerate    as A
import Data.Array.Accelerate.IO as A


-- |The value of each element in an integral image is the sum of all input elements
-- above and to the left, inclusive. It is calculated by performing an inclusive/post
-- scan from left-to-right then top-to-bottom.
--
integralImage :: (Elt a, IsFloating a) => Array DIM2 Word32 -> Acc (Array DIM2 a)
integralImage img = sumTable
  where
    -- scan rows
    rowArr  = reshape (index1 (w * h))  $ arr
    rowSegs = A.replicate (index1 h)    $ unit w
    rowSum  = reshape (index2 w h)      $ scanl1Seg (+) rowArr rowSegs

    -- scan cols
    colArr  = reshape (index1 (h * w))  $ transpose rowSum
    colSegs = A.replicate (index1 w)    $ unit h
    colSum  = reshape (index2 h w)      $ A.scanl1Seg (+) colArr colSegs

    -- transpose back
    sumTable = transpose colSum

    --
    arr     = A.map luminanceOfRGBA32 (use img)
    Z:.w:.h = unlift $ shape arr


-- Run integralImage over the input PGM
--
run :: FilePath -> IO (() -> Acc (Array DIM2 Float))
run file = do
  bmp <- either (error . show) id `fmap` readImageFromBMP file
  return (\() -> integralImage bmp)