{-# LANGUAGE BangPatterns , FlexibleContexts , TypeFamilies #-} -- | Provides high level filtering functions for images. -- -- Use 'Vision.Image.Filter.Internal' if you want to create new image filters. -- -- Filters are operations on images on which the surrounding of each processed -- pixel is considered according to a kernel. -- -- See for details. -- -- The @radius@ argument of some filters is used to determine the kernel size. -- A radius as of 1 means a kernel of size 3, 2 a kernel of size 5 and so on. -- -- /Note:/ filters are currently not supported on multi-channel images (RGB, -- RGBA ...) are currently not supported. module Vision.Image.Filter ( -- * Classes and type Filterable, Filter, SeparatelyFiltrable -- * Morphological operators , dilate, erode -- * Blur , blur, gaussianBlur -- * Derivation , DerivativeType (..), scharr, sobel -- * Others , mean ) where import Data.Int import Foreign.Storable (Storable) import Vision.Image.Class (MaskedImage (..), Image (..), FromFunction (..)) import Vision.Image.Filter.Internal ( Filterable, Filter, SeparatelyFiltrable (..) , DerivativeType ) import Vision.Primitive (Size) import qualified Vision.Image.Filter.Internal as Internal -- Morphological operators ----------------------------------------------------- dilate, erode :: ( Image src, Ord (ImagePixel src) , FromFunction res, FromFunctionPixel res ~ ImagePixel src , SeparatelyFiltrable src res (ImagePixel src)) => Int -- ^ Kernel radius. -> src -> res dilate radius img = Internal.dilate radius `Internal.apply` img {-# INLINABLE dilate #-} erode radius img = Internal.erode radius `Internal.apply` img {-# INLINABLE erode #-} -- Blur ------------------------------------------------------------------------ -- | Blurs the image by averaging the pixel inside the kernel. -- -- Uses an 'Int32' as accumulator during the averaging operation. blur :: ( Image src, Integral (ImagePixel src) , FromFunction res, Num (FromFunctionPixel res) , SeparatelyFiltrable src res Int32) => Int -- ^ Blur radius. -> src -> res blur radius img = let filt :: (Integral src, Num res) => Internal.Blur src Int32 res filt = Internal.blur radius in filt `Internal.apply` img {-# INLINABLE blur #-} -- | Blurs the image by averaging the pixel inside the kernel using a Gaussian -- function. -- -- See gaussianBlur :: ( Image src, Integral (ImagePixel src) , FromFunction res, Integral (FromFunctionPixel res) , Floating acc, RealFrac acc, Storable acc , SeparatelyFiltrable src res acc) => Int -- ^ Blur radius. -> Maybe acc -- ^ Sigma value of the Gaussian function. If not given, will be -- automatically computed from the radius so that the kernel -- fits 3σ of the distribution. -> src -> res gaussianBlur radius mSig img = Internal.gaussianBlur radius mSig `Internal.apply` img {-# INLINABLE gaussianBlur #-} -- Derivation ------------------------------------------------------------------ -- | Estimates the first derivative using the Scharr's 3x3 kernel. -- -- Convolves the following kernel for the X derivative: -- -- @ -- -3 0 3 -- -10 0 10 -- -3 0 3 -- @ -- -- And this kernel for the Y derivative: -- -- @ -- -3 -10 -3 -- 0 0 0 -- 3 10 3 -- @ -- -- Uses an 'Int32' as accumulator during kernel application. scharr :: ( Image src, Integral (ImagePixel src) , FromFunction res, Integral (FromFunctionPixel res) , Storable (FromFunctionPixel res) , SeparatelyFiltrable src res (FromFunctionPixel res)) => DerivativeType -> src -> res scharr der img = Internal.scharr der `Internal.apply` img {-# INLINABLE scharr #-} -- | Estimates the first derivative using a Sobel's kernel. -- -- Prefer 'scharr' when radius equals @1@ as Scharr's kernel is more accurate -- and is implemented faster. -- -- Uses an 'Int32' as accumulator during kernel application. sobel :: ( Image src, Integral (ImagePixel src) , FromFunction res, Integral (FromFunctionPixel res) , Storable (FromFunctionPixel res) , SeparatelyFiltrable src res (FromFunctionPixel res)) => Int -- ^ Kernel radius. -> DerivativeType -> src -> res sobel radius der img = Internal.sobel radius der `Internal.apply` img {-# INLINABLE sobel #-} -- Others ---------------------------------------------------------------------- -- | Computes the average of a kernel of the given size. -- -- This is similar to 'blur' but with a rectangular kernel and a 'Fractional' -- result. -- -- Uses an 'Int32' as accumulator during the averaging operation. mean :: ( Image src, Integral (ImagePixel src) , FromFunction res, Fractional (FromFunctionPixel res) , SeparatelyFiltrable src res Int32) => Size -> src -> res mean size img = let filt :: (Integral src, Fractional res) => Internal.Mean src Int32 res filt = Internal.mean size in filt `Internal.apply` img {-# INLINABLE mean #-}