-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A functionnal image processing library for Haskell. -- @package friday @version 0.1 -- | 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 type Point = DIM2 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.Type -- | Determines the number of channels and the type of each pixel of the -- image and how images are represented. class Storable p => 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 is located in the -- lower left corner. class Pixel (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 -- | Stores the image content in a Vector. data Storable p => 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) -- | Returns the number of channels of an image. nChannels :: 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 -- | 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 delayed 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 (Pixel p1, Pixel p2, Storable p1, Convertible p1 p2) => Convertible (Manifest p1) (Delayed p2) instance (Pixel p1, Pixel p2, Storable p2, Convertible p1 p2) => Convertible (Delayed p1) (Manifest p2) instance (Pixel p1, Pixel p2, Convertible p1 p2) => Convertible (Delayed p1) (Delayed p2) instance (Pixel p1, Pixel p2, Storable p1, Storable p2, Convertible p1 p2) => Convertible (Manifest p1) (Manifest p2) instance (MaskedImage src, Pixel p) => FunctorImage src (DelayedMask p) instance Pixel p => FromFunction (DelayedMask p) instance Pixel p => MaskedImage (DelayedMask p) instance (Image src, Pixel p) => FunctorImage src (Delayed p) instance FromFunction (Delayed p) instance Pixel p => Image (Delayed p) instance Pixel p => MaskedImage (Delayed p) instance (Image src, Pixel p) => FunctorImage src (Manifest p) instance Storable p => FromFunction (Manifest p) instance Pixel p => Image (Manifest p) instance Pixel p => MaskedImage (Manifest p) 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 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. -- -- 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. -- -- 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). -- -- To apply a filter to an image, use the apply method: -- --
-- let filter :: SeparableFilter GreyPixel Double GreyPixel -- filter = gaussianBlur 2 Nothing -- in apply filter img :: Grey --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 apply :: Filterable src res f => f -> src -> res data Filter src kernel init acc res Filter :: !Size -> !KernelAnchor -> !kernel -> !init -> !(src -> acc -> res) -> !(BorderInterpolate src) -> Filter src kernel init acc res fKernelSize :: Filter src kernel init acc res -> !Size fKernelCenter :: Filter src kernel init acc res -> !KernelAnchor -- | See Kernel and SeparableKernel. fKernel :: Filter src kernel init acc res -> !kernel -- | Defines how the accumulated value is initialized. -- -- See FilterFold and FilterFold1. fInit :: Filter src kernel init acc res -> !init fPost :: Filter src kernel init acc res -> !(src -> acc -> res) fInterpol :: Filter src kernel init acc res -> !(BorderInterpolate src) -- | 2D filters which are initialized with a value. type BoxFilter src acc res = Filter src (Kernel src acc) (FilterFold acc) acc res -- | 2D filters which are not initialized with a value. type BoxFilter1 src res = Filter src (Kernel src src) FilterFold1 src res -- | Separable 2D filters which are initialized with a value. type SeparableFilter src acc res = Filter src (SeparableKernel src acc) (FilterFold acc) acc res -- | Separable 2D filters which are not initialized with a value. type SeparableFilter1 src res = Filter src (SeparableKernel src src) FilterFold1 src res -- | Defines how the center of the kernel will be determined. data KernelAnchor KernelAnchor :: !DIM2 -> 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 acc Kernel :: (DIM2 -> src -> acc -> acc) -> Kernel src 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 acc SeparableKernel :: !(DIM1 -> src -> acc -> acc) -> !(DIM1 -> acc -> acc -> acc) -> SeparableKernel src acc -- | Vertical (column) kernel. skVertical :: SeparableKernel src acc -> !(DIM1 -> src -> acc -> acc) -- | Horizontal (row) kernel. skHorizontal :: SeparableKernel src acc -> !(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 SeparatelyFiltrable src res acc where type family SeparableFilterAccumulator src res acc -- | Uses an initial value to initialize the filter. data FilterFold acc FilterFold :: 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 -> DIM2 -- | 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 dilate :: Ord src => Int -> SeparableFilter1 src src erode :: Ord src => Int -> SeparableFilter1 src src -- | 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 -> SeparableFilter 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 -> SeparableFilter src acc res data Derivative DerivativeX :: Derivative DerivativeY :: Derivative -- | 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) => Derivative -> SeparableFilter src res 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 -> Derivative -> SeparableFilter src res res instance (Image src, FromFunction res, SeparatelyFiltrable src res src_p, src_p ~ ImagePixel src, res_p ~ FromFunctionPixel res, FromFunction (SeparableFilterAccumulator src res src_p), FromFunctionPixel (SeparableFilterAccumulator src res src_p) ~ src_p, Image (SeparableFilterAccumulator src res src_p), ImagePixel (SeparableFilterAccumulator src res src_p) ~ src_p) => Filterable src res (SeparableFilter1 src_p res_p) instance (Image src, FromFunction res, SeparatelyFiltrable src res acc, src_p ~ ImagePixel src, res_p ~ FromFunctionPixel res, FromFunction (SeparableFilterAccumulator src res acc), FromFunctionPixel (SeparableFilterAccumulator src res acc) ~ acc, Image (SeparableFilterAccumulator src res acc), ImagePixel (SeparableFilterAccumulator src res acc) ~ acc) => Filterable src res (SeparableFilter src_p acc res_p) instance (Image src, FromFunction res, src_p ~ ImagePixel src, res_p ~ FromFunctionPixel res) => Filterable src res (BoxFilter1 src_p res_p) instance (Image src, FromFunction res, src_p ~ ImagePixel src, res_p ~ FromFunctionPixel res) => Filterable src res (BoxFilter src_p acc res_p) instance SeparatelyFiltrable src (Delayed p) acc instance SeparatelyFiltrable src (Manifest p) acc -- | 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.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) -> DIM2 -> 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) -> DIM2 -> 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 Storable p => MutableManifest p s MutableManifest :: !Size -> !(MVector s p) -> MutableManifest p s mmSize :: MutableManifest p s -> !Size mmVector :: MutableManifest p s -> !(MVector s p) instance (Pixel p, Storable p) => MutableImage (MutableManifest p) 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. data ThresholdType src res BinaryThreshold :: res -> res -> ThresholdType src res Truncate :: src -> ThresholdType src src -- | 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 -- | Applies a thresholding adaptively. Compares every pixel to its -- surrounding ones in the kernel of the given radius. adaptiveThreshold :: (Integral src, Num src, Ord src, Storable acc) => AdaptiveThresholdKernel acc -> Int -> src -> ThresholdType src res -> SeparableFilter src acc res -- | 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 () 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 FiniteBits 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.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 module Vision.Image.Grey.Conversion instance Convertible RGBPixel GreyPixel instance Convertible RGBAPixel GreyPixel instance Convertible GreyPixel GreyPixel module Vision.Image.Grey module Vision.Image.RGB.Conversion instance Convertible RGBAPixel RGBPixel instance Convertible GreyPixel RGBPixel instance Convertible RGBPixel RGBPixel module Vision.Image.RGB module Vision.Image.RGBA.Conversion instance Convertible RGBPixel RGBAPixel instance Convertible GreyPixel RGBAPixel instance Convertible RGBAPixel RGBAPixel module Vision.Image.RGBA -- | Uses the DevIL C library to read and write images from and to files. -- -- Note: As the underlier DevIL library is *not* tread-safe, there -- is a global lock which will prevent two load/save calls to be -- performed at the same time. module Vision.Image.Storage data ImageType BMP :: ImageType CUT :: ImageType -- | DirectDraw Surface (.dds). DDS :: ImageType -- | Doom texture. Doom :: ImageType -- | Doom flat texture (floor). DoomFlat :: ImageType GIF :: ImageType ICO :: ImageType JPG :: ImageType -- | Homeworld (.lif). LIF :: ImageType MNG :: ImageType PCD :: ImageType PCX :: ImageType PIC :: ImageType PNG :: ImageType -- | Portable AnyMap (.pbm, .pgm or .ppm). PNM :: ImageType PSD :: ImageType PSP :: ImageType SGI :: ImageType TGA :: ImageType TIFF :: ImageType RAW :: ImageType data StorageImage GreyStorage :: Grey -> StorageImage RGBAStorage :: RGBA -> StorageImage RGBStorage :: RGB -> StorageImage data StorageError -- | Failed to initialise the library. FailedToInit :: StorageError -- | Failed to open the given file. FailedToOpenFile :: StorageError -- | The file could not be loaded based on extension or header. InvalidType :: StorageError -- | Could not allocate memory for the new image data. OutOfMemory :: StorageError -- | Failed to load the image, invalid format. FailedToLoad :: StorageError -- | Failed to convert the loaded image to its Haskell representation. FailedToHaskell :: StorageError -- | Failed to write the image content through the inner DevIL library. FailedToDevil :: StorageError -- | Could not open the file for writing. FailedToSave :: StorageError UnknownError :: (Maybe String) -> StorageError -- | Reads an image into a manifest vector from a file. -- -- If no image type is given, type will be determined automatically. load :: Maybe ImageType -> FilePath -> IO (Either StorageError StorageImage) -- | Reads an image into a manifest vector from a strict -- ByteString. -- -- If no image type is given, type will be determined automatically. TIFF -- images are not supported. loadBS :: Maybe ImageType -> ByteString -> IO (Either StorageError StorageImage) -- | Saves the image to the given file. -- -- Note: The image type is determined by the filename extension. -- Will fail if the file already exists. save :: Convertible i StorageImage => FilePath -> i -> IO (Maybe StorageError) instance Eq ImageType instance Show ImageType instance Eq StorageError instance Show ImageName instance Show StorageError instance Error StorageError instance Convertible StorageImage (Delayed RGBPixel) instance Convertible StorageImage (Delayed RGBAPixel) instance Convertible StorageImage (Delayed GreyPixel) instance Convertible StorageImage (Manifest RGBPixel) instance Convertible StorageImage (Manifest RGBAPixel) instance Convertible StorageImage (Manifest GreyPixel) instance Convertible (Manifest RGBPixel) StorageImage instance Convertible (Manifest RGBAPixel) StorageImage instance Convertible (Manifest GreyPixel) StorageImage instance Convertible StorageImage StorageImage 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.HSV.Conversion instance Convertible HSVPixel RGBAPixel instance Convertible RGBAPixel HSVPixel instance Convertible HSVPixel RGBPixel instance Convertible RGBPixel HSVPixel instance Convertible HSVPixel HSVPixel module Vision.Image.HSV -- | 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 -- | 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 -- | 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)] -- | 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.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, Pixel res) => Int -> Int32 -> Int32 -> src -> Manifest res