packages feed

friday 0.2.2.0 → 0.2.3.0

raw patch · 4 files changed

+470/−2 lines, 4 filesdep +containersdep ~basedep ~transformersnew-uploaderPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: containers

Dependency ranges changed: base, transformers

API changes (from Hackage documentation)

- Vision.Histogram: instance (Eq sh, Eq a, Storable a) => Eq (Histogram sh a)
- Vision.Histogram: instance (Ord sh, Ord a, Storable a) => Ord (Histogram sh a)
- Vision.Histogram: instance (Show sh, Show a, Storable a) => Show (Histogram sh a)
- Vision.Histogram: instance HistogramShape Z
- Vision.Histogram: instance HistogramShape sh => HistogramShape (sh :. Int)
- Vision.Histogram: instance ToHistogram GreyPixel
- Vision.Histogram: instance ToHistogram HSVPixel
- Vision.Histogram: instance ToHistogram RGBAPixel
- Vision.Histogram: instance ToHistogram RGBPixel
- Vision.Histogram: shape :: Histogram sh a -> !sh
- Vision.Histogram: vector :: Histogram sh a -> !(Vector a)
- Vision.Image.Class: instance Pixel Bool
- Vision.Image.Class: instance Pixel Double
- Vision.Image.Class: instance Pixel Float
- Vision.Image.Class: instance Pixel Int
- Vision.Image.Class: instance Pixel Int16
- Vision.Image.Class: instance Pixel Int32
- Vision.Image.Class: instance Pixel Word
- Vision.Image.Class: instance Pixel Word16
- Vision.Image.Class: instance Pixel Word32
- Vision.Image.Class: instance Pixel Word8
- Vision.Image.Conversion: instance Convertible GreyPixel GreyPixel
- Vision.Image.Conversion: instance Convertible GreyPixel HSVPixel
- Vision.Image.Conversion: instance Convertible GreyPixel RGBAPixel
- Vision.Image.Conversion: instance Convertible GreyPixel RGBPixel
- Vision.Image.Conversion: instance Convertible HSVPixel GreyPixel
- Vision.Image.Conversion: instance Convertible HSVPixel HSVPixel
- Vision.Image.Conversion: instance Convertible HSVPixel RGBAPixel
- Vision.Image.Conversion: instance Convertible HSVPixel RGBPixel
- Vision.Image.Conversion: instance Convertible RGBAPixel GreyPixel
- Vision.Image.Conversion: instance Convertible RGBAPixel HSVPixel
- Vision.Image.Conversion: instance Convertible RGBAPixel RGBAPixel
- Vision.Image.Conversion: instance Convertible RGBAPixel RGBPixel
- Vision.Image.Conversion: instance Convertible RGBPixel GreyPixel
- Vision.Image.Conversion: instance Convertible RGBPixel HSVPixel
- Vision.Image.Conversion: instance Convertible RGBPixel RGBAPixel
- Vision.Image.Conversion: instance Convertible RGBPixel RGBPixel
- Vision.Image.Filter.Internal: fFold :: Filter src kernel init fold acc res -> !fold
- Vision.Image.Filter.Internal: fInit :: Filter src kernel init fold acc res -> !(Point -> src -> init)
- Vision.Image.Filter.Internal: fInterpol :: Filter src kernel init fold acc res -> !(BorderInterpolate src)
- Vision.Image.Filter.Internal: fKernel :: Filter src kernel init fold acc res -> !kernel
- Vision.Image.Filter.Internal: fKernelCenter :: Filter src kernel init fold acc res -> !KernelAnchor
- Vision.Image.Filter.Internal: fKernelSize :: Filter src kernel init fold acc res -> !Size
- Vision.Image.Filter.Internal: fPost :: Filter src kernel init fold acc res -> !(Point -> src -> init -> acc -> res)
- Vision.Image.Filter.Internal: instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res) => Filterable src res (BoxFilter src_pix init acc res_pix)
- Vision.Image.Filter.Internal: instance (Image src, FromFunction res, src_pix ~ ImagePixel src, res_pix ~ FromFunctionPixel res) => Filterable src res (BoxFilter1 src_pix init res_pix)
- Vision.Image.Filter.Internal: 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)
- Vision.Image.Filter.Internal: 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)
- Vision.Image.Filter.Internal: instance Storable acc => SeparatelyFiltrable src (Delayed p) acc
- Vision.Image.Filter.Internal: instance Storable acc => SeparatelyFiltrable src (Manifest p) acc
- Vision.Image.Filter.Internal: skHorizontal :: SeparableKernel src init acc -> !(init -> DIM1 -> acc -> acc -> acc)
- Vision.Image.Filter.Internal: skVertical :: SeparableKernel src init acc -> !(init -> DIM1 -> src -> acc -> acc)
- Vision.Image.Grey.Type: instance Bits GreyPixel
- Vision.Image.Grey.Type: instance Bounded GreyPixel
- Vision.Image.Grey.Type: instance Enum GreyPixel
- Vision.Image.Grey.Type: instance Eq GreyPixel
- Vision.Image.Grey.Type: instance Integral GreyPixel
- Vision.Image.Grey.Type: instance Interpolable GreyPixel
- Vision.Image.Grey.Type: instance Num GreyPixel
- Vision.Image.Grey.Type: instance Ord GreyPixel
- Vision.Image.Grey.Type: instance Pixel GreyPixel
- Vision.Image.Grey.Type: instance Read GreyPixel
- Vision.Image.Grey.Type: instance Real GreyPixel
- Vision.Image.Grey.Type: instance Show GreyPixel
- Vision.Image.Grey.Type: instance Storable GreyPixel
- Vision.Image.HSV.Type: hsvHue :: HSVPixel -> {-# UNPACK #-} !Word8
- Vision.Image.HSV.Type: hsvSat :: HSVPixel -> {-# UNPACK #-} !Word8
- Vision.Image.HSV.Type: hsvValue :: HSVPixel -> {-# UNPACK #-} !Word8
- Vision.Image.HSV.Type: instance Eq HSVPixel
- Vision.Image.HSV.Type: instance Interpolable HSVPixel
- Vision.Image.HSV.Type: instance Pixel HSVPixel
- Vision.Image.HSV.Type: instance Show HSVPixel
- Vision.Image.HSV.Type: instance Storable HSVPixel
- Vision.Image.Interpolate: instance Interpolable Bool
- Vision.Image.Interpolate: instance Interpolable Double
- Vision.Image.Interpolate: instance Interpolable Float
- Vision.Image.Interpolate: instance Interpolable Int
- Vision.Image.Interpolate: instance Interpolable Int16
- Vision.Image.Interpolate: instance Interpolable Int32
- Vision.Image.Interpolate: instance Interpolable Word
- Vision.Image.Interpolate: instance Interpolable Word16
- Vision.Image.Interpolate: instance Interpolable Word32
- Vision.Image.Interpolate: instance Interpolable Word8
- Vision.Image.Mutable: instance Storable p => MutableImage (MutableManifest p)
- Vision.Image.Mutable: mmSize :: MutableManifest p s -> !Size
- Vision.Image.Mutable: mmVector :: MutableManifest p s -> !(MVector s p)
- Vision.Image.RGB.Type: instance Eq RGBPixel
- Vision.Image.RGB.Type: instance Interpolable RGBPixel
- Vision.Image.RGB.Type: instance Pixel RGBPixel
- Vision.Image.RGB.Type: instance Show RGBPixel
- Vision.Image.RGB.Type: instance Storable RGBPixel
- Vision.Image.RGB.Type: rgbBlue :: RGBPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGB.Type: rgbGreen :: RGBPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGB.Type: rgbRed :: RGBPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGBA.Type: instance Eq RGBAPixel
- Vision.Image.RGBA.Type: instance Interpolable RGBAPixel
- Vision.Image.RGBA.Type: instance Pixel RGBAPixel
- Vision.Image.RGBA.Type: instance Show RGBAPixel
- Vision.Image.RGBA.Type: instance Storable RGBAPixel
- Vision.Image.RGBA.Type: rgbaAlpha :: RGBAPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGBA.Type: rgbaBlue :: RGBAPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGBA.Type: rgbaGreen :: RGBAPixel -> {-# UNPACK #-} !Word8
- Vision.Image.RGBA.Type: rgbaRed :: RGBAPixel -> {-# UNPACK #-} !Word8
- Vision.Image.Threshold: BinaryThreshold :: res -> res -> ThresholdType src res
- Vision.Image.Threshold: GaussianKernel :: Maybe acc -> AdaptiveThresholdKernel acc
- Vision.Image.Threshold: MeanKernel :: AdaptiveThresholdKernel acc
- Vision.Image.Threshold: Truncate :: src -> ThresholdType src src
- Vision.Image.Threshold: TruncateInv :: src -> ThresholdType src src
- Vision.Image.Type: delayedFun :: Delayed p -> !(Point -> p)
- Vision.Image.Type: delayedMaskFun :: DelayedMask p -> !(Point -> Maybe p)
- Vision.Image.Type: delayedMaskSize :: DelayedMask p -> !Size
- Vision.Image.Type: delayedSize :: Delayed p -> !Size
- Vision.Image.Type: instance (Eq p, Storable p) => Eq (Manifest p)
- Vision.Image.Type: instance (Image src, Storable p) => FunctorImage src (Delayed p)
- Vision.Image.Type: instance (Image src, Storable p) => FunctorImage src (Manifest p)
- Vision.Image.Type: instance (MaskedImage src, Storable p) => FunctorImage src (DelayedMask p)
- Vision.Image.Type: instance (Ord p, Storable p) => Ord (Manifest p)
- Vision.Image.Type: instance (Show p, Storable p) => Show (Manifest p)
- Vision.Image.Type: instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Delayed p1) (Delayed p2)
- Vision.Image.Type: instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Delayed p1) (Manifest p2)
- Vision.Image.Type: instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Manifest p1) (Delayed p2)
- Vision.Image.Type: instance (Storable p1, Storable p2, Convertible p1 p2) => Convertible (Manifest p1) (Manifest p2)
- Vision.Image.Type: instance FromFunction (Delayed p)
- Vision.Image.Type: instance NFData (Manifest p)
- Vision.Image.Type: instance Storable p => FromFunction (DelayedMask p)
- Vision.Image.Type: instance Storable p => FromFunction (Manifest p)
- Vision.Image.Type: instance Storable p => Image (Delayed p)
- Vision.Image.Type: instance Storable p => Image (Manifest p)
- Vision.Image.Type: instance Storable p => MaskedImage (Delayed p)
- Vision.Image.Type: instance Storable p => MaskedImage (DelayedMask p)
- Vision.Image.Type: instance Storable p => MaskedImage (Manifest p)
- Vision.Image.Type: manifestSize :: Manifest p -> !Size
- Vision.Image.Type: manifestVector :: Manifest p -> !(Vector p)
- Vision.Primitive: instance Eq RPoint
- Vision.Primitive: instance Eq Rect
- Vision.Primitive: instance Ord RPoint
- Vision.Primitive: instance Ord Rect
- Vision.Primitive: instance Read RPoint
- Vision.Primitive: instance Read Rect
- Vision.Primitive: instance Show RPoint
- Vision.Primitive: instance Show Rect
- Vision.Primitive: rHeight :: Rect -> {-# UNPACK #-} !Int
- Vision.Primitive: rWidth :: Rect -> {-# UNPACK #-} !Int
- Vision.Primitive: rX :: Rect -> {-# UNPACK #-} !Int
- Vision.Primitive: rY :: Rect -> {-# UNPACK #-} !Int
- Vision.Primitive: rpX :: RPoint -> {-# UNPACK #-} !RatioInt
- Vision.Primitive: rpY :: RPoint -> {-# UNPACK #-} !RatioInt
- Vision.Primitive.Shape: instance (Eq tail, Eq head) => Eq (tail :. head)
- Vision.Primitive.Shape: instance (Ord tail, Ord head) => Ord (tail :. head)
- Vision.Primitive.Shape: instance (Read tail, Read head) => Read (tail :. head)
- Vision.Primitive.Shape: instance (Show tail, Show head) => Show (tail :. head)
- Vision.Primitive.Shape: instance Eq Z
- Vision.Primitive.Shape: instance Ord Z
- Vision.Primitive.Shape: instance Read Z
- Vision.Primitive.Shape: instance Shape Z
- Vision.Primitive.Shape: instance Shape sh => Shape (sh :. Int)
- Vision.Primitive.Shape: instance Show Z
- Vision.Primitive.Shape: instance Storable Z
- Vision.Primitive.Shape: instance Storable sh => Storable (sh :. Int)
+ Vision.Histogram: [shape] :: Histogram sh a -> !sh
+ Vision.Histogram: [vector] :: Histogram sh a -> !(Vector a)
+ Vision.Histogram: instance (Foreign.Storable.Storable a, GHC.Show.Show a, GHC.Show.Show sh) => GHC.Show.Show (Vision.Histogram.Histogram sh a)
+ Vision.Histogram: instance (GHC.Classes.Eq a, GHC.Classes.Eq sh, Foreign.Storable.Storable a) => GHC.Classes.Eq (Vision.Histogram.Histogram sh a)
+ Vision.Histogram: instance (GHC.Classes.Ord a, GHC.Classes.Ord sh, Foreign.Storable.Storable a) => GHC.Classes.Ord (Vision.Histogram.Histogram sh a)
+ Vision.Histogram: instance Vision.Histogram.HistogramShape Vision.Primitive.Shape.Z
+ Vision.Histogram: instance Vision.Histogram.HistogramShape sh => Vision.Histogram.HistogramShape (sh Vision.Primitive.Shape.:. GHC.Types.Int)
+ Vision.Histogram: instance Vision.Histogram.ToHistogram Vision.Image.Grey.Type.GreyPixel
+ Vision.Histogram: instance Vision.Histogram.ToHistogram Vision.Image.HSV.Type.HSVPixel
+ Vision.Histogram: instance Vision.Histogram.ToHistogram Vision.Image.RGB.Type.RGBPixel
+ Vision.Histogram: instance Vision.Histogram.ToHistogram Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Histogram: type family PixelValueSpace p;
+ Vision.Histogram: }
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Int.Int16
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Int.Int32
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Types.Bool
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Types.Double
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Types.Float
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Types.Int
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Types.Word
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Word.Word16
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Word.Word32
+ Vision.Image.Class: instance Vision.Image.Class.Pixel GHC.Word.Word8
+ Vision.Image.Class: type family FromFunctionPixel i;
+ Vision.Image.Class: }
+ Vision.Image.Contour: AllOutlines :: ContourDrawStyle
+ Vision.Image.Contour: Contour :: OneContour -> [OneContour] -> Contour
+ Vision.Image.Contour: Contours :: Map ContourId Contour -> !(Vector Int) -> Contours
+ Vision.Image.Contour: Fill :: ContourDrawStyle
+ Vision.Image.Contour: FillWithHoles :: ContourDrawStyle
+ Vision.Image.Contour: OuterOutline :: ContourDrawStyle
+ Vision.Image.Contour: [contourOutlines] :: Contours -> Map ContourId Contour
+ Vision.Image.Contour: [contourSizes] :: Contours -> !(Vector Int)
+ Vision.Image.Contour: [innerContours] :: Contour -> [OneContour]
+ Vision.Image.Contour: [outerContour] :: Contour -> OneContour
+ Vision.Image.Contour: allContourIds :: Contours -> [ContourId]
+ Vision.Image.Contour: contourPerimeter :: Contours -> ContourId -> [Point]
+ Vision.Image.Contour: contourSize :: Contours -> ContourId -> Int
+ Vision.Image.Contour: contours :: (Image src, Num (ImagePixel src), Eq (ImagePixel src)) => src -> Contours
+ Vision.Image.Contour: data Contour
+ Vision.Image.Contour: data ContourDrawStyle
+ Vision.Image.Contour: data ContourId
+ Vision.Image.Contour: data Contours
+ Vision.Image.Contour: drawContour :: Contours -> Size -> ContourDrawStyle -> ContourId -> Grey
+ Vision.Image.Contour: drawContours :: Contours -> Size -> ContourDrawStyle -> [ContourId] -> Grey
+ Vision.Image.Contour: instance Foreign.Storable.Storable Vision.Image.Contour.ContourId
+ Vision.Image.Contour: instance GHC.Classes.Eq Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Classes.Eq Vision.Image.Contour.ContourId
+ Vision.Image.Contour: instance GHC.Classes.Eq Vision.Image.Contour.ContourPos
+ Vision.Image.Contour: instance GHC.Classes.Eq Vision.Image.Contour.ContourType
+ Vision.Image.Contour: instance GHC.Classes.Ord Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Classes.Ord Vision.Image.Contour.ContourId
+ Vision.Image.Contour: instance GHC.Enum.Bounded Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Enum.Bounded Vision.Image.Contour.ContourPos
+ Vision.Image.Contour: instance GHC.Enum.Enum Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Enum.Enum Vision.Image.Contour.ContourPos
+ Vision.Image.Contour: instance GHC.Num.Num Vision.Image.Contour.ContourId
+ Vision.Image.Contour: instance GHC.Read.Read Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Show.Show Vision.Image.Contour.ContourDrawStyle
+ Vision.Image.Contour: instance GHC.Show.Show Vision.Image.Contour.ContourId
+ Vision.Image.Contour: instance GHC.Show.Show Vision.Image.Contour.ContourPos
+ Vision.Image.Contour: lookupContour :: Contours -> ContourId -> Maybe Contour
+ Vision.Image.Contour: rowContour :: [ContourValue] -> RowContour
+ Vision.Image.Contour: type ContourValue = (Point, Bool)
+ Vision.Image.Contour: type OneContour = Vector ContourValue
+ Vision.Image.Contour: type RowContour = Vector (Point, Point)
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.Grey.Type.GreyPixel Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.Grey.Type.GreyPixel Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.Grey.Type.GreyPixel Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.Grey.Type.GreyPixel Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.HSV.Type.HSVPixel Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.HSV.Type.HSVPixel Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.HSV.Type.HSVPixel Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.HSV.Type.HSVPixel Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGB.Type.RGBPixel Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGB.Type.RGBPixel Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGB.Type.RGBPixel Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGB.Type.RGBPixel Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGBA.Type.RGBAPixel Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGBA.Type.RGBAPixel Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGBA.Type.RGBAPixel Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.Conversion: instance Data.Convertible.Base.Convertible Vision.Image.RGBA.Type.RGBAPixel Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.Filter.Internal: [fFold] :: Filter src kernel init fold acc res -> !fold
+ Vision.Image.Filter.Internal: [fInit] :: Filter src kernel init fold acc res -> !(Point -> src -> init)
+ Vision.Image.Filter.Internal: [fInterpol] :: Filter src kernel init fold acc res -> !(BorderInterpolate src)
+ Vision.Image.Filter.Internal: [fKernelCenter] :: Filter src kernel init fold acc res -> !KernelAnchor
+ Vision.Image.Filter.Internal: [fKernelSize] :: Filter src kernel init fold acc res -> !Size
+ Vision.Image.Filter.Internal: [fKernel] :: Filter src kernel init fold acc res -> !kernel
+ Vision.Image.Filter.Internal: [fPost] :: Filter src kernel init fold acc res -> !(Point -> src -> init -> acc -> res)
+ Vision.Image.Filter.Internal: [skHorizontal] :: SeparableKernel src init acc -> !(init -> DIM1 -> acc -> acc -> acc)
+ Vision.Image.Filter.Internal: [skVertical] :: SeparableKernel src init acc -> !(init -> DIM1 -> src -> acc -> acc)
+ Vision.Image.Filter.Internal: instance (Vision.Image.Class.Image src, Vision.Image.Class.FromFunction res, src_pix ~ Vision.Image.Class.ImagePixel src, res_pix ~ Vision.Image.Class.FromFunctionPixel res) => Vision.Image.Filter.Internal.Filterable src res (Vision.Image.Filter.Internal.BoxFilter src_pix init acc res_pix)
+ Vision.Image.Filter.Internal: instance (Vision.Image.Class.Image src, Vision.Image.Class.FromFunction res, src_pix ~ Vision.Image.Class.ImagePixel src, res_pix ~ Vision.Image.Class.FromFunctionPixel res) => Vision.Image.Filter.Internal.Filterable src res (Vision.Image.Filter.Internal.BoxFilter1 src_pix init res_pix)
+ Vision.Image.Filter.Internal: instance (Vision.Image.Class.Image src, Vision.Image.Class.FromFunction res, src_pix ~ Vision.Image.Class.ImagePixel src, res_pix ~ Vision.Image.Class.FromFunctionPixel res, Vision.Image.Filter.Internal.SeparatelyFiltrable src res acc) => Vision.Image.Filter.Internal.Filterable src res (Vision.Image.Filter.Internal.SeparableFilter src_pix init acc res_pix)
+ Vision.Image.Filter.Internal: instance (Vision.Image.Class.Image src, Vision.Image.Class.FromFunction res, src_pix ~ Vision.Image.Class.ImagePixel src, res_pix ~ Vision.Image.Class.FromFunctionPixel res, Vision.Image.Filter.Internal.SeparatelyFiltrable src res src_pix) => Vision.Image.Filter.Internal.Filterable src res (Vision.Image.Filter.Internal.SeparableFilter1 src_pix init res_pix)
+ Vision.Image.Filter.Internal: instance Foreign.Storable.Storable acc => Vision.Image.Filter.Internal.SeparatelyFiltrable src (Vision.Image.Type.Delayed p) acc
+ Vision.Image.Filter.Internal: instance Foreign.Storable.Storable acc => Vision.Image.Filter.Internal.SeparatelyFiltrable src (Vision.Image.Type.Manifest p) acc
+ Vision.Image.Filter.Internal: type family SeparableFilterAccumulator src res acc;
+ Vision.Image.Filter.Internal: }
+ Vision.Image.Grey.Type: instance Data.Bits.Bits Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance Foreign.Storable.Storable Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Classes.Eq Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Classes.Ord Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Enum.Bounded Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Enum.Enum Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Num.Num Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Read.Read Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Real.Integral Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Real.Real Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance GHC.Show.Show Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance Vision.Image.Class.Pixel Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.Grey.Type: instance Vision.Image.Interpolate.Interpolable Vision.Image.Grey.Type.GreyPixel
+ Vision.Image.HSV.Type: [hsvHue] :: HSVPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.HSV.Type: [hsvSat] :: HSVPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.HSV.Type: [hsvValue] :: HSVPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.HSV.Type: instance Foreign.Storable.Storable Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.HSV.Type: instance GHC.Classes.Eq Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.HSV.Type: instance GHC.Show.Show Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.HSV.Type: instance Vision.Image.Class.Pixel Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.HSV.Type: instance Vision.Image.Interpolate.Interpolable Vision.Image.HSV.Type.HSVPixel
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Int.Int16
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Int.Int32
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Types.Bool
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Types.Double
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Types.Float
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Types.Int
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Types.Word
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Word.Word16
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Word.Word32
+ Vision.Image.Interpolate: instance Vision.Image.Interpolate.Interpolable GHC.Word.Word8
+ Vision.Image.Mutable: [mmSize] :: MutableManifest p s -> !Size
+ Vision.Image.Mutable: [mmVector] :: MutableManifest p s -> !(MVector s p)
+ Vision.Image.Mutable: instance Foreign.Storable.Storable p => Vision.Image.Mutable.MutableImage (Vision.Image.Mutable.MutableManifest p)
+ Vision.Image.Mutable: type family Freezed i;
+ Vision.Image.Mutable: }
+ Vision.Image.RGB.Type: [rgbBlue] :: RGBPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGB.Type: [rgbGreen] :: RGBPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGB.Type: [rgbRed] :: RGBPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGB.Type: instance Foreign.Storable.Storable Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.RGB.Type: instance GHC.Classes.Eq Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.RGB.Type: instance GHC.Show.Show Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.RGB.Type: instance Vision.Image.Class.Pixel Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.RGB.Type: instance Vision.Image.Interpolate.Interpolable Vision.Image.RGB.Type.RGBPixel
+ Vision.Image.RGBA.Type: [rgbaAlpha] :: RGBAPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGBA.Type: [rgbaBlue] :: RGBAPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGBA.Type: [rgbaGreen] :: RGBAPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGBA.Type: [rgbaRed] :: RGBAPixel -> {-# UNPACK #-} !Word8
+ Vision.Image.RGBA.Type: instance Foreign.Storable.Storable Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.RGBA.Type: instance GHC.Classes.Eq Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.RGBA.Type: instance GHC.Show.Show Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.RGBA.Type: instance Vision.Image.Class.Pixel Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.RGBA.Type: instance Vision.Image.Interpolate.Interpolable Vision.Image.RGBA.Type.RGBAPixel
+ Vision.Image.Threshold: [BinaryThreshold] :: res -> res -> ThresholdType src res
+ Vision.Image.Threshold: [GaussianKernel] :: (Floating acc, RealFrac acc) => Maybe acc -> AdaptiveThresholdKernel acc
+ Vision.Image.Threshold: [MeanKernel] :: Integral acc => AdaptiveThresholdKernel acc
+ Vision.Image.Threshold: [TruncateInv] :: src -> ThresholdType src src
+ Vision.Image.Threshold: [Truncate] :: src -> ThresholdType src src
+ Vision.Image.Type: [delayedFun] :: Delayed p -> !(Point -> p)
+ Vision.Image.Type: [delayedMaskFun] :: DelayedMask p -> !(Point -> Maybe p)
+ Vision.Image.Type: [delayedMaskSize] :: DelayedMask p -> !Size
+ Vision.Image.Type: [delayedSize] :: Delayed p -> !Size
+ Vision.Image.Type: [manifestSize] :: Manifest p -> !Size
+ Vision.Image.Type: [manifestVector] :: Manifest p -> !(Vector p)
+ Vision.Image.Type: instance (Foreign.Storable.Storable p, GHC.Show.Show p) => GHC.Show.Show (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance (Foreign.Storable.Storable p1, Foreign.Storable.Storable p2, Data.Convertible.Base.Convertible p1 p2) => Data.Convertible.Base.Convertible (Vision.Image.Type.Delayed p1) (Vision.Image.Type.Delayed p2)
+ Vision.Image.Type: instance (Foreign.Storable.Storable p1, Foreign.Storable.Storable p2, Data.Convertible.Base.Convertible p1 p2) => Data.Convertible.Base.Convertible (Vision.Image.Type.Delayed p1) (Vision.Image.Type.Manifest p2)
+ Vision.Image.Type: instance (Foreign.Storable.Storable p1, Foreign.Storable.Storable p2, Data.Convertible.Base.Convertible p1 p2) => Data.Convertible.Base.Convertible (Vision.Image.Type.Manifest p1) (Vision.Image.Type.Delayed p2)
+ Vision.Image.Type: instance (Foreign.Storable.Storable p1, Foreign.Storable.Storable p2, Data.Convertible.Base.Convertible p1 p2) => Data.Convertible.Base.Convertible (Vision.Image.Type.Manifest p1) (Vision.Image.Type.Manifest p2)
+ Vision.Image.Type: instance (GHC.Classes.Eq p, Foreign.Storable.Storable p) => GHC.Classes.Eq (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance (GHC.Classes.Ord p, Foreign.Storable.Storable p) => GHC.Classes.Ord (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance (Vision.Image.Class.Image src, Foreign.Storable.Storable p) => Vision.Image.Class.FunctorImage src (Vision.Image.Type.Delayed p)
+ Vision.Image.Type: instance (Vision.Image.Class.Image src, Foreign.Storable.Storable p) => Vision.Image.Class.FunctorImage src (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance (Vision.Image.Class.MaskedImage src, Foreign.Storable.Storable p) => Vision.Image.Class.FunctorImage src (Vision.Image.Type.DelayedMask p)
+ Vision.Image.Type: instance Control.DeepSeq.NFData (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.FromFunction (Vision.Image.Type.DelayedMask p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.FromFunction (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.Image (Vision.Image.Type.Delayed p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.Image (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.MaskedImage (Vision.Image.Type.Delayed p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.MaskedImage (Vision.Image.Type.DelayedMask p)
+ Vision.Image.Type: instance Foreign.Storable.Storable p => Vision.Image.Class.MaskedImage (Vision.Image.Type.Manifest p)
+ Vision.Image.Type: instance Vision.Image.Class.FromFunction (Vision.Image.Type.Delayed p)
+ Vision.Primitive: [rHeight] :: Rect -> {-# UNPACK #-} !Int
+ Vision.Primitive: [rWidth] :: Rect -> {-# UNPACK #-} !Int
+ Vision.Primitive: [rX] :: Rect -> {-# UNPACK #-} !Int
+ Vision.Primitive: [rY] :: Rect -> {-# UNPACK #-} !Int
+ Vision.Primitive: [rpX] :: RPoint -> {-# UNPACK #-} !RatioInt
+ Vision.Primitive: [rpY] :: RPoint -> {-# UNPACK #-} !RatioInt
+ Vision.Primitive: instance GHC.Classes.Eq Vision.Primitive.RPoint
+ Vision.Primitive: instance GHC.Classes.Eq Vision.Primitive.Rect
+ Vision.Primitive: instance GHC.Classes.Ord Vision.Primitive.RPoint
+ Vision.Primitive: instance GHC.Classes.Ord Vision.Primitive.Rect
+ Vision.Primitive: instance GHC.Read.Read Vision.Primitive.RPoint
+ Vision.Primitive: instance GHC.Read.Read Vision.Primitive.Rect
+ Vision.Primitive: instance GHC.Show.Show Vision.Primitive.RPoint
+ Vision.Primitive: instance GHC.Show.Show Vision.Primitive.Rect
+ Vision.Primitive.Shape: instance (Data.Vector.Unboxed.Base.Unbox t, Data.Vector.Unboxed.Base.Unbox h) => Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector (t Vision.Primitive.Shape.:. h)
+ Vision.Primitive.Shape: instance (Data.Vector.Unboxed.Base.Unbox t, Data.Vector.Unboxed.Base.Unbox h) => Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector (t Vision.Primitive.Shape.:. h)
+ Vision.Primitive.Shape: instance (Data.Vector.Unboxed.Base.Unbox t, Data.Vector.Unboxed.Base.Unbox h) => Data.Vector.Unboxed.Base.Unbox (t Vision.Primitive.Shape.:. h)
+ Vision.Primitive.Shape: instance (GHC.Classes.Eq head, GHC.Classes.Eq tail) => GHC.Classes.Eq (tail Vision.Primitive.Shape.:. head)
+ Vision.Primitive.Shape: instance (GHC.Classes.Ord head, GHC.Classes.Ord tail) => GHC.Classes.Ord (tail Vision.Primitive.Shape.:. head)
+ Vision.Primitive.Shape: instance (GHC.Read.Read head, GHC.Read.Read tail) => GHC.Read.Read (tail Vision.Primitive.Shape.:. head)
+ Vision.Primitive.Shape: instance (GHC.Show.Show head, GHC.Show.Show tail) => GHC.Show.Show (tail Vision.Primitive.Shape.:. head)
+ Vision.Primitive.Shape: instance Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Data.Vector.Unboxed.Base.Unbox Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Foreign.Storable.Storable Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Foreign.Storable.Storable sh => Foreign.Storable.Storable (sh Vision.Primitive.Shape.:. GHC.Types.Int)
+ Vision.Primitive.Shape: instance GHC.Classes.Eq Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance GHC.Classes.Ord Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance GHC.Read.Read Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance GHC.Show.Show Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Vision.Primitive.Shape.Shape Vision.Primitive.Shape.Z
+ Vision.Primitive.Shape: instance Vision.Primitive.Shape.Shape sh => Vision.Primitive.Shape.Shape (sh Vision.Primitive.Shape.:. GHC.Types.Int)
- Vision.Histogram: class (Pixel p, Shape (PixelValueSpace p)) => ToHistogram p where type family PixelValueSpace p
+ Vision.Histogram: class (Pixel p, Shape (PixelValueSpace p)) => ToHistogram p where type PixelValueSpace p where {
- Vision.Image.Class: 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)
+ Vision.Image.Class: class FromFunction i where type 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) where {
- Vision.Image.Class: 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)
+ Vision.Image.Class: class Storable (ImagePixel i) => MaskedImage i where type 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) where {
- Vision.Image.Class: class Pixel p where type family PixelChannel p
+ Vision.Image.Class: class Pixel p where type PixelChannel p where {
- Vision.Image.Filter.Internal: 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
+ Vision.Image.Filter.Internal: 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 SeparableFilterAccumulator src res acc where {
- Vision.Image.Mutable: 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
+ Vision.Image.Mutable: class Image (Freezed i) => MutableImage i where type 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 where {
- Vision.Image.Mutable: create :: MutableImage i => (forall s. ST s (i s)) -> Freezed i
+ Vision.Image.Mutable: create :: (MutableImage i) => (forall s. ST s (i s)) -> Freezed i

Files

changelog view
@@ -1,5 +1,10 @@ -*-change-log-*- +v0.2.3.0 December 2016+ * Add Contour Tracing (Vision.Image.Contour)+ * Add pointer to friday-juicypixels+ * First release by TomMD - Raphael is MIA but it remains his package.+ v0.2.2.0 June 2015  * New 'computeP' function to compute an image in parallel. 
friday.cabal view
@@ -2,7 +2,7 @@ --                      +-+------- breaking API changes --                      | | +----- non-breaking API additions --                      | | | +--- code changes with no API change-version:                0.2.2.0+version:                0.2.3.0 synopsis:               A functional image processing library for Haskell. homepage:               https://github.com/RaphaelJ/friday license:                LGPL-3@@ -50,6 +50,7 @@                         Vision.Image                         Vision.Image.Class                         Vision.Image.Conversion+                        Vision.Image.Contour                         Vision.Image.Grey                         Vision.Image.Grey.Specialize                         Vision.Image.Grey.Type@@ -78,12 +79,13 @@     default-language:   Haskell2010      build-depends:      base                    >= 4            && < 5+                      , containers              >= 0.4          && < 0.6                       , convertible             >= 1            && < 2                       , deepseq                 >= 1.3          && < 2                       , primitive               >= 0.5.2.1      && < 0.7                       , ratio-int               >= 0.1.2        && < 0.2                       , vector                  >= 0.10.0.1     && < 1-                      , transformers            >= 0.3          && < 0.5+                      , transformers            >= 0.3          && < 0.6  Test-Suite      test     type:       exitcode-stdio-1.0
+ src/Vision/Image/Contour.hs view
@@ -0,0 +1,405 @@+{-# LANGUAGE BangPatterns+           , FlexibleContexts+           , CPP+           , GeneralizedNewtypeDeriving+           , ScopedTypeVariables+           , FlexibleInstances+           , MultiWayIf #-}+-- | Contour tracing of binary images (zero ~ background, nonzero ~ object).+--+-- Terminology:+--+-- A binary image is an image in which the pixel is boolean (represented+-- here  using 'Grey' and zero or non-zero pixel values).+--+-- All zero-value pixels are part of the "background".+--+-- An object is an connected group of non-zero pixels.+--+-- A 'Contour' is a trace of an objects' outer or inner edges.  Some+-- objects are solid, having no inner contours (consider a filled circle,+-- or letters such as 'h', 's', 'k' and 'l').  Other objects have "holes", also known as inner+-- contours.  The letters 'a' and 'e' have one hole while the letter 'B' has two.+--+-- After obtaining a 'Contours' structure (via the 'contours' function) the+-- raw traces ('Contour' type) can be used for further processing or the contours can be+-- filtered by aspects of interest and selectively re-drawn ('drawContour') , perhaps used to+-- mask the original image.+--+-- About Holes:+--+-- In cases where there is only one hole it is uniquely recorded in the+-- 'Contours' structure.  Objects with more than one hole record all inner+-- contours in one vector making them hard to extract separately - this is+-- due to the main data structure not being rich enough to record the holes+-- separately. As of writing, this is not seen as an issue because the+-- desired operation, drawContour, can still be achieved.  Changing this+-- behavior should be trivial if desired.+--+-- Use:+--+-- To use this library it is advised that you preprocess the image,+-- including thresholding (ex: 'otsu' on a grey scale image), to obtain a binary image then call:+--+-- @+-- cs = contours img+-- @+--+-- The 'Contours' structure can be accessed directly if desired.  It+-- includes an 'Map' of all contours (numbered counting from 1) and+-- a vector of the contour sizes (indexed by contour number, zero index is+-- unused/zero).+--+-- The algorithm implemented in this module follows the design laid out in+-- 'A Linear-Time Component-Labeling Algorithm Using Contour Tracing Technique' [1].+--+-- [1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.95.6330&rep=rep1&type=pdf+module Vision.Image.Contour (+    -- * Main Interface+      Contours(..), ContourId, OneContour, ContourValue, Contour(..), RowContour+    , contours+    -- * ADT style interface (hides 'Contours' internals)+    , allContourIds, lookupContour, rowContour, contourSize, contourPerimeter+    -- * Reconstructing Image Elements+    , ContourDrawStyle(..), drawContour, drawContours+    ) where++#if __GLASGOW_HASKELL__ < 710+import Control.Applicative+#endif++import Control.Monad (when)+import Control.Monad.ST+import qualified Data.Map.Strict as Map+import Data.Map.Strict (Map)+import Data.Maybe (catMaybes)+import Data.List (groupBy,sort)+import Data.Function (on)+import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Unboxed.Mutable as VM+import Foreign.Storable++import Vision.Image.Mutable (MutableManifest, new', write)+import qualified Vision.Image.Mutable as Mut+import Vision.Image.Grey (Grey,GreyPixel)+import Vision.Image.Type (Delayed)+import Vision.Image.Class (+      MaskedImage (..), Image (..), FromFunction (..), index+    )+import Vision.Primitive (+      Z (..), (:.) (..), Point, ix2, Size+    )++--------------------------------------------------------------------------------+--  Types and ADT-Style Interface++-- | Contours of an image include:+--    * A map from contour number to outer points and negative contour number of inner contour points.+--    * A vector of sizes for each contour for domain [1..size contourOutlines] (the zero index is meaningless)+data Contours =+        Contours { contourOutlines :: Map ContourId Contour+                 , contourSizes    :: !(VU.Vector Int)+                 }++allContourIds :: Contours -> [ContourId]+allContourIds = Map.keys . contourOutlines++contourPerimeter :: Contours -> ContourId -> [Point]+contourPerimeter m i =+    maybe [] (map fst . VU.toList . outerContour) (lookupContour m i)++contourSize :: Contours -> ContourId -> Int+contourSize (Contours _ s) i+    | unCID i < 0 || unCID i >= VU.length s = 0+    | otherwise                             = s VU.! unCID i++lookupContour :: Contours -> ContourId -> Maybe Contour+lookupContour m i = Map.lookup i (contourOutlines m)++-- |Contours are identified by a numeric ID number.+newtype ContourId = CID { unCID :: Int } deriving (Eq, Ord, Storable, Num, Show)++-- |A contour is described by the points on the perimeter and a boolean+-- indicating if that point is "terminal" (next pixel to+-- the right is background iff the point is terminal).  The terminal+-- information allows for a slightly simpler 'drawContour' implementation.+type OneContour    = VU.Vector ContourValue+type ContourValue  = (Point,Bool)+data Contour = Contour { outerContour  :: OneContour+                       , innerContours :: [OneContour]+                       } -- Pair of outer and inner contours++insOuterContour :: ContourId -> OneContour -> Map ContourId Contour+                                           -> Map ContourId Contour+insOuterContour cid o mp =+    let c = Contour o []+    in Map.insert cid c mp++insInnerContour :: ContourId -> OneContour -> Map ContourId Contour+                                           -> Map ContourId Contour+insInnerContour cid i mp =+    let c = Contour (error "Impossible: Inner contour with no outer!") [i]+        f _ (Contour o is) = Contour o (i:is)+    in Map.insertWith f cid c mp++-- |RowContour is a method of expressing contours by, for each row,+-- recording the start of an object and the end (due to reaching the other+-- side or a hole/inner contour) for each row.+type RowContour = VU.Vector (Point,Point)++--------------------------------------------------------------------------------+--  Image Reconstruction++-- | Outline: Just draw the edge.+--+-- OuterOutline: Outline the outer contours only, no hole contours+-- AllOutlines: Draw all contours+-- Fill: Draw the object but fill it in, ignoring holes.+-- FillWithHoles: Draw the object and do not fill in the holes.+data ContourDrawStyle = OuterOutline | AllOutlines | Fill | FillWithHoles+      deriving (Eq, Ord, Show, Read, Enum, Bounded)++-- | Draws a given contour. The size specified must be large enough to+-- include the coordinate originally occupied by the contour being drawn,+-- no cropping or other transformation is done.+drawContour :: Contours -> Size -> ContourDrawStyle -> ContourId -> Grey+drawContour master sz sty c = drawContours master sz sty [c]++-- |Draws many contours.  See 'drawContour'.+drawContours :: Contours -> Size -> ContourDrawStyle -> [ContourId] -> Grey+drawContours m sz AllOutlines ids  = drawOutlines listOfUVec m ids sz+ where listOfUVec (Contour o is) = o:is+drawContours m sz OuterOutline ids = drawOutlines listOfUVec m ids sz+ where listOfUVec (Contour o _) = [o]+drawContours m sz sty ids = drawRows pnts sz+ where lk = lookupContour m+       pnts = case sty of+                  Fill          -> map (VU.toList . outerContour) $ catMaybes $ map lk ids -- map (map (\(a,x) -> (a,not x)) . lk) innerIds ++ map lk outerIds+                  FillWithHoles -> map  (concatMap VU.toList . maybe [] (\x -> outerContour x : innerContours x) . lk) ids+                  _             -> error "Impossible: Style is not Fill, FillWithHoles"++drawOutlines :: (Contour -> [VU.Vector ContourValue]) -> Contours -> [ContourId] -> Size -> Grey+drawOutlines oper m ids sz = runST f+ where+  f = do+    i <- new' sz 0 :: ST s (MutableManifest GreyPixel s)+    let vs = map fst $ concatMap VU.toList $ concatMap oper $ catMaybes $ map (lookupContour m) ids+    mapM_ (\p -> write i p 255) vs+    Mut.unsafeFreeze i+++-- | Draws rows, throwing an exception when the size is too small for the+-- coordinates.+drawRows :: [[ContourValue]] -> Size -> Grey+drawRows vs sz = runST $ do+    i <- new' sz 0+    mapM_ (drawMutable i) vs+    Mut.unsafeFreeze i++drawMutable :: MutableManifest GreyPixel s -> [ContourValue] -> ST s ()+drawMutable i cs = VU.mapM_ (f i) rs+ where+     rs = rowContour cs+     f img (start,stop) = go (start, stop)+       where go (s@(Z:.row:.col),t) = do+                write img s 255+                when (s /= t) $ go (Z :. row :. (col+1),t)++-- |Given a vector including outer (and optionally inner) contour points,+-- make 'row contour' from which is easier to transform back into a binary+-- image.  By not including the inner contour points the row will be filled, making+-- traces of objects with holes appear solid.+rowContour :: [ContourValue] -> RowContour+rowContour cs =+    let rows :: [[(Point,Bool)]]+        rows = groupBy ((==) `on` ((\(Z:.r:._) -> r) . fst)) $ sort cs -- XXX consider vector quick/tim sort+    in VU.fromList $ concatMap walkM rows+ where+  walkM :: [(Point,Bool)] -> [(Point,Point)]+  walkM [x] = [(fst x,fst x)]+  walkM x   = maybe (error $ "Impossible: No terminal when walking contour: " ++ show (x,cs)) id $ walk x+  walk :: [(Point,Bool)] -> Maybe [(Point,Point)]+  walk [] = Just []+  walk xs@(x:_) = case dropWhile (not . snd) xs of+                      []     -> Nothing+                      (t:ys) -> ((fst x,fst t) :) <$> walk ys++-- |The meat of this module is the 'contours' function, which extracts+-- the contours (outer and inner outlines) of a binary image.+-- Zero-valued pixels are the background and non-zero are active/objects to+-- trace.  The output, 'Contours', contains enough information to determine+-- the number of contours, their traces, the size in pixels (filled size+-- and perimeter), number of holes, etc.+contours :: (Image src, Num (ImagePixel src), Eq (ImagePixel src)) => src -> Contours+contours src = runST $ do+     let bsrc = fromFunction (Z :. y+2 :. x+2) mkBorder+     mutImg   <- new' (shape bsrc) zid+     (outlines,sz) <- doLabeling bsrc mutImg+     sizes <- freezeBlobSizes sz+     return (Contours outlines sizes)+ where+ (Z :. y :. x) = shape src++ mkBorder (Z :. j :. i)+   | j == 0 || j == (y+1) || i == 0 || i == (x+1) = background+   | otherwise                                    = index src (Z :. j-1 :. i-1)++-- The image is assumed to be binary and should have values of either 0 (black) or... nonzero (white)+-- here we assume the background is black.  Nonzero would require more+-- change elsewhere!+background :: Num a => a+background = 0++zid :: ContourId+zid = CID 0++data BlobSizes s = BS (VM.MVector s Int)++freezeBlobSizes :: BlobSizes s -> ST s (VU.Vector Int)+freezeBlobSizes (BS v) = VU.unsafeFreeze v++incBlobSizes :: ContourId -> BlobSizes s -> ST s (BlobSizes s)+incBlobSizes (CID i) s@(BS v)+  | i > 0 =+     if VM.length v <= i+         then do nv <- VM.unsafeGrow v (i*2)+                 mapM_ (\ix -> VM.unsafeWrite nv ix 0) [i..i*2-1]+                 VM.unsafeWrite nv i 1+                 return (BS nv)+         else do p <- VM.unsafeRead v i+                 VM.unsafeWrite v i (p+1)+                 return s+  | otherwise = return s++zeroBlobSizes :: ST s (BlobSizes s)+zeroBlobSizes = BS <$> VM.replicate 1024 0++-- Make a contour image of the same dimension but with ContourIDs instead+-- of pixels.+doLabeling :: forall s p. (Storable p, Num p, Eq p) => Delayed p -> MutableManifest ContourId s -> ST s (Map ContourId Contour,BlobSizes s)+doLabeling src mutImg = zeroBlobSizes >>= go (Just $ ix2 1 1) (CID 0) (CID 1) mempty+ where+ getCID    :: Point -> ST s ContourId+ getCID     = Mut.read mutImg+ setCID i c = write mutImg i c+ getPixel :: Point -> ImagePixel (Delayed p)+ getPixel   = index src++ incIx :: Point -> Maybe Point+ incIx !(Z :. (!y) :. (!x))+    | x < xMax-1  = Just $ Z :. y     :. (x+1)+    | y < yMax-1  = Just $ Z :. (y+1) :. 1+    | otherwise = Nothing++ (Z :. yMax :. xMax) = shape src++ -- Traverse the source image top to bottom, left to right.  If the pixel+ -- has an ID then propagate that ID to all the following active pixels in+ -- the row.  If the pixel is active and has no ID then trace either an+ -- inner or outer contour.  If the pixel is inactive then skip it.+ go Nothing   _ _ !mp v              = return (mp,v)+ go (Just idx) leftCID !newCID !mp v =+   do thisCID <- getCID idx+      if | val == background                     -> skipForward -- this step doesn't appear in the paper! D'oh+         | thisCID == zid && above == background ->+                         do -- Step 1: Outer contour trace (active pixel with id=0 and above is background)+                            newContour <- traceContour src mutImg ExternalContour idx newCID+                            go (Just idx) newCID (newCID + 1) (insOuterContour newCID newContour mp) v+         | below == background ->               -- Step 2: P is an              white pixel+             do belowCID <- getCID belowIdx     --                 ^          ^+                if | belowCID == zid ->         --                 ^ unmarked ^+                         do -- Step 2a: Inner contour trace, below pixel was unmarked+                            let innerCID = if zid == thisCID then leftCID else thisCID+                            inner <- traceContour src mutImg InternalContour idx innerCID+                            go (incIx idx) innerCID newCID (insInnerContour innerCID inner mp) v+                            -- there can be more than one inner contour, make a richer container structure than IntMap?+                            -- Notice this isn't entirely necessary, one+                            -- CID can contain all inner contours and they can be redrawn correctly.+                   | otherwise -> stepForward -- Step 2b: Previously-observed contour+         | otherwise                             -> stepForward -- Active pixel not on a contour+   where val         = getPixel idx+         above       = getPixel (Z :. y-1 :. x)+         below       = getPixel belowIdx+         belowIdx    = Z :. y+1 :. x+         Z :. y :. x = idx+         stepForward = do xId <- if leftCID <= zid+                                  then getCID idx+                                  else return leftCID+                          setCID idx xId+                          nv <- incBlobSizes xId v+                          go (incIx idx) xId newCID mp nv+         skipForward = go (incIx idx) (-2) newCID mp v++-- Mark surrounding background pixels+-- label non-background pixels with CID+--+-- Unroll the loop one step to account for the lone-pixel case.  Without+-- lone pixels the tight inner loop can save a check (See 'Impossible')+--+-- TODO: optimize later, duplicate tracer and remove the p==pos, after a benchmarking method is setup.+traceContour :: forall p s. (Storable p, Num p, Eq p) => Delayed p -> MutableManifest ContourId s -> ContourType -> Point -> ContourId -> ST s OneContour+traceContour src mutImg contourTy origPnt assignedCID =+  do next <- tracer origPnt startPos+     case next of+         Nothing              -> return (VU.fromList $ fixList [(origPnt,True)])+         Just (sndPnt,sndPos) -> do+            let f pnt pos = do (nPnt,nPos) <- maybe (error "Impossible: Nothing in inner") id <$> tracer pnt pos+                               if pnt == origPnt && nPnt == sndPnt+                                   then return [] -- XXX some algorithms duplicate the start point, pnt, as the last point `return [pnt]`.  Should we?+                                   else ((pnt,terminal pnt) :) <$> f nPnt nPos+            VU.fromList . fixList . ((origPnt, terminal origPnt):) <$> f sndPnt sndPos++ where+   terminal (Z :. row :. col) = 0 == getPixel (Z :. row :. (col+1))+   -- Translate between indexes in our border-added image and the original+   fixList xs = let f (Z :. a :. b, t) = (Z :. a-1 :. b-1,t) in map f xs+   startPos   = case contourTy of { ExternalContour -> UR ; InternalContour -> LL  }+   setCID i c = write mutImg i c+   getPixel :: Point -> ImagePixel (Delayed p)+   getPixel   = index src++   {-# INLINE tracer #-}+   tracer pnt pos =+       let tracer' True p | p == pos = setCID pnt assignedCID >> return Nothing+           tracer' _ p = do let rpnt = relPoint pnt p+                                v    = getPixel rpnt+                            if | v == background -> do setCID rpnt (-1)+                                                       tracer' True (incCP p)+                               | otherwise       -> do setCID pnt assignedCID+                                                       return (Just (rpnt, decCP2 p))+       in tracer' False pos+++--------------------------------------------------------------------------------+--  Internal Types and Utilities++data ContourType = ExternalContour | InternalContour deriving (Eq)++-- A contour position is Upper/Lower/Middle Left/Center/Right pixel+-- relative to the current.  Because we add a border to the image prior+-- to processing, all original pixels `cross` contours positions are+-- a valid point.+data ContourPos  = MR | LR | LC | LL+                 | ML | UL | UC | UR+            deriving (Enum, Bounded, Eq, Show)++relPoint :: Point -> ContourPos -> Point+relPoint (Z :. row :. col) pos = Z :. row' :. col'+ where !row' = row + y+       !col' = col + x+       x = colOffset VU.! fromEnum pos+       y = rowOffset VU.! fromEnum pos++-- Rather than have branching (and expected poor performance),+-- use a table of x/y offsets for the relative pixel position.+colOffset,rowOffset :: VU.Vector Int+rowOffset = VU.fromList [0,1,1,1,0,-1,-1,-1]+colOffset = VU.fromList [1,1,0,-1,-1,-1,0,1]++-- Position clockwise by one tick+incCP :: ContourPos -> ContourPos+incCP  = toEnum . ((`rem` 8) . (+ 1)) . fromEnum++-- Position counter-clockwise by two ticks+decCP2 :: ContourPos -> ContourPos+decCP2 = toEnum . ((`rem` 8) . (+ 6)) . fromEnum
src/Vision/Primitive/Shape.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns            , CPP            , FlexibleInstances+           , TypeFamilies, MultiParamTypeClasses, FlexibleContexts            , TypeOperators #-}  -- | 'Shape's are similar to what you could found in @repa@. 'Shape' are used@@ -28,6 +29,10 @@  import Foreign.Storable (Storable (..)) import Foreign.Ptr (castPtr, plusPtr)+import Data.Vector.Unboxed (Unbox)+import qualified Data.Vector.Unboxed as VU+import Data.Vector.Generic.Mutable (MVector(..))+import qualified Data.Vector.Generic as VG  -- | Class of types that can be used as array shapes and indices. class Eq sh => Shape sh where@@ -70,6 +75,57 @@ infixl 3 :. data tail :. head = !tail :. !head     deriving (Show, Read, Eq, Ord)++newtype instance VU.MVector s Z = MV_Z (VU.MVector s ())+newtype instance VU.Vector    Z = V_Z  (VU.Vector    ())++instance MVector VU.MVector Z where+  {-# INLINE basicLength #-}+  basicLength (MV_Z v)          = basicLength v+  basicUnsafeSlice s e (MV_Z v) = MV_Z $ basicUnsafeSlice s e v+  basicUnsafeRead (MV_Z v) i    = basicUnsafeRead  v i >>= \_ -> return Z+  basicUnsafeNew   i            = MV_Z `fmap` basicUnsafeNew i+  basicUnsafeWrite (MV_Z v) i a = a `seq` basicUnsafeWrite v i ()+  basicOverlaps (MV_Z a) (MV_Z b) = basicOverlaps a b++instance VG.Vector VU.Vector Z where+  {-# INLINE basicLength #-}+  basicLength (V_Z v)          = VG.basicLength v+  basicUnsafeFreeze (MV_Z v)   = V_Z `fmap` VG.basicUnsafeFreeze v+  basicUnsafeThaw (V_Z v)      = MV_Z `fmap` VG.basicUnsafeThaw v+  basicUnsafeSlice s e (V_Z v) = V_Z $ VG.basicUnsafeSlice s e v+  basicUnsafeIndexM (V_Z v) i  = VG.basicUnsafeIndexM v i >>= \_ -> return Z++instance Unbox Z++newtype instance VU.MVector s (t :. h) = MV_Dim (VU.MVector s (t , h))+newtype instance VU.Vector    (t :. h) = V_Dim  (VU.Vector    (t , h))++instance (Unbox t, Unbox h) => MVector VU.MVector (t :. h) where+  {-# INLINE basicLength #-}+  basicLength (MV_Dim v)          = basicLength v+  basicUnsafeSlice s e (MV_Dim v) = MV_Dim $ basicUnsafeSlice s e v+  basicUnsafeRead (MV_Dim v) i    = pairToPoint `fmap` basicUnsafeRead  v i+  basicUnsafeNew   i              = MV_Dim `fmap` basicUnsafeNew i+  basicUnsafeWrite (MV_Dim v) i a = basicUnsafeWrite v i (pointToPair a)+  basicOverlaps (MV_Dim a) (MV_Dim b) = basicOverlaps a b++instance (Unbox t, Unbox h) => VG.Vector VU.Vector (t :. h) where+  {-# INLINE basicLength #-}+  basicLength (V_Dim v) = VG.basicLength v+  basicUnsafeFreeze (MV_Dim v)   = V_Dim `fmap` VG.basicUnsafeFreeze v+  basicUnsafeThaw (V_Dim v)      = MV_Dim `fmap` VG.basicUnsafeThaw v+  basicUnsafeSlice s e (V_Dim v) = V_Dim $ VG.basicUnsafeSlice s e v+  basicUnsafeIndexM (V_Dim v) i  = pairToPoint `fmap` VG.basicUnsafeIndexM v i++instance (Unbox t, Unbox h) => Unbox (t :. h)++pairToPoint :: (tail, head) -> tail :. head+pairToPoint (a,b) = a :. b++pointToPair :: tail :. head -> (tail, head)+pointToPair (a :. b) = (a,b)+  -- Common dimensions. type DIM0 = Z