-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A functional image processing library for Haskell. -- @package friday @version 0.2.0.2 -- | Shapes are similar to what you could found in repa. -- Shape are used both for indexes and shapes. -- -- To create a shape/index, use the ix1, ix2, ix3 -- ... helpers : -- --
--   size = ix2 200 100
--   
-- -- To pull values from a shape, use the Z and :. -- constructors : -- --
--   Z :. h :. w = size
--   
module Vision.Primitive.Shape -- | Class of types that can be used as array shapes and indices. class Eq sh => Shape sh shapeRank :: Shape sh => sh -> Int shapeLength :: Shape sh => sh -> Int shapeZero :: Shape sh => sh shapeSucc :: Shape sh => sh -> sh -> sh toLinearIndex :: Shape sh => sh -> sh -> Int fromLinearIndex :: Shape sh => sh -> Int -> sh shapeList :: Shape sh => sh -> [sh] inShape :: Shape sh => sh -> sh -> Bool -- | An index of dimension zero. data Z Z :: Z -- | Our index type, used for both shapes and indices. data (:.) tail head (:.) :: !tail -> !head -> (:.) tail head type DIM0 = Z type DIM1 = DIM0 :. Int type DIM2 = DIM1 :. Int type DIM3 = DIM2 :. Int type DIM4 = DIM3 :. Int type DIM5 = DIM4 :. Int type DIM6 = DIM5 :. Int type DIM7 = DIM6 :. Int type DIM8 = DIM7 :. Int type DIM9 = DIM8 :. Int -- | Helper for index construction. -- -- Use this instead of explicit constructors like (Z :. (x :: -- Int)) The this is sometimes needed to ensure that x is -- constrained to be in Int. ix1 :: Int -> DIM1 ix2 :: Int -> Int -> DIM2 ix3 :: Int -> Int -> Int -> DIM3 ix4 :: Int -> Int -> Int -> Int -> DIM4 ix5 :: Int -> Int -> Int -> Int -> Int -> DIM5 ix6 :: Int -> Int -> Int -> Int -> Int -> Int -> DIM6 ix7 :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> DIM7 ix8 :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> DIM8 ix9 :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> DIM9 instance Show Z instance Read Z instance Eq Z instance Ord Z instance (Show tail, Show head) => Show (tail :. head) instance (Read tail, Read head) => Read (tail :. head) instance (Eq tail, Eq head) => Eq (tail :. head) instance (Ord tail, Ord head) => Ord (tail :. head) instance Storable sh => Storable (sh :. Int) instance Shape sh => Shape (sh :. Int) instance Storable Z instance Shape Z module Vision.Primitive -- | Coordinates inside the image. -- -- Can be constructed using ix2. The first parameter is the y -- coordinate while the second is the x coordinate (i.e. ix2 y -- x). Image origin (ix2 0 0) is located in the -- upper left corner. type Point = DIM2 -- | Size of an object. -- -- Can be constructed using ix2. The first parameter is the height -- while the second is the width (i.e. ix2 h w). type Size = DIM2 data Rect Rect :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Rect rX :: Rect -> {-# UNPACK #-} !Int rY :: Rect -> {-# UNPACK #-} !Int rWidth :: Rect -> {-# UNPACK #-} !Int rHeight :: Rect -> {-# UNPACK #-} !Int -- | Rational coordinates used for interpolations. data RPoint RPoint :: {-# UNPACK #-} !RatioInt -> {-# UNPACK #-} !RatioInt -> RPoint rpX :: RPoint -> {-# UNPACK #-} !RatioInt rpY :: RPoint -> {-# UNPACK #-} !RatioInt instance Show Rect instance Read Rect instance Eq Rect instance Ord Rect instance Show RPoint instance Read RPoint instance Eq RPoint instance Ord RPoint module Vision.Image.Class -- | Determines the number of channels and the type of each pixel of the -- image and how images are represented. class Pixel p where type family PixelChannel p pixNChannels :: Pixel p => p -> Int pixIndex :: Pixel p => p -> Int -> PixelChannel p -- | Provides an abstraction for images which are not defined for each of -- their pixels. The interface is similar to Image except that -- indexing functions don't always return. -- -- Image origin (ix2 0 0) is located in the upper left -- corner. class Storable (ImagePixel i) => MaskedImage i where type family ImagePixel i maskedIndex img = (img `maskedLinearIndex`) . toLinearIndex (shape img) maskedLinearIndex img = (img `maskedIndex`) . fromLinearIndex (shape img) values !img = unfoldr step 0 where !n = shapeLength (shape img) step !i | i >= n = Nothing | Just p <- img `maskedLinearIndex` i = Just (p, i + 1) | otherwise = step (i + 1) shape :: MaskedImage i => i -> Size maskedIndex :: MaskedImage i => i -> Point -> Maybe (ImagePixel i) maskedLinearIndex :: MaskedImage i => i -> Int -> Maybe (ImagePixel i) values :: MaskedImage i => i -> Vector (ImagePixel i) -- | Provides an abstraction over the internal representation of an image. -- -- Image origin is located in the lower left corner. class MaskedImage i => Image i where index img = (img `linearIndex`) . toLinearIndex (shape img) linearIndex img = (img `index`) . fromLinearIndex (shape img) vector img = generate (shapeLength $ shape img) (img `linearIndex`) index :: Image i => i -> Point -> ImagePixel i linearIndex :: Image i => i -> Int -> ImagePixel i vector :: Image i => i -> Vector (ImagePixel i) type ImageChannel i = PixelChannel (ImagePixel i) -- | Provides ways to construct an image from a function. class FromFunction i where type family FromFunctionPixel i fromFunctionLine size line f = fromFunction size (\ pt@(Z :. y :. _) -> f (line y) pt) fromFunctionCol size col f = fromFunction size (\ pt@(Z :. _ :. x) -> f (col x) pt) fromFunctionCached size line col f = fromFunction size (\ pt@(Z :. y :. x) -> f (line y) (col x) pt) fromFunction :: FromFunction i => Size -> (Point -> FromFunctionPixel i) -> i fromFunctionLine :: FromFunction i => Size -> (Int -> a) -> (a -> Point -> FromFunctionPixel i) -> i fromFunctionCol :: (FromFunction i, Storable b) => Size -> (Int -> b) -> (b -> Point -> FromFunctionPixel i) -> i fromFunctionCached :: (FromFunction i, Storable b) => Size -> (Int -> a) -> (Int -> b) -> (a -> b -> Point -> FromFunctionPixel i) -> i -- | Defines a class for images on which a function can be applied. The -- class is different from Functor as there could be some -- constraints and transformations the pixel and image types. class (MaskedImage src, MaskedImage res) => FunctorImage src res map :: FunctorImage src res => (ImagePixel src -> ImagePixel res) -> src -> res -- | Alias of index. (!) :: Image i => i -> Point -> ImagePixel i -- | Alias of maskedIndex. (!?) :: MaskedImage i => i -> Point -> Maybe (ImagePixel i) -- | Returns the number of channels of an image. nChannels :: (Pixel (ImagePixel i), MaskedImage i) => i -> Int -- | Returns an undefined instance of a pixel of the image. This is -- sometime useful to satisfy the type checker as in a call to -- pixNChannels : -- --
--   nChannels img = pixNChannels (pixel img)
--   
pixel :: MaskedImage i => i -> ImagePixel i -- | A typeclass that represents something that can be converted. A -- Convertible a b instance represents an a that can be -- converted to a b. class Convertible a b safeConvert :: Convertible a b => a -> ConvertResult b -- | Convert from one type of data to another. Raises an exception if there -- is an error with the conversion. For a function that does not raise an -- exception in that case, see safeConvert. convert :: Convertible a b => a -> b instance Pixel Bool instance Pixel Double instance Pixel Float instance Pixel Word instance Pixel Word32 instance Pixel Word16 instance Pixel Word8 instance Pixel Int instance Pixel Int32 instance Pixel Int16 -- | Provides a way to estimate the value of a pixel at rational -- coordinates using a linear interpolation. module Vision.Image.Interpolate -- | Provides a way to apply the interpolation to every component of a -- pixel. class Interpolable p interpol :: Interpolable p => (PixelChannel p -> PixelChannel p -> PixelChannel p) -> p -> p -> p -- | Uses a bilinear interpolation to find the value of the pixel at the -- rational coordinates. -- -- Estimates the value of a rational point p using a, -- b, c and d : -- --
--         x1       x2
--   
--   y1    a ------ b
--         -        -
--         -  p     -
--         -        -
--   y2    c ------ d
--   
bilinearInterpol :: (Image i, Interpolable (ImagePixel i), Integral (ImageChannel i)) => i -> RPoint -> ImagePixel i instance Interpolable Bool instance Interpolable Double instance Interpolable Float instance Interpolable Word instance Interpolable Word32 instance Interpolable Word16 instance Interpolable Word8 instance Interpolable Int instance Interpolable Int32 instance Interpolable Int16 module Vision.Image.Type -- | Stores the image content in a Vector. data Manifest p Manifest :: !Size -> !(Vector p) -> Manifest p manifestSize :: Manifest p -> !Size manifestVector :: Manifest p -> !(Vector p) -- | A delayed image is an image which is constructed using a function. -- -- Usually, a delayed image maps each of its pixels over another image. -- Delayed images are useful by avoiding intermediate images in a -- transformation pipeline of images or by avoiding the computation of -- the whole resulting image when only a portion of its pixels will be -- accessed. data Delayed p Delayed :: !Size -> !(Point -> p) -> Delayed p delayedSize :: Delayed p -> !Size delayedFun :: Delayed p -> !(Point -> p) data DelayedMask p DelayedMask :: !Size -> !(Point -> Maybe p) -> DelayedMask p delayedMaskSize :: DelayedMask p -> !Size delayedMaskFun :: DelayedMask p -> !(Point -> Maybe p) -- | Delays an image in its delayed representation. delay :: Image i => i -> Delayed (ImagePixel i) -- | Computes the value of an image into a manifest representation. compute :: (Image i, Storable (ImagePixel i)) => i -> Manifest (ImagePixel i) -- | Forces an image to be in its delayed represenation. Does nothing. delayed :: Delayed p -> Delayed p -- | Forces an image to be in its manifest represenation. Does nothing. manifest :: Manifest p -> Manifest p instance (Eq p, Storable p) => Eq (Manifest p) instance (Ord p, Storable p) => Ord (Manifest p) instance (Show p, Storable p) => Show (Manifest p) instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Manifest p1) (Delayed p2) instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Delayed p1) (Manifest p2) instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Delayed p1) (Delayed p2) instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Manifest p1) (Manifest p2) instance (MaskedImage src, Storable p) => FunctorImage src (DelayedMask p) instance Storable p => FromFunction (DelayedMask p) instance Storable p => MaskedImage (DelayedMask p) instance (Image src, Storable p) => FunctorImage src (Delayed p) instance FromFunction (Delayed p) instance Storable p => Image (Delayed p) instance Storable p => MaskedImage (Delayed p) instance (Image src, Storable p) => FunctorImage src (Manifest p) instance Storable p => FromFunction (Manifest p) instance Storable p => Image (Manifest p) instance Storable p => MaskedImage (Manifest p) instance NFData (Manifest p) module Vision.Image.Grey.Type type Grey = Manifest GreyPixel newtype GreyPixel GreyPixel :: Word8 -> GreyPixel type GreyDelayed = Delayed GreyPixel instance Bits GreyPixel instance Bounded GreyPixel instance Enum GreyPixel instance Eq GreyPixel instance Integral GreyPixel instance Num GreyPixel instance Ord GreyPixel instance Real GreyPixel instance Read GreyPixel instance Show GreyPixel instance Storable GreyPixel instance Interpolable GreyPixel instance Pixel GreyPixel module Vision.Image.HSV.Type -- | 24 bits (3 * 8 bits) HSV image. -- -- The Hue value is in [0..179], Saturation in [0..255] and Value in -- [0..255]. -- -- This image type is more respectful to human eye perception of colors -- and can be converted (using convert) from RGB -- images. -- -- Uses http://en.wikipedia.org/wiki/HSL_and_HSV equations to -- convert from and to RGB. type HSV = Manifest HSVPixel data HSVPixel HSVPixel :: {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> HSVPixel hsvHue :: HSVPixel -> {-# UNPACK #-} !Word8 hsvSat :: HSVPixel -> {-# UNPACK #-} !Word8 hsvValue :: HSVPixel -> {-# UNPACK #-} !Word8 type HSVDelayed = Delayed HSVPixel instance Eq HSVPixel instance Show HSVPixel instance Interpolable HSVPixel instance Pixel HSVPixel instance Storable HSVPixel module Vision.Image.RGBA.Type type RGBA = Manifest RGBAPixel data RGBAPixel RGBAPixel :: {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> RGBAPixel rgbaRed :: RGBAPixel -> {-# UNPACK #-} !Word8 rgbaGreen :: RGBAPixel -> {-# UNPACK #-} !Word8 rgbaBlue :: RGBAPixel -> {-# UNPACK #-} !Word8 rgbaAlpha :: RGBAPixel -> {-# UNPACK #-} !Word8 type RGBADelayed = Delayed RGBAPixel instance Eq RGBAPixel instance Show RGBAPixel instance Interpolable RGBAPixel instance Pixel RGBAPixel instance Storable RGBAPixel module Vision.Image.RGB.Type type RGB = Manifest RGBPixel data RGBPixel RGBPixel :: {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> RGBPixel rgbRed :: RGBPixel -> {-# UNPACK #-} !Word8 rgbGreen :: RGBPixel -> {-# UNPACK #-} !Word8 rgbBlue :: RGBPixel -> {-# UNPACK #-} !Word8 type RGBDelayed = Delayed RGBPixel instance Eq RGBPixel instance Show RGBPixel instance Interpolable RGBPixel instance Pixel RGBPixel instance Storable RGBPixel -- | Contains functions to compute and manipulate histograms as well as -- some images transformations which are histogram-based. -- -- Every polymorphic function is specialised for histograms of -- Int32, Double and Float. Other types can be -- specialized as every polymorphic function is declared -- INLINABLE. module Vision.Histogram data Histogram sh a Histogram :: !sh -> !(Vector a) -> Histogram sh a shape :: Histogram sh a -> !sh -- | Values of the histogram in row-major order. vector :: Histogram sh a -> !(Vector a) -- | Subclass of Shape which defines how to resize a shape so it -- will fit inside a resized histogram. class Shape sh => HistogramShape sh toBin :: HistogramShape sh => sh -> sh -> sh -> sh -- | This class defines how many dimensions a histogram will have and what -- will be the default number of bins. class (Pixel p, Shape (PixelValueSpace p)) => ToHistogram p where type family PixelValueSpace p pixToIndex :: ToHistogram p => p -> PixelValueSpace p domainSize :: ToHistogram p => p -> PixelValueSpace p index :: (Shape sh, Storable a) => Histogram sh a -> sh -> a -- | Alias of index. (!) :: (Shape sh, Storable a) => Histogram sh a -> sh -> a -- | Returns the value at the index as if the histogram was a single -- dimension vector (row-major representation). linearIndex :: (Shape sh, Storable a) => Histogram sh a -> Int -> a map :: (Storable a, Storable b) => (a -> b) -> Histogram sh a -> Histogram sh b -- | Returns all index/value pairs from the histogram. assocs :: (Shape sh, Storable a) => Histogram sh a -> [(sh, a)] -- | Given the number of bins of an histogram and a given pixel, returns -- the corresponding bin. pixToBin :: (HistogramShape (PixelValueSpace p), ToHistogram p) => PixelValueSpace p -> p -> PixelValueSpace p -- | Computes an histogram from a (possibly) multi-channel image. -- -- If the size of the histogram is not given, there will be as many bins -- as the range of values of pixels of the original image (see -- domainSize). -- -- If the size of the histogram is specified, every bin of a given -- dimension will be of the same size (uniform histogram). histogram :: (MaskedImage i, ToHistogram (ImagePixel i), Storable a, Num a, HistogramShape (PixelValueSpace (ImagePixel i))) => Maybe (PixelValueSpace (ImagePixel i)) -> i -> Histogram (PixelValueSpace (ImagePixel i)) a -- | Similar to histogram but adds two dimensions for the y and -- x-coordinates of the sampled points. This way, the histogram will map -- different regions of the original image. -- -- For example, an RGB image will be mapped as Z -- :. red channel :. green channel :. blue channel -- :. y region :. x region. -- -- As there is no reason to create an histogram as large as the number of -- pixels of the image, a size is always needed. histogram2D :: (Image i, ToHistogram (ImagePixel i), Storable a, Num a, HistogramShape (PixelValueSpace (ImagePixel i))) => ((PixelValueSpace (ImagePixel i)) :. Int) :. Int -> i -> Histogram (((PixelValueSpace (ImagePixel i)) :. Int) :. Int) a -- | Reduces a 2D histogram to its linear representation. See resize -- for a reduction of the number of bins of an histogram. -- --
--   histogram == reduce . histogram2D
--   
reduce :: (HistogramShape sh, Storable a, Num a) => Histogram ((sh :. Int) :. Int) a -> Histogram sh a -- | Resizes an histogram to another index shape. See reduce for a -- reduction of the number of dimensions of an histogram. resize :: (HistogramShape sh, Storable a, Num a) => sh -> Histogram sh a -> Histogram sh a -- | Computes the cumulative histogram of another single dimension -- histogram. -- -- C(i) = SUM H(j) for each j in [0..i] where -- C is the cumulative histogram, and H the original -- histogram. cumulative :: (Storable a, Num a) => Histogram DIM1 a -> Histogram DIM1 a -- | Normalizes the histogram so that the sum of the histogram bins is -- equal to the given value (normalisation by the L1 norm). -- -- This is useful to compare two histograms which have been computed from -- images with a different number of pixels. normalize :: (Storable a, Real a, Storable b, Fractional b) => b -> Histogram sh a -> Histogram sh b -- | Equalizes a single channel image by equalising its histogram. -- -- The algorithm equalizes the brightness and increases the contrast of -- the image by mapping each pixel values to the value at the index of -- the cumulative L1-normalized histogram : -- -- N(x, y) = H(I(x, y)) where N is the equalized image, -- I is the image and H the cumulative of the histogram -- normalized over an L1 norm. -- -- See https://en.wikipedia.org/wiki/Histogram_equalization. equalizeImage :: (FunctorImage i i, Integral (ImagePixel i), ToHistogram (ImagePixel i), PixelValueSpace (ImagePixel i) ~ DIM1) => i -> i -- | Computes the Pearson's correlation coefficient between each -- corresponding bins of the two histograms. -- -- A value of 1 implies a perfect correlation, a value of -1 a perfect -- opposition and a value of 0 no correlation at all. -- --
--   compareCorrel = SUM  [ (H1(i) - µ(H1)) (H1(2) - µ(H2)) ]
--                     / (   SQRT [ SUM [ (H1(i) - µ(H1))^2 ] ]
--                         * SQRT [ SUM [ (H2(i) - µ(H2))^2 ] ] )
--   
-- -- Where µ(H) is the average value of the histogram H. -- -- See -- http://en.wikipedia.org/wiki/Pearson_correlation_coefficient. compareCorrel :: (Shape sh, Storable a, Real a, Storable b, Eq b, Floating b) => Histogram sh a -> Histogram sh a -> b -- | Computes the Chi-squared distance between two histograms. -- -- A value of 0 indicates a perfect match. -- -- compareChi = SUM (d(i)) for each indice i of -- the histograms where d(i) = 2 * ((H1(i) - H2(i))^2 / (H1(i) + -- H2(i))). compareChi :: (Shape sh, Storable a, Real a, Storable b, Fractional b) => Histogram sh a -> Histogram sh a -> b -- | Computes the intersection of the two histograms. -- -- The higher the score is, the best the match is. -- -- compareIntersect = SUM (min(H1(i), H2(i)) for each -- indice i of the histograms. compareIntersect :: (Shape sh, Storable a, Num a, Ord a) => Histogram sh a -> Histogram sh a -> a -- | Computed the Earth mover's distance between two histograms. -- -- Current algorithm only supports histograms of one dimension. -- -- See https://en.wikipedia.org/wiki/Earth_mover's_distance. compareEMD :: (Num a, Storable a) => Histogram DIM1 a -> Histogram DIM1 a -> a instance (Eq sh, Eq a, Storable a) => Eq (Histogram sh a) instance (Ord sh, Ord a, Storable a) => Ord (Histogram sh a) instance (Show sh, Show a, Storable a) => Show (Histogram sh a) instance ToHistogram HSVPixel instance ToHistogram RGBPixel instance ToHistogram RGBAPixel instance ToHistogram GreyPixel instance HistogramShape sh => HistogramShape (sh :. Int) instance HistogramShape Z module Vision.Image.Grey.Conversion instance Convertible RGBPixel GreyPixel instance Convertible RGBAPixel GreyPixel instance Convertible GreyPixel GreyPixel module Vision.Image.RGB.Conversion instance Convertible RGBAPixel RGBPixel instance Convertible GreyPixel RGBPixel instance Convertible RGBPixel RGBPixel module Vision.Image.RGBA.Conversion instance Convertible RGBPixel RGBAPixel instance Convertible GreyPixel RGBAPixel instance Convertible RGBAPixel RGBAPixel module Vision.Image.HSV.Conversion instance Convertible HSVPixel RGBAPixel instance Convertible RGBAPixel HSVPixel instance Convertible HSVPixel RGBPixel instance Convertible RGBPixel HSVPixel instance Convertible HSVPixel HSVPixel -- | Contains an stateful image type which can be modified inside a -- ST monad. module Vision.Image.Mutable -- | Class for images which can be constructed from a mutable image. class Image (Freezed i) => MutableImage i where type family Freezed i read !img !ix = img `linearRead` toLinearIndex (mShape img) ix linearRead !img !ix = img `read` fromLinearIndex (mShape img) ix write !img !ix !val = linearWrite img (toLinearIndex (mShape img) ix) val linearWrite !img !ix !val = write img (fromLinearIndex (mShape img) ix) val unsafeFreeze = freeze mShape :: MutableImage i => i s -> Size new :: (MutableImage i, PrimMonad m) => Size -> m (i (PrimState m)) new' :: (MutableImage i, PrimMonad m) => Size -> ImagePixel (Freezed i) -> m (i (PrimState m)) read :: (MutableImage i, PrimMonad m) => i (PrimState m) -> Point -> m (ImagePixel (Freezed i)) linearRead :: (MutableImage i, PrimMonad m) => i (PrimState m) -> Int -> m (ImagePixel (Freezed i)) write :: (MutableImage i, PrimMonad m) => i (PrimState m) -> Point -> ImagePixel (Freezed i) -> m () linearWrite :: (MutableImage i, PrimMonad m) => i (PrimState m) -> Int -> ImagePixel (Freezed i) -> m () freeze :: (MutableImage i, PrimMonad m) => i (PrimState m) -> m (Freezed i) unsafeFreeze :: (MutableImage i, PrimMonad m) => i (PrimState m) -> m (Freezed i) thaw :: (MutableImage i, PrimMonad m) => Freezed i -> m (i (PrimState m)) -- | Creates an immutable image from an ST action creating a mutable -- image. create :: MutableImage i => (forall s. ST s (i s)) -> Freezed i data MutableManifest p s MutableManifest :: !Size -> !(MVector s p) -> MutableManifest p s mmSize :: MutableManifest p s -> !Size mmVector :: MutableManifest p s -> !(MVector s p) instance Storable p => MutableImage (MutableManifest p) -- | Provides high level functions to do geometric transformations on -- images. -- -- Every transformation is been declared INLINABLE so new image -- types could be specialized. module Vision.Image.Transform -- | Defines the set of possible methods for pixel interpolations when -- looking for a pixel at floating point coordinates. data InterpolMethod -- | Selects the top left pixel (fastest). TruncateInteger :: InterpolMethod -- | Selects the nearest pixel (fast). NearestNeighbor :: InterpolMethod -- | Does a double linear interpolation over the four surrounding points -- (slow). Bilinear :: InterpolMethod -- | Maps the content of the image's rectangle in a new image. crop :: (Image i1, FromFunction i2, ImagePixel i1 ~ FromFunctionPixel i2) => Rect -> i1 -> i2 -- | Resizes the Image using the given interpolation method. resize :: (Image i1, Interpolable (ImagePixel i1), FromFunction i2, ImagePixel i1 ~ FromFunctionPixel i2, Integral (ImageChannel i1)) => InterpolMethod -> Size -> i1 -> i2 -- | Reverses the image horizontally. horizontalFlip :: (Image i1, FromFunction i2, ImagePixel i1 ~ FromFunctionPixel i2) => i1 -> i2 -- | Reverses the image vertically. verticalFlip :: (Image i1, FromFunction i2, ImagePixel i1 ~ FromFunctionPixel i2) => i1 -> i2 -- | Paints with a new value the pixels surrounding the given point of the -- image which have the same value as the starting point. floodFill :: (PrimMonad m, MutableImage i, Eq (ImagePixel (Freezed i))) => Point -> ImagePixel (Freezed i) -> i (PrimState m) -> m () -- | Provides high level functions to define and apply filters on images. -- -- Filters are operations on images on which the surrounding of each -- processed pixel is considered according to a kernel. -- -- Please use Filter if you only want to apply filter to images. -- -- To apply a filter to an image, use the apply method: -- --
--   let -- Creates a filter which will blur the image. Uses a Double as
--       -- accumulator of the Gaussian kernel.
--       filter :: Blur GreyPixel Double GreyPixel
--       filter = gaussianBlur 2 Nothing
--   in apply filter img :: Grey
--   
-- -- 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. -- -- The acc type argument of some filters defines the type which -- will be used to store the accumulated value of the kernel (e.g. by -- setting acc to Double in the computation of a Gaussian -- blur, the kernel average will be computed using a Double). module Vision.Image.Filter.Internal -- | Provides an implementation to execute a type of filter. -- -- src is the original image, res the resulting image -- and f the filter. class Filterable src res f apply :: Filterable src res f => f -> src -> res data Filter src kernel init fold acc res Filter :: !Size -> !KernelAnchor -> !kernel -> !(Point -> src -> init) -> !fold -> !(Point -> src -> init -> acc -> res) -> !(BorderInterpolate src) -> Filter src kernel init fold acc res fKernelSize :: Filter src kernel init fold acc res -> !Size fKernelCenter :: Filter src kernel init fold acc res -> !KernelAnchor -- | See Kernel and SeparableKernel. fKernel :: Filter src kernel init fold acc res -> !kernel -- | Computes a constant value for each pixel before applying the kernel. -- -- This value will be passed to fKernel functions and to the -- fPost function. For most filters, fInit will be _ -- _ -> (). fInit :: Filter src kernel init fold acc res -> !(Point -> src -> init) -- | Defines how the accumulated value is initialized. -- -- See FilterFold and FilterFold1. fFold :: Filter src kernel init fold acc res -> !fold -- | This function will be executed after the iteration of the kernel on a -- given point. -- -- Can be used to normalize the accumulated value, for example. fPost :: Filter src kernel init fold acc res -> !(Point -> src -> init -> acc -> res) fInterpol :: Filter src kernel init fold acc res -> !(BorderInterpolate src) -- | 2D filters which are initialized with a value. type BoxFilter src init acc res = Filter src (Kernel src init acc) init (FilterFold acc) acc res -- | 2D filters which are not initialized with a value. type BoxFilter1 src init res = Filter src (Kernel src init src) init FilterFold1 src res -- | Separable 2D filters which are initialized with a value. type SeparableFilter src init acc res = Filter src (SeparableKernel src init acc) init (FilterFold acc) acc res -- | Separable 2D filters which are not initialized with a value. type SeparableFilter1 src init res = Filter src (SeparableKernel src init src) init FilterFold1 src res -- | Defines how the center of the kernel will be determined. data KernelAnchor KernelAnchor :: !Point -> KernelAnchor KernelAnchorCenter :: KernelAnchor -- | A simple 2D kernel. -- -- The kernel function accepts the coordinates in the kernel, the value -- of the pixel at these coordinates (src), the current -- accumulated value and returns a new accumulated value. -- -- Non-separable filters computational complexity grows quadratically -- according to the size of the sides of the kernel. newtype Kernel src init acc Kernel :: (init -> Point -> src -> acc -> acc) -> Kernel src init acc -- | Some kernels can be factorized in two uni-dimensional kernels -- (horizontal and vertical). -- -- Separable filters computational complexity grows linearly according to -- the size of the sides of the kernel. -- -- See http://http://en.wikipedia.org/wiki/Separable_filter. data SeparableKernel src init acc SeparableKernel :: !(init -> DIM1 -> src -> acc -> acc) -> !(init -> DIM1 -> acc -> acc -> acc) -> SeparableKernel src init acc -- | Vertical (column) kernel. skVertical :: SeparableKernel src init acc -> !(init -> DIM1 -> src -> acc -> acc) -- | Horizontal (row) kernel. skHorizontal :: SeparableKernel src init acc -> !(init -> DIM1 -> acc -> acc -> acc) -- | Used to determine the type of the accumulator image used when -- computing separable filters. -- -- src and res are respectively the source and the -- result image types while acc is the pixel type of the -- accumulator. class (Image (SeparableFilterAccumulator src res acc), ImagePixel (SeparableFilterAccumulator src res acc) ~ acc, FromFunction (SeparableFilterAccumulator src res acc), FromFunctionPixel (SeparableFilterAccumulator src res acc) ~ acc) => SeparatelyFiltrable src res acc where type family SeparableFilterAccumulator src res acc -- | Uses the result of the provided function as the initial value of the -- kernel's accumulator, depending on the center coordinates in the -- image. -- -- For most filters, the function will always return the same value (i.e. -- defined as const 0), but this kind of initialization could be -- required for some filters. data FilterFold acc FilterFold :: (Point -> acc) -> FilterFold acc -- | Uses the first pixel in the kernel as initial value. The kernel must -- not be empty and the accumulator type must be the same as the source -- pixel type. -- -- This kind of initialization is needed by morphological filters. data FilterFold1 FilterFold1 :: FilterFold1 -- | Defines how image boundaries are extrapolated by the algorithms. -- -- '|' characters in examples are image borders. data BorderInterpolate a -- | Replicates the first and last pixels of the image. -- --
--   aaaaaa|abcdefgh|hhhhhhh
--   
BorderReplicate :: BorderInterpolate a -- | Reflects the border of the image. -- --
--   fedcba|abcdefgh|hgfedcb
--   
BorderReflect :: BorderInterpolate a -- | Considers that the last pixel of the image is before the first one. -- --
--   cdefgh|abcdefgh|abcdefg
--   
BorderWrap :: BorderInterpolate a -- | Assigns a constant value to out of image pixels. -- --
--   iiiiii|abcdefgh|iiiiiii  with some specified 'i'
--   
BorderConstant :: !a -> BorderInterpolate a -- | Given a method to compute the kernel anchor and the size of the -- kernel, returns the anchor of the kernel as coordinates. kernelAnchor :: KernelAnchor -> Size -> Point -- | Given a method of interpolation, the number of pixel in the dimension -- and an index in this dimension, returns either the index of the -- interpolated pixel or a constant value. borderInterpolate :: BorderInterpolate a -> Int -> Int -> Either Int a type Morphological pix = SeparableFilter1 pix () pix dilate :: Ord pix => Int -> Morphological pix erode :: Ord pix => Int -> Morphological pix type Blur src acc res = SeparableFilter src () acc res -- | Blurs the image by averaging the pixel inside the kernel. -- -- Considers using a type for acc with maxBound acc >= -- maxBound src * (kernel size)². blur :: (Integral src, Integral acc, Num res) => Int -> Blur src acc res -- | Blurs the image by averaging the pixel inside the kernel using a -- Gaussian function. -- -- See http://en.wikipedia.org/wiki/Gaussian_blur gaussianBlur :: (Integral src, Floating acc, RealFrac acc, Storable acc, Integral res) => Int -> Maybe acc -> Blur src acc res type Derivative src res = SeparableFilter src () res res data DerivativeType DerivativeX :: DerivativeType DerivativeY :: DerivativeType -- | 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
--   
-- -- Considers using a signed integer type for res with -- maxBound res >= 16 * maxBound src. scharr :: (Integral src, Integral res) => DerivativeType -> Derivative src res -- | 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. -- -- Considers using a signed integer type for res which is -- significantly larger than src, especially for large kernels. sobel :: (Integral src, Integral res, Storable res) => Int -> DerivativeType -> Derivative src res type Mean src acc res = SeparableFilter src () acc res -- | Computes the average of a kernel of the given size. -- -- This is similar to blur but with a rectangular kernel and a -- Fractional result. mean :: (Integral src, Integral acc, Fractional res) => Size -> SeparableFilter src () acc res instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res, SeparatelyFiltrable src res src_pix) => Filterable src res (SeparableFilter1 src_pix init res_pix) instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res, SeparatelyFiltrable src res acc) => Filterable src res (SeparableFilter src_pix init acc res_pix) instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res) => Filterable src res (BoxFilter1 src_pix init res_pix) instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res) => Filterable src res (BoxFilter src_pix init acc res_pix) instance Storable acc => SeparatelyFiltrable src (Delayed p) acc instance Storable acc => SeparatelyFiltrable src (Manifest p) acc -- | Provides high level filtering functions for images. -- -- Use 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 http://en.wikipedia.org/wiki/Kernel_(image_processing) 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 -- | Provides an implementation to execute a type of filter. -- -- src is the original image, res the resulting image -- and f the filter. class Filterable src res f data Filter src kernel init fold acc res -- | Used to determine the type of the accumulator image used when -- computing separable filters. -- -- src and res are respectively the source and the -- result image types while acc is the pixel type of the -- accumulator. class (Image (SeparableFilterAccumulator src res acc), ImagePixel (SeparableFilterAccumulator src res acc) ~ acc, FromFunction (SeparableFilterAccumulator src res acc), FromFunctionPixel (SeparableFilterAccumulator src res acc) ~ acc) => SeparatelyFiltrable src res acc dilate :: (Image src, Ord (ImagePixel src), FromFunction res, FromFunctionPixel res ~ ImagePixel src, SeparatelyFiltrable src res (ImagePixel src)) => Int -> src -> res erode :: (Image src, Ord (ImagePixel src), FromFunction res, FromFunctionPixel res ~ ImagePixel src, SeparatelyFiltrable src res (ImagePixel src)) => Int -> src -> res -- | 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 -> src -> res -- | Blurs the image by averaging the pixel inside the kernel using a -- Gaussian function. -- -- See http://en.wikipedia.org/wiki/Gaussian_blur gaussianBlur :: (Image src, Integral (ImagePixel src), FromFunction res, Integral (FromFunctionPixel res), Floating acc, RealFrac acc, Storable acc, SeparatelyFiltrable src res acc) => Int -> Maybe acc -> src -> res data DerivativeType DerivativeX :: DerivativeType DerivativeY :: DerivativeType -- | 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 -- | 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 -> DerivativeType -> src -> res -- | 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 module Vision.Image.Threshold -- | Specifies what to do with pixels matching the threshold predicate. -- -- BinaryThreshold a b will replace matching pixels by -- a and non-matchings pixels by b. -- -- Truncate a will replace matching pixels by a. -- -- TruncateInv a will replace non-matching pixels by -- a. data ThresholdType src res BinaryThreshold :: res -> res -> ThresholdType src res Truncate :: src -> ThresholdType src src TruncateInv :: src -> ThresholdType src src -- | Given the thresholding method, a boolean indicating if the pixel match -- the thresholding condition and the pixel, returns the new pixel value. thresholdType :: ThresholdType src res -> Bool -> src -> res -- | Applies the given predicate and threshold policy on the image. threshold :: FunctorImage src res => (ImagePixel src -> Bool) -> ThresholdType (ImagePixel src) (ImagePixel res) -> src -> res -- | Defines how pixels of the kernel of the adaptive threshold will be -- weighted. -- -- With MeanKernel, pixels of the kernel have the same weight. -- -- With GaussianKernel sigma, pixels are weighted -- according to their distance from the thresholded pixel using a -- Gaussian function parametred by sigma. See -- gaussianBlur for details. data AdaptiveThresholdKernel acc MeanKernel :: AdaptiveThresholdKernel acc GaussianKernel :: Maybe acc -> AdaptiveThresholdKernel acc type AdaptiveThreshold src acc res = SeparableFilter src () acc res -- | Compares every pixel to its surrounding ones in the kernel of the -- given radius. adaptiveThreshold :: (Image src, Integral (ImagePixel src), Ord (ImagePixel src), FromFunction res, Integral (FromFunctionPixel res), Storable acc, SeparatelyFiltrable src res acc) => AdaptiveThresholdKernel acc -> Int -> ImagePixel src -> ThresholdType (ImagePixel src) (FromFunctionPixel res) -> src -> res -- | Creates an adaptive thresholding filter to be used with apply. -- -- Use adaptiveThreshold if you only want to apply the filter on -- the image. -- -- Compares every pixel to its surrounding ones in the kernel of the -- given radius. adaptiveThresholdFilter :: (Integral src, Ord src, Storable acc) => AdaptiveThresholdKernel acc -> Int -> src -> ThresholdType src res -> AdaptiveThreshold src acc res -- | Applies a clustering-based image thresholding using the Otsu's method. -- -- See https://en.wikipedia.org/wiki/Otsu's_method. otsu :: (HistogramShape (PixelValueSpace (ImagePixel src)), ToHistogram (ImagePixel src), FunctorImage src res, Ord (ImagePixel src), Num (ImagePixel src), Enum (ImagePixel src)) => ThresholdType (ImagePixel src) (ImagePixel res) -> src -> res -- | This is a sliding concentric window filter (SCW) that uses the ratio -- of the standard deviations of two sliding windows centered on a same -- point to detect regions of interest (ROI). -- --
--   scw sizeWindowA sizeWindowB beta thresType img
--   
-- -- Let σA be the standard deviation of a fist window around a -- pixel and σB be the standard deviation of another window -- around the same pixel. Then the pixel will match the threshold if -- σB / σA >= beta, and will be thresholded according to the -- given ThresholdType. -- -- See -- http://www.academypublisher.com/jcp/vol04/no08/jcp0408771777.pdf. scw :: (Image src, Integral (ImagePixel src), FromFunction dst, Floating stdev, Fractional stdev, Ord stdev, Storable stdev) => Size -> Size -> stdev -> ThresholdType (ImagePixel src) (FromFunctionPixel dst) -> src -> dst -- | SPECIALIZE pragma declarations for grey-scale images. module Vision.Image.Grey.Specialize module Vision.Image.Grey -- | SPECIALIZE pragma declarations for HSV images. module Vision.Image.HSV.Specialize module Vision.Image.HSV -- | SPECIALIZE pragma declarations for RGBA images. module Vision.Image.RGBA.Specialize module Vision.Image.RGBA -- | SPECIALIZE pragma declarations for RGB images. module Vision.Image.RGB.Specialize module Vision.Image.RGB -- | Images are manipulated by their Image and MaskedImage -- type-class instances. -- -- The Manifest representation uses an internal Vector to -- represent the image whereas the Delayed representation uses a -- function to generate pixels. Most transformation functions are generic -- to both representations in the way they apply to any type which -- implements the type-classes. -- -- The Delayed image should be used as intermediate -- representations of complex image transformations. -- -- Please refer to our README file for a detailed usage and -- examples. module Vision.Image module Vision.Detector.Edge -- | Detects edges using the Canny's algorithm. Edges are given the value -- maxBound while non-edges are given the value minBound. -- -- This implementation doesn't perform any noise erasing (as blurring) -- before edge detection. Noisy images might need to be pre-processed -- using a Gaussian blur. -- -- The bidirectional derivative (gradient magnitude) is computed from -- x and y derivatives using sqrt(dx² + dy²). -- -- See http://en.wikipedia.org/wiki/Canny_edge_detector for -- details. -- -- This function is specialized for Grey images but is declared -- INLINABLE to be further specialized for new image types. canny :: (Image src, Integral (ImagePixel src), Bounded res, Eq res, Storable res) => Int -> Int32 -> Int32 -> src -> Manifest res