packages feed

opencv (empty) → 0.0.0.0

raw patch · 237 files changed

+22168/−0 lines, 237 filesdep +Globdep +JuicyPixelsdep +QuickCheckbuild-type:Customsetup-changedbinary-added

Dependencies added: Glob, JuicyPixels, QuickCheck, aeson, base, base64-bytestring, bindings-DSL, bytestring, containers, criterion, data-default, deepseq, directory, haskell-src-exts, inline-c, inline-c-cpp, lens, linear, opencv, primitive, repa, tasty, tasty-hunit, tasty-quickcheck, template-haskell, text, transformers, vector

Files

+ LICENSE view
@@ -0,0 +1,32 @@+Copyright 2015—2016 Lumi Guide Fietsdetectie B.V.++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * The name Lumi Guide Fietsdetectie B.V. and the names of+      contributors may NOT be used to endorse or promote products+      derived from this software without specific prior written+      permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,8 @@+import Distribution.Simple ( defaultMainArgs )+import System.Environment ( getArgs )++main = do+    args <- getArgs+    let args' | "configure" `elem` args = args ++ ["--with-gcc","g++", "--with-ld","g++"]+              | otherwise               = args+    defaultMainArgs args'
+ bench/bench.hs view
@@ -0,0 +1,58 @@+module Main where++import "base" Control.Exception ( evaluate )+import "base" Data.Monoid+import "base" Data.Word+import qualified "bytestring" Data.ByteString as B+import "criterion" Criterion.Main+import "opencv" OpenCV+import "opencv" OpenCV.Unsafe+import qualified "repa" Data.Array.Repa as Repa++main :: IO ()+main = defaultMain+    [ bgroup "Core"+      [+        bgroup "Mat"+        [+          bgroup "Repa"+          [ env (loadImgAsRepa "Lenna.png") $ \a ->+              bench "computeS" $ nfArray benchComputeS a+          , env (loadImgAsRepa "Lenna.png") $ \a ->+              bench "computeP" $ nfArrayIO (benchComputeP a)+          ]+        ]+      ]+    , bgroup "ImgProc"+      [+      ]+    , bgroup "ImgCodecs"+      [+      ]+    , bgroup "HighGui"+      [+      ]+    , bgroup "Video"+      [+      ]+    ]++nfArray :: (Repa.Source r e, Repa.Shape sh) => (a -> Repa.Array r sh e) -> a -> Benchmarkable+nfArray f = nf (\x -> Repa.deepSeqArray (f x) ())++nfArrayIO :: (Repa.Source r e, Repa.Shape sh) =>  IO (Repa.Array r sh e) -> Benchmarkable+nfArrayIO m = nfIO $ do+                a <- m+                evaluate $ Repa.deepSeqArray a ()++benchComputeS :: Repa.Array (M '[ 'D, 'D ] 3) Repa.DIM3 Word8 -> Repa.Array Repa.U Repa.DIM3 Word8+benchComputeS = Repa.computeS . Repa.delay++benchComputeP :: Repa.Array (M '[ 'D, 'D ] 3) Repa.DIM3 Word8 -> IO (Repa.Array Repa.U Repa.DIM3 Word8)+benchComputeP = Repa.computeP . Repa.delay++loadImgAsRepa :: FilePath -> IO (Repa.Array (M '[ 'D, 'D ] 3) Repa.DIM3 Word8)+loadImgAsRepa fp = toRepa <$> loadImg+  where+    loadImg :: IO (Mat ('S '[ 'D, 'D ]) ('S 3) ('S Word8))+    loadImg = (unsafeCoerceMat . imdecode ImreadGrayscale) <$> B.readFile ("data/" <> fp)
+ data/Lenna.png view

binary file changed (absent → 473831 bytes)

+ data/arnold-schwarzenegger.jpg view

binary file changed (absent → 1588935 bytes)

+ data/building.jpg view

binary file changed (absent → 79718 bytes)

+ data/circles.png view

binary file changed (absent → 559020 bytes)

+ data/damage_mask.png view

binary file changed (absent → 3510 bytes)

+ data/haskell-opencv-logo.png view

binary file changed (absent → 30467 bytes)

+ data/kikker.jpg view

binary file changed (absent → 36014 bytes)

+ data/kodim05.png view

binary file changed (absent → 785610 bytes)

+ data/kodim06.png view

binary file changed (absent → 618959 bytes)

+ data/kodim07.png view

binary file changed (absent → 566322 bytes)

+ data/kodim23.png view

binary file changed (absent → 557596 bytes)

+ data/lambda.png view

binary file changed (absent → 1152 bytes)

+ doc/ExampleExtractor.hs view
@@ -0,0 +1,350 @@+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++module ExampleExtractor+  ( Animation++  , renderImage+  , renderAnimation++  , extractExampleImages+  ) where++import "base" Control.Arrow ( (***), (&&&) )+import "base" Control.Monad+import "base" Data.Bifunctor+import "base" Data.Either+import "base" Data.Maybe+import "base" Data.Monoid+import "base" Data.Word+import qualified "containers" Data.Map.Strict as M+import "directory" System.Directory ( canonicalizePath )+import qualified "haskell-src-exts" Language.Haskell.Exts.Extension as Hse+import qualified "haskell-src-exts" Language.Haskell.Exts.Parser as Hse+import qualified "haskell-src-exts" Language.Haskell.Exts.Syntax as Hse+import qualified "haskell-src-exts" Language.Haskell.Exts.SrcLoc as Hse+import qualified "Glob" System.FilePath.Glob as G+import "JuicyPixels" Codec.Picture.ColorQuant as JP+import "JuicyPixels" Codec.Picture.Gif        as JP+import "JuicyPixels" Codec.Picture.Types      as JP+import qualified "opencv" OpenCV as CV+import qualified "opencv" OpenCV.Juicy as CVJ+import qualified "text" Data.Text as T+import qualified "text" Data.Text.IO as T+import qualified "bytestring" Data.ByteString as B+import qualified "bytestring" Data.ByteString.Lazy as BL+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Syntax+import "this" Language.Haskell.Meta.Syntax.Translate ( toDecs )++--------------------------------------------------------------------------------++-- An animation is a list of images. Each image has a duration+-- specified in hundreths of a second.+type Animation shape channels depth = [(Int, CV.Mat shape channels depth)]++--------------------------------------------------------------------------------++renderImage+    :: FilePath+    -> CV.Mat ('CV.S [height, width]) channels depth+    -> IO ()+renderImage fp img = do+    let bs = CV.exceptError $ CV.imencode (CV.OutputPng CV.defaultPngParams) img+    putStr $ "Writing image " <> dest <> " ..."+    B.writeFile dest bs+    putStrLn " OK"+  where+    dest = mkDestPath fp++renderAnimation+    :: FilePath+    -> Animation ('CV.S [height, width]) ('CV.S 3) ('CV.S Word8)+    -> IO ()+renderAnimation fp imgs = do+    putStr $ "Writing animation " <> dest <> " ..."+    case gif of+      Left errMsg -> putStrLn $ " " <> errMsg+      Right bs -> BL.writeFile dest bs+    putStrLn " OK"+  where+    gif :: Either String BL.ByteString+    gif = JP.encodeGifImages JP.LoopingForever palImgs++    palImgs :: [(JP.Palette, JP.GifDelay, JP.Image JP.Pixel8)]+    palImgs =+        map (\(delay, img) ->+              let (img8, pal) = JP.palettize JP.defaultPaletteOptions img+              in (pal, delay, img8)+            )+            jpImgs++    jpImgs :: [(JP.GifDelay, JP.Image JP.PixelRGB8)]+    jpImgs = map (second CVJ.toImage) imgs++    dest = mkDestPath fp++mkDestPath :: FilePath -> FilePath+mkDestPath fp = "doc/generated/" <> fp++--------------------------------------------------------------------------------++data SrcLoc+   = SrcLoc+     { locFile :: !FilePath+     , locLine :: !Int+     }++-- | Haskell source code containing 0, 1 or more examples.+data ExampleSrc+   = ExampleSrc+     { exsLoc :: !SrcLoc+     , exsSrc :: !T.Text+     }++data ParsedExampleSrc+   = ParsedExampleSrc+     { pexsLoc   :: !SrcLoc+     , pexsDecls :: ![Dec]+     }++-- | A single line of Haskell source code.+data SrcLine+   = SrcLine+     { srcLoc  :: !SrcLoc+     , srcLine :: !T.Text+     }++data SymbolType+   = SymImage+   | SymImageAction+     deriving (Show, Eq)++data ExampleProps+   = ExampleProps+     { exPropIO        :: !Bool+     , exPropAnimation :: !Bool+     } deriving Show++data RenderTarget+   = RenderTarget+     { rtDestination :: !FilePath+       -- ^ Relative path where the symbol must be rendered as an image file.+     , rtSymbolName :: !Name+       -- ^ Name of a top level symbol (function or CAF) that is either an image+       -- or an IO action that yields an image.+     , rtSymbolProps :: !ExampleProps+     } deriving Show++--------------------------------------------------------------------------------++extractExampleImages :: FilePath -> Q [Dec]+extractExampleImages srcDir = do+    haskellPaths <- runIO $ findHaskellPaths srcDir+    mapM_ (addDependentFile <=< runIO . canonicalizePath) haskellPaths++    ((exampleSrcs, renderTargets) :: ([ExampleSrc], [RenderTarget])) <- runIO $ do+      xs <- mapM findExamples haskellPaths+      pure $ (concat *** concat) $ unzip xs++    let parseErrors       :: [String]+        parsedExampleSrcs :: [ParsedExampleSrc]+        (parseErrors, parsedExampleSrcs) = partitionEithers $ map parseExampleSrc exampleSrcs++        examplesTH :: [Dec]+        examplesTH = concatMap (\pexs -> parsedExampleLinePragma pexs : pexsDecls pexs)+                               parsedExampleSrcs++        exampleTypes :: M.Map Name Type+        exampleTypes = M.fromList $ mapMaybe asSigD examplesTH++        renderTargets' :: [RenderTarget]+        renderTargets' =+            mapMaybe+              (\rt -> do+                 exampleType <- M.lookup (rtSymbolName rt) exampleTypes+                 pure rt {rtSymbolProps = classifyExample exampleType}+              )+              renderTargets++    unless (null parseErrors) $+      error $ show parseErrors++    mdecs <- mkRenderExampleImages renderTargets'+    pure $ examplesTH <> mdecs++parsedExampleLinePragma :: ParsedExampleSrc -> Dec+parsedExampleLinePragma pexs =+    PragmaD $ LineP (locLine loc) (locFile loc)+  where+    loc = pexsLoc pexs++parseExampleSrc :: ExampleSrc -> Either String ParsedExampleSrc+parseExampleSrc exs =+    case parseDecsHse (locFile $ exsLoc exs) $ T.unpack $ haddockToHaskell $ exsSrc exs of+      Left errMsg -> Left $ (locFile $ exsLoc exs) <> ": " <> errMsg+      Right decls -> Right+                     ParsedExampleSrc+                     { pexsLoc   = exsLoc exs+                     , pexsDecls = toDecs decls+                     }+++asSigD :: Dec -> Maybe (Name, Type)+asSigD (SigD n t) = Just (n, t)+asSigD _ = Nothing++-- Really hacky way of determining the properties of an example based+-- on its type.+classifyExample :: Type -> ExampleProps+classifyExample (ForallT _ _ t) = classifyExample t+classifyExample (AppT (ConT n) t2) | nameBase n == nameBase ''IO = checkIOAnimation t2+classifyExample (AppT t1 _)     = classifyExample t1+classifyExample (VarT _)        = ExampleProps False False+classifyExample (ConT n) | nameBase n == nameBase ''Animation = ExampleProps False True+classifyExample (PromotedT _)   = ExampleProps False False+classifyExample _               = ExampleProps False False++checkIOAnimation :: Type -> ExampleProps+checkIOAnimation (ForallT _ _ t) = checkIOAnimation t+checkIOAnimation (AppT t1 _)     = checkIOAnimation t1+checkIOAnimation (VarT _)        = ExampleProps True False+checkIOAnimation (ConT n) | nameBase n == nameBase ''Animation = ExampleProps True True+checkIOAnimation (PromotedT _)   = ExampleProps True False+checkIOAnimation _               = ExampleProps True False++parseDecsHse :: String -> String -> Either String [Hse.Decl Hse.SrcSpanInfo]+parseDecsHse fileName str =+    case Hse.parseModuleWithMode (parseMode fileName) str of+      Hse.ParseFailed _srcLoc err -> Left err+      Hse.ParseOk (Hse.Module _ _ _ _  decls) -> Right decls+      Hse.ParseOk _ -> Left "Invalid module"++parseMode :: String -> Hse.ParseMode+parseMode fileName =+    Hse.ParseMode+    { Hse.parseFilename         = fileName+    , Hse.baseLanguage          = Hse.Haskell2010+    , Hse.extensions            = map Hse.EnableExtension exts+    , Hse.ignoreLanguagePragmas = False+    , Hse.ignoreLinePragmas     = False+    , Hse.fixities              = Nothing+    , Hse.ignoreFunctionArity   = False+    }+  where+    exts :: [Hse.KnownExtension]+    exts =+      [ Hse.BangPatterns+      , Hse.DataKinds+      , Hse.FlexibleContexts+      , Hse.LambdaCase+      , Hse.OverloadedStrings+      , Hse.PackageImports+      , Hse.PolyKinds+      , Hse.ScopedTypeVariables+      , Hse.TupleSections+      , Hse.TypeFamilies+      , Hse.TypeOperators+      , Hse.PostfixOperators+      , Hse.QuasiQuotes+      , Hse.UnicodeSyntax+      , Hse.MagicHash+      , Hse.PatternSignatures+      , Hse.MultiParamTypeClasses+      , Hse.RankNTypes+      ]++-- | Generate code for every render target+--+-- Executing the generated code will actually render the target.+mkRenderExampleImages :: [RenderTarget] -> Q [Dec]+mkRenderExampleImages renderTargets = [d|+    renderExampleImages :: IO ()+    renderExampleImages = $(pure doRender)+    |]+  where+    doRender :: Exp+    doRender =+        DoE $ do+          rt <- renderTargets+          let sym = VarE $ rtSymbolName rt+              fp  = LitE $ StringL $ "examples/" <> rtDestination rt+              props = rtSymbolProps rt+              render | exPropAnimation props = 'renderAnimation+                     | otherwise             = 'renderImage+          pure $ NoBindS $+            if exPropIO props+            then VarE '(>>=) `AppE` sym `AppE` (VarE render `AppE` fp)+            else VarE render `AppE` fp `AppE` sym++findHaskellPaths :: FilePath -> IO [FilePath]+findHaskellPaths srcDir = do+  (paths, _) <- G.globDir [G.compile "**/*.hs", G.compile "**/*.hsc"] srcDir+  pure $ concat paths++haddockToHaskell :: T.Text -> T.Text+haddockToHaskell =+    T.replace "\\\\" "\\"+  . T.replace "\\`" "`"+  . T.replace "\\<" "<"+  . T.replace "\\/" "/"++findExamples :: FilePath -> IO ([ExampleSrc], [RenderTarget])+findExamples fp = ((parseExamples &&& parseGeneratedImages) . textToSource fp) <$> T.readFile fp++textToSource :: FilePath -> T.Text -> [SrcLine]+textToSource fp txt = zipWith lineToSource [1..] (T.lines txt)+  where+    lineToSource :: Int -> T.Text -> SrcLine+    lineToSource n line =+        SrcLine+        { srcLoc  = SrcLoc {locFile = fp, locLine = n}+        , srcLine = line+        }++parseExamples :: [SrcLine] -> [ExampleSrc]+parseExamples = findStart+  where+    findStart :: [SrcLine] -> [ExampleSrc]+    findStart      []  = []+    findStart   (_:[]) = []+    findStart (_:_:[]) = []+    findStart (a:b:c:ls)+              | srcLine a == "Example:"+              , srcLine b == ""+              , srcLine c == "@"+                     = findEnd [] ls+    findStart (_:ls) = findStart ls++    findEnd :: [SrcLine] -> [SrcLine] -> [ExampleSrc]+    findEnd _acc [] = []+    findEnd acc (l:ls)+        | srcLine l == "@" =+            case reverse acc of+              []    -> findStart ls+              revAcc@(firstLine:_) ->+                  let exs = ExampleSrc+                            { exsLoc = srcLoc firstLine+                            , exsSrc = T.unlines (map srcLine revAcc)+                            }+                  in exs : findStart ls+        | otherwise = findEnd (l:acc) ls++parseGeneratedImages :: [SrcLine] -> [RenderTarget]+parseGeneratedImages = concatMap $ parseLine . srcLine+  where+    parseLine :: T.Text -> [RenderTarget]+    parseLine line = maybeToList $ do+      let fromPrefix = snd $ T.breakOn prefix line+      rest <- T.stripPrefix prefix fromPrefix+      case take 2 $ T.words rest of+        [fp, funcName] ->+            pure RenderTarget+                 { rtDestination = T.unpack $ fp+                 , rtSymbolName = mkName $ T.unpack $ fromMaybe funcName (T.stripSuffix ">>" funcName)+                   -- Later on we will determine the actual properties.+                 , rtSymbolProps = ExampleProps False False+                 }+        _ -> Nothing++    prefix = "<<doc/generated/examples/"
+ doc/Language/Haskell/Meta/Syntax/Translate.hs view
@@ -0,0 +1,761 @@+{-# LANGUAGE CPP, TemplateHaskell, TypeSynonymInstances, FlexibleInstances #-}++{- |+  Module      :  Language.Haskell.Meta.Syntax.Translate+  Copyright   :  (c) Matt Morrow 2008+  License     :  BSD3+  Maintainer  :  Matt Morrow <mjm2002@gmail.com>+  Stability   :  experimental+  Portability :  portable (template-haskell)+-}++module Language.Haskell.Meta.Syntax.Translate (+    module Language.Haskell.Meta.Syntax.Translate+) where++import Data.Char (ord, isUpper)+import Data.Typeable+import Data.List (foldl', nub, (\\))+import Language.Haskell.TH.Syntax+import qualified Language.Haskell.Exts.SrcLoc as Hs+#if MIN_VERSION_haskell_src_exts(1,18,0)+import qualified Language.Haskell.Exts.Syntax as Hs+#else+import qualified Language.Haskell.Exts.Annotated.Syntax as Hs+#endif++-----------------------------------------------------------------------------+++class ToName a where toName :: a -> Name+class ToNames a where toNames :: a -> [Name]+class ToLit  a where toLit  :: a -> Lit+class ToType a where toType :: a -> Type+class ToPat  a where toPat  :: a -> Pat+class ToExp  a where toExp  :: a -> Exp+class ToDecs a where toDecs :: a -> [Dec]+class ToDec  a where toDec  :: a -> Dec+class ToStmt a where toStmt :: a -> Stmt+class ToLoc  a where toLoc  :: a -> Loc+class ToCxt  a where toCxt  :: a -> Cxt+class ToPred a where toPred :: a -> Pred+class ToTyVars a where toTyVars :: a -> [TyVarBndr]+#if MIN_VERSION_haskell_src_exts(1,18,0)+class ToMaybeKind a where toMaybeKind :: a -> Maybe Kind+#if MIN_VERSION_template_haskell(2,11,0)+class ToInjectivityAnn a where toInjectivityAnn :: a -> InjectivityAnn+#endif+#endif++-- for error messages+moduleName = "Language.Haskell.Meta.Syntax.Translate"++-- When to use each of these isn't always clear: prefer 'todo' if unsure.+noTH :: (Functor f, Show (f ())) => String -> f e -> a+noTH fun thing = error . concat $ [moduleName, ".", fun,+  ": template-haskell has no representation for: ", show (fmap (const ()) thing)]++noTHyet :: (Functor f, Show (f ())) => String -> String -> f e -> a+noTHyet fun minVersion thing = error . concat $ [moduleName, ".", fun,+  ": template-haskell-", VERSION_template_haskell, " (< ", minVersion, ")",+  " has no representation for: ", show (fmap (const ()) thing)]++todo :: (Functor f, Show (f ())) => String -> f e -> a+todo fun thing = error . concat $ [moduleName, ".", fun,+  ": not implemented: ", show (fmap (const ()) thing)]++nonsense :: (Functor f, Show (f ())) => String -> String -> f e -> a+nonsense fun inparticular thing = error . concat $ [moduleName, ".", fun,+  ": nonsensical: ", inparticular, ": ", show (fmap (const ()) thing)]++-----------------------------------------------------------------------------+++instance ToExp Lit where+  toExp = LitE+instance (ToExp a) => ToExp [a] where+  toExp = ListE . fmap toExp+instance (ToExp a, ToExp b) => ToExp (a,b) where+  toExp (a,b) = TupE [toExp a, toExp b]+instance (ToExp a, ToExp b, ToExp c) => ToExp (a,b,c) where+  toExp (a,b,c) = TupE [toExp a, toExp b, toExp c]+instance (ToExp a, ToExp b, ToExp c, ToExp d) => ToExp (a,b,c,d) where+  toExp (a,b,c,d) = TupE [toExp a, toExp b, toExp c, toExp d]+++instance ToPat Lit where+  toPat = LitP+instance (ToPat a) => ToPat [a] where+  toPat = ListP . fmap toPat+instance (ToPat a, ToPat b) => ToPat (a,b) where+  toPat (a,b) = TupP [toPat a, toPat b]+instance (ToPat a, ToPat b, ToPat c) => ToPat (a,b,c) where+  toPat (a,b,c) = TupP [toPat a, toPat b, toPat c]+instance (ToPat a, ToPat b, ToPat c, ToPat d) => ToPat (a,b,c,d) where+  toPat (a,b,c,d) = TupP [toPat a, toPat b, toPat c, toPat d]+++instance ToLit Char where+  toLit = CharL+instance ToLit String where+  toLit = StringL+instance ToLit Integer where+  toLit = IntegerL+instance ToLit Int where+  toLit = IntegerL . toInteger+instance ToLit Float where+  toLit = RationalL . toRational+instance ToLit Double where+  toLit = RationalL . toRational+++-----------------------------------------------------------------------------+++-- * ToName {String,HsName,Module,HsSpecialCon,HsQName}+++instance ToName String where+  toName = mkName++instance ToName (Hs.Name l) where+  toName (Hs.Ident _ s) = toName s+  toName (Hs.Symbol _ s) = toName s++instance ToName (Hs.SpecialCon l) where+  toName (Hs.UnitCon _) = '()+  toName (Hs.ListCon _) = '[]+  toName (Hs.FunCon _)  = ''(->)+  toName (Hs.TupleCon _ _ n)+    | n<2 = '()+    | otherwise =+      let x = maybe [] (++".") (nameModule '(,))+      in mkName . concat $ x : ["(",replicate (n-1) ',',")"]+  toName (Hs.Cons _)    = '(:)+++instance ToName (Hs.QName l) where+--  toName (Hs.Qual (Hs.Module []) n) = toName n+  toName (Hs.Qual _ (Hs.ModuleName _ []) n) = toName n+  toName (Hs.Qual _ (Hs.ModuleName _ m) n) =+    let m' = show . toName $ m+        n' = show . toName $ n+    in toName . concat $ [m',".",n']+  toName (Hs.UnQual _ n) = toName n+  toName (Hs.Special _ s) = toName s+++instance ToName (Hs.Op l) where+  toName (Hs.VarOp _ n) = toName n+  toName (Hs.ConOp _ n) = toName n+++-----------------------------------------------------------------------------++-- * ToLit HsLiteral+++instance ToLit (Hs.Literal l) where+  toLit (Hs.Char _ a _) = CharL a+  toLit (Hs.String _ a _) = StringL a+  toLit (Hs.Int _ a _) = IntegerL a+  toLit (Hs.Frac _ a _) = RationalL a+  toLit l@Hs.PrimChar{} = noTH "toLit" l+  toLit (Hs.PrimString _ a _) = StringPrimL (map toWord8 a)+   where+    toWord8 = fromIntegral . ord+  toLit (Hs.PrimInt _ a _) = IntPrimL a+  toLit (Hs.PrimFloat _ a _) = FloatPrimL a+  toLit (Hs.PrimDouble _ a _) = DoublePrimL a+  toLit (Hs.PrimWord _ a _) = WordPrimL a+++-----------------------------------------------------------------------------++-- * ToPat HsPat+++instance ToPat (Hs.Pat l) where+  toPat (Hs.PVar _ n)+    = VarP (toName n)+  toPat (Hs.PLit _ (Hs.Signless _) l)+    = LitP (toLit l)+  toPat (Hs.PLit _ (Hs.Negative _) l) = LitP $ case toLit l of+    IntegerL z -> IntegerL (negate z)+    RationalL q -> RationalL (negate q)+    IntPrimL z' -> IntPrimL (negate z')+    FloatPrimL r' -> FloatPrimL (negate r')+    DoublePrimL r'' -> DoublePrimL (negate r'')+    _ -> nonsense "toPat" "negating wrong kind of literal" l+  toPat (Hs.PInfixApp _ p n q) = UInfixP (toPat p) (toName n) (toPat q)+  toPat (Hs.PApp _ n ps) = ConP (toName n) (fmap toPat ps)+  toPat (Hs.PTuple _ Hs.Boxed ps) = TupP (fmap toPat ps)+  toPat (Hs.PTuple _ Hs.Unboxed ps) = UnboxedTupP (fmap toPat ps)+  toPat (Hs.PList _ ps) = ListP (fmap toPat ps)+  toPat (Hs.PParen _ p) = ParensP (toPat p)+  toPat (Hs.PRec _ n pfs) = let toFieldPat (Hs.PFieldPat _ n p) = (toName n, toPat p)+                            in RecP (toName n) (fmap toFieldPat pfs)+  toPat (Hs.PAsPat _ n p) = AsP (toName n) (toPat p)+  toPat (Hs.PWildCard _) = WildP+  toPat (Hs.PIrrPat _ p) = TildeP (toPat p)+  toPat (Hs.PatTypeSig _ p t) = SigP (toPat p) (toType t)+  toPat (Hs.PViewPat _ e p) = ViewP (toExp e) (toPat p)+  -- regular pattern+  toPat p@Hs.PRPat{} = noTH "toPat" p+  -- XML stuff+  toPat p@Hs.PXTag{} = noTH "toPat" p+  toPat p@Hs.PXETag{} = noTH "toPat" p+  toPat p@Hs.PXPcdata{} = noTH "toPat" p+  toPat p@Hs.PXPatTag{} = noTH "toPat" p+  toPat (Hs.PBangPat _ p) = BangP (toPat p)+  toPat p = todo "toPat" p++-----------------------------------------------------------------------------++-- * ToExp HsExp++instance ToExp (Hs.QOp l) where+  toExp (Hs.QVarOp _ n) = VarE (toName n)+  toExp (Hs.QConOp _ n) = ConE (toName n)++toFieldExp :: Hs.FieldUpdate l -> FieldExp+toFieldExp (Hs.FieldUpdate _ n e) = (toName n, toExp e)+++++instance ToExp (Hs.Exp l) where+  toExp (Hs.Var _ n)                 = VarE (toName n)+  toExp e@Hs.IPVar{}               = noTH "toExp" e+  toExp (Hs.Con _ n)                 = ConE (toName n)+  toExp (Hs.Lit _ l)                 = LitE (toLit l)+  toExp (Hs.InfixApp _ e o f)        = UInfixE (toExp e) (toExp o) (toExp f)+  toExp (Hs.App _ e f)               = AppE (toExp e) (toExp f)+  toExp (Hs.NegApp _ e)              = AppE (VarE 'negate) (toExp e)+  toExp (Hs.Lambda _ ps e)         = LamE (fmap toPat ps) (toExp e)+  toExp (Hs.Let _ bs e)              = LetE (toDecs bs) (toExp e)+  toExp (Hs.If _ a b c)              = CondE (toExp a) (toExp b) (toExp c)+  toExp (Hs.MultiIf _ ifs)           = MultiIfE (map toGuard ifs)+  toExp (Hs.Case _ e alts)           = CaseE (toExp e) (map toMatch alts)+  toExp (Hs.Do _ ss)                 = DoE (map toStmt ss)+  toExp e@(Hs.MDo _ _)               = noTH "toExp" e+  toExp (Hs.Tuple _ Hs.Boxed xs)     = TupE (fmap toExp xs)+  toExp (Hs.Tuple _ Hs.Unboxed xs)   = UnboxedTupE (fmap toExp xs)+  toExp e@Hs.TupleSection{}        = noTH "toExp" e+  toExp (Hs.List _ xs)               = ListE (fmap toExp xs)+  toExp (Hs.Paren _ e)               = ParensE (toExp e)+  toExp (Hs.LeftSection _ e o)       = InfixE (Just . toExp $ e) (toExp o) Nothing+  toExp (Hs.RightSection _ o f)      = InfixE Nothing (toExp o) (Just . toExp $ f)+  toExp (Hs.RecConstr _ n xs)        = RecConE (toName n) (fmap toFieldExp xs)+  toExp (Hs.RecUpdate _ e xs)        = RecUpdE (toExp e) (fmap toFieldExp xs)+  toExp (Hs.EnumFrom _ e)            = ArithSeqE $ FromR (toExp e)+  toExp (Hs.EnumFromTo _ e f)        = ArithSeqE $ FromToR (toExp e) (toExp f)+  toExp (Hs.EnumFromThen _ e f)      = ArithSeqE $ FromThenR (toExp e) (toExp f)+  toExp (Hs.EnumFromThenTo _ e f g)  = ArithSeqE $ FromThenToR (toExp e) (toExp f) (toExp g)+  toExp (Hs.ListComp _ e ss)         = CompE $ map convert ss ++ [NoBindS (toExp e)]+   where+    convert (Hs.QualStmt _ st) = toStmt st+    convert s = noTH "toExp ListComp" s+  toExp (Hs.ExpTypeSig _ e t)      = SigE (toExp e) (toType t)+  toExp e = todo "toExp" e+++toMatch :: Hs.Alt l -> Match+toMatch (Hs.Alt _ p rhs ds) = Match (toPat p) (toBody rhs) (toDecs ds)++toBody :: Hs.Rhs l -> Body+toBody (Hs.UnGuardedRhs _ e) = NormalB $ toExp e+toBody (Hs.GuardedRhss _ rhss) = GuardedB $ map toGuard rhss++toGuard (Hs.GuardedRhs _ stmts e) = (g, toExp e)+  where+    g = case map toStmt stmts of+      [NoBindS x] -> NormalG x+      xs -> PatG xs++instance ToDecs a => ToDecs (Maybe a) where+    toDecs Nothing = []+    toDecs (Just a) = toDecs a++instance ToDecs (Hs.Binds l) where+  toDecs (Hs.BDecls _ ds)   = toDecs ds+  toDecs a@(Hs.IPBinds {}) = noTH "ToDecs Hs.Binds" a++instance ToDecs (Hs.ClassDecl l) where+  toDecs (Hs.ClsDecl _ d) = toDecs d+  toDecs x = todo "classDecl" x++-----------------------------------------------------------------------------++-- * ToLoc SrcLoc++instance ToLoc Hs.SrcLoc where+  toLoc (Hs.SrcLoc fn l c) =+    Loc fn [] [] (l,c) (-1,-1)++-----------------------------------------------------------------------------++-- * ToType HsType++instance ToName (Hs.TyVarBind l) where+  toName (Hs.KindedVar _ n _) = toName n+  toName (Hs.UnkindedVar _ n) = toName n++instance ToName Name where+  toName = id++instance ToName TyVarBndr where+  toName (PlainTV n) = n+  toName (KindedTV n _) = n++instance ToType (Hs.Kind l) where+  toType (Hs.KindStar _) = StarT+  toType (Hs.KindFn _ k1 k2) = toType k1 .->. toType k2+  toType (Hs.KindParen _ kp) = toType kp+  toType (Hs.KindVar _ n)+      | isCon (nameBase th_n) = ConT th_n+      | otherwise             = VarT th_n+    where+      th_n = toName n++      isCon :: String -> Bool+      isCon (c:_) = isUpper c || c == ':'+      isCon _ = nonsense "toType" "empty kind variable name" n+  toType (Hs.KindApp _ k1 k2) = toType k1 `AppT` toType k2+  toType (Hs.KindTuple _ ks) = foldr (\k pt -> pt `AppT` toType k) (TupleT $ length ks) ks+  toType (Hs.KindList _ k) = ListT `AppT` toType k++toKind :: Hs.Kind l -> Kind+toKind = toType++toTyVar :: Hs.TyVarBind l -> TyVarBndr+toTyVar (Hs.KindedVar _ n k) = KindedTV (toName n) (toKind k)+toTyVar (Hs.UnkindedVar _ n) = PlainTV (toName n)++instance ToType (Hs.Type l) where+  toType (Hs.TyForall _ tvbM cxt t) = ForallT (maybe [] (fmap toTyVar) tvbM) (toCxt cxt) (toType t)+  toType (Hs.TyFun _ a b) = toType a .->. toType b+  toType (Hs.TyList _ t) = ListT `AppT` toType t+  toType (Hs.TyTuple _ b ts) = foldAppT (tuple . length $ ts) (fmap toType ts)+   where+    tuple = case b of+      Hs.Boxed -> TupleT+      Hs.Unboxed -> UnboxedTupleT+  toType (Hs.TyApp _ a b) = AppT (toType a) (toType b)+  toType (Hs.TyVar _ n) = VarT (toName n)+  toType (Hs.TyCon _ qn) = ConT (toName qn)+  toType (Hs.TyParen _ t) = toType t+  -- XXX: need to wrap the name in parens!+  toType (Hs.TyInfix _ a o b) = AppT (AppT (ConT (toName o)) (toType a)) (toType b)+  toType (Hs.TyKind _ t k) = SigT (toType t) (toKind k)+  toType (Hs.TyPromoted _ p) =+      case p of+        Hs.PromotedInteger _ i _ -> LitT $ NumTyLit i+        Hs.PromotedString _ _ s -> LitT $ StrTyLit s+        Hs.PromotedCon _ _q n -> PromotedT (toName n)+        Hs.PromotedList _ _q ts -> foldr (\t pl -> PromotedConsT `AppT` toType t `AppT` pl) PromotedNilT ts+        Hs.PromotedTuple _ ts -> foldr (\t pt -> pt `AppT` toType t) (PromotedTupleT $ length ts) ts+        Hs.PromotedUnit _ -> PromotedT ''()+  toType (Hs.TyEquals _ t1 t2) = EqualityT `AppT` toType t1 `AppT` toType t2+  toType t@(Hs.TySplice _ _) = noTH "toType" t+  toType t@Hs.TyBang{} =+    nonsense "toType" "type cannot have strictness annotations in this context" t+  toType t@(Hs.TyWildCard _ _) = noTH "toType" t+  toType t = todo "toType" t++toStrictType :: Hs.Type l -> StrictType+#if MIN_VERSION_haskell_src_exts(1,18,0)+#if MIN_VERSION_template_haskell(2,11,0)+toStrictType (Hs.TyBang _ s u t) = (Bang (toUnpack u) (toStrict s), toType t)+    where+      toStrict (Hs.LazyTy _) = SourceLazy+      toStrict (Hs.BangedTy _) = SourceStrict+      toStrict (Hs.NoStrictAnnot _) = NoSourceStrictness+      toUnpack (Hs.Unpack _) = SourceUnpack+      toUnpack (Hs.NoUnpack _) = SourceNoUnpack+      toUnpack (Hs.NoUnpackPragma _) = NoSourceUnpackedness+toStrictType x = (Bang NoSourceUnpackedness NoSourceStrictness, toType x)+#else+-- TyBang l (BangType l) (Unpackedness l) (Type l)+-- data BangType l = BangedTy l	| LazyTy l | NoStrictAnnot l+-- data Unpackedness l = Unpack l | NoUnpack l | NoUnpackPragma l+toStrictType (Hs.TyBang _ b u t) = (toStrict b u, toType t)+    where+      toStrict :: Hs.BangType l -> Hs.Unpackedness l -> Strict+      toStrict (Hs.BangedTy _) _ = IsStrict+      toStrict _ (Hs.Unpack _) = Unpacked+      toStrict _ _ = NotStrict+toStrictType x = (NotStrict, toType x)+#endif+#else+#if MIN_VERSION_template_haskell(2,11,0)+toStrictType (Hs.TyBang _ (Hs.UnpackedTy _) t) = toStrictType2 SourceUnpack t+toStrictType t = toStrictType2 NoSourceUnpackedness t++toStrictType2 u t@(Hs.TyBang _ _ Hs.TyBang{}) =+  nonsense "toStrictType" "double strictness annotation" t+toStrictType2 u (Hs.TyBang _ (Hs.BangedTy _) t) = (Bang u SourceStrict, toType t)+toStrictType2 u (Hs.TyBang _ (Hs.UnpackedTy _) t) =+  nonsense "toStrictType" "double unpackedness annotation" t+toStrictType2 u t = (Bang u NoSourceStrictness, toType t)+#else /* !MIN_VERSION_template_haskell(2,11,0) */+toStrictType t@(Hs.TyBang _ _ Hs.TyBang{}) =+  nonsense "toStrictType" "double strictness annotation" t+toStrictType (Hs.TyBang _ (Hs.BangedTy _) t) = (IsStrict, toType t)+toStrictType (Hs.TyBang _ (Hs.UnpackedTy _) t) = (Unpacked, toType t)+toStrictType t = (NotStrict, toType t)+#endif /* !MIN_VERSION_template_haskell(2,11,0) */+#endif+++(.->.) :: Type -> Type -> Type+a .->. b = AppT (AppT ArrowT a) b++instance ToPred (Hs.Asst l) where+#if MIN_VERSION_template_haskell(2,10,0)+    toPred (Hs.ClassA _ n ts) = foldl' AppT (ConT (toName n)) (fmap toType ts)+    toPred (Hs.InfixA _ t1 n t2) = foldl' AppT (ConT (toName n)) (fmap toType [t1,t2])+    toPred (Hs.EqualP _ t1 t2) = foldl' AppT EqualityT (fmap toType [t1,t2])+    toPred (Hs.ParenA _ asst) = toPred asst+    toPred a@Hs.AppA{} = todo "toCxt" a+    toPred a@Hs.WildCardA{} = todo "toCxt" a+#else+    toPred (Hs.ClassA _ n ts) = ClassP (toName n) (fmap toType ts)+    toPred (Hs.InfixA _ t1 n t2) = ClassP (toName n) (fmap toType [t1, t2])+    toPred (Hs.EqualP _ t1 t2) = EqualP (toType t1) (toType t2)+#endif+    toPred a@Hs.IParam{} = noTH "toCxt" a+    toPred p = todo "toPred" p++#if MIN_VERSION_template_haskell(2,11,0)+instance ToCxt (Hs.Deriving l) where+  toCxt (Hs.Deriving _ rule) = toCxt rule+instance ToCxt [Hs.InstRule l] where+  toCxt = concatMap toCxt+#endif++instance ToCxt a => ToCxt (Maybe a) where+    toCxt Nothing = []+    toCxt (Just a) = toCxt a++foldAppT :: Type -> [Type] -> Type+foldAppT t ts = foldl' AppT t ts++-----------------------------------------------------------------------------++-- * ToStmt HsStmt++instance ToStmt (Hs.Stmt l) where+  toStmt (Hs.Generator _ p e)  = BindS (toPat p) (toExp e)+  toStmt (Hs.Qualifier _ e)      = NoBindS (toExp e)+  toStmt a@(Hs.LetStmt _ bnds)   = LetS (toDecs bnds)+  toStmt s@Hs.RecStmt{}        = noTH "toStmt" s+++-----------------------------------------------------------------------------++-- * ToDec HsDecl++instance ToDec (Hs.Decl l) where+  toDec (Hs.TypeDecl _ h t)+    = TySynD (toName h) (toTyVars h) (toType t)++  toDec a@(Hs.DataDecl  _ dOrN cxt h qcds qns)+    = case dOrN of+        Hs.DataType _ -> DataD (toCxt cxt)+                             (toName h)+                             (toTyVars h)+#if MIN_VERSION_template_haskell(2,11,0)+                             Nothing+#endif+                             (fmap qualConDeclToCon qcds)+#if MIN_VERSION_template_haskell(2,11,0)+                             -- Convert a Deriving into a list of types, one for each derived class+                             -- Assumes that the types do not have any contexts+                             (maybe [] (\(Hs.Deriving _ q) -> map toType q) qns)+#else+                             (toNames qns)+#endif+        Hs.NewType _  -> let qcd = case qcds of+                                     [x] -> x+                                     _   -> nonsense "toDec" ("newtype with " +++                                                              "wrong number of constructors") a+                        in NewtypeD (toCxt cxt)+                                    (toName h)+                                    (toTyVars h)+#if MIN_VERSION_template_haskell(2,11,0)+                                    Nothing+#endif+                                    (qualConDeclToCon qcd)+#if MIN_VERSION_template_haskell(2,11,0)+                                    (maybe [] (\(Hs.Deriving _ q) -> map toType q) qns)+#else+                                    (toNames qns)+#endif++  -- This type-signature conversion is just wrong.+  -- Type variables need to be dealt with. /Jonas+  toDec a@(Hs.TypeSig _ ns t)+    -- XXXXXXXXXXXXXX: oh crap, we can't return a [Dec] from this class!+    = let xs = fmap (flip SigD (toType t) . toName) ns+      in case xs of x:_ -> x; [] -> error "toDec: malformed TypeSig!"++  toDec (Hs.InlineConlikeSig _ act qn) = PragmaD $+    InlineP (toName qn) Inline ConLike (transAct act)+  toDec (Hs.InlineSig _ b act qn) = PragmaD $+    InlineP (toName qn) inline FunLike (transAct act)+   where+    inline | b = Inline | otherwise = NoInline++#if MIN_VERSION_template_haskell(2,11,0)+#if MIN_VERSION_haskell_src_exts(1,18,0)+  toDec (Hs.TypeFamDecl _ h sig inj)+    = OpenTypeFamilyD $ TypeFamilyHead (toName h)+                                       (toTyVars h)+                                       (maybe NoSig KindSig . toMaybeKind $ sig)+                                       (fmap toInjectivityAnn inj)+  toDec (Hs.DataFamDecl _ _ h sig)+    = DataFamilyD (toName h) (toTyVars h) (toMaybeKind sig)+#else+  toDec (Hs.TypeFamDecl _ h k)+    = OpenTypeFamilyD $ TypeFamilyHead (toName h)+                                       (toTyVars h)+                                       (maybe NoSig (KindSig . toKind) k)+                                       Nothing+  -- TODO: do something with context?+  toDec (Hs.DataFamDecl _ _ h k)+    = DataFamilyD (toName h) (toTyVars h) (fmap toKind k)+#endif++#else+#if MIN_VERSION_haskell_src_exts(1,18,0)+  toDec (Hs.TypeFamDecl _ h sig inj)+    = FamilyD TypeFam (toName h) (toTyVars h) (toMaybeKind sig)+  toDec (Hs.DataFamDecl _ _ h sig)+    = FamilyD DataFam (toName h) (toTyVars h) (toMaybeKind sig)+#else+  toDec (Hs.TypeFamDecl _ h k)+    = FamilyD TypeFam (toName h) (toTyVars h) (fmap toKind k)++  -- TODO: do something with context?+  toDec (Hs.DataFamDecl _ _ h k)+    = FamilyD DataFam (toName h) (toTyVars h) (fmap toKind k)+#endif+#endif /* MIN_VERSION_template_haskell(2,11,0) */++  toDec a@(Hs.FunBind _ mtchs)                           = hsMatchesToFunD mtchs+  toDec (Hs.PatBind _ p rhs bnds)                      = ValD (toPat p)+                                                              (hsRhsToBody rhs)+                                                              (toDecs bnds)++  toDec i@(Hs.InstDecl _ (Just overlap) _ _) =+    noTH "toDec" (fmap (const ()) overlap, i)++  -- the 'vars' bit seems to be for: instance forall a. C (T a) where ...+  -- TH's own parser seems to flat-out ignore them, and honestly I can't see+  -- that it's obviously wrong to do so.+#if MIN_VERSION_template_haskell(2,11,0)+  toDec (Hs.InstDecl _ Nothing irule ids) = InstanceD+    Nothing+    (toCxt irule)+    (toType irule)+    (toDecs ids)+#else+  toDec (Hs.InstDecl _ Nothing irule ids) = InstanceD+    (toCxt irule)+    (toType irule)+    (toDecs ids)+#endif++  toDec (Hs.ClassDecl _ cxt h fds decls) = ClassD+    (toCxt cxt)+    (toName h)+    (toTyVars h)+    (fmap toFunDep fds)+    (toDecs decls)+   where+    toFunDep (Hs.FunDep _ ls rs) = FunDep (fmap toName ls) (fmap toName rs)++  toDec x = todo "toDec" x++#if MIN_VERSION_haskell_src_exts(1,18,0)+instance ToMaybeKind (Hs.ResultSig l) where+    toMaybeKind (Hs.KindSig _ k) = Just $ toKind k+    toMaybeKind (Hs.TyVarSig _ _) = Nothing++instance ToMaybeKind a => ToMaybeKind (Maybe a) where+    toMaybeKind Nothing = Nothing+    toMaybeKind (Just a) = toMaybeKind a++#if MIN_VERSION_template_haskell(2,11,0)+instance ToInjectivityAnn (Hs.InjectivityInfo l) where+  toInjectivityAnn (Hs.InjectivityInfo _ n ns) = InjectivityAnn (toName n) (fmap toName ns)+#endif+#endif++transAct :: Maybe (Hs.Activation l) -> Phases+transAct Nothing = AllPhases+transAct (Just (Hs.ActiveFrom _ n)) = FromPhase n+transAct (Just (Hs.ActiveUntil _ n)) = BeforePhase n++instance ToName (Hs.DeclHead l) where+  toName (Hs.DHead _ n) = toName n+  toName (Hs.DHInfix _ _ n) = toName n+  toName (Hs.DHParen _ h) = toName h+  toName (Hs.DHApp _ h _) = toName h++instance ToTyVars (Hs.DeclHead l) where+  toTyVars (Hs.DHead _ _) = []+  toTyVars (Hs.DHParen _ h) = toTyVars h+  toTyVars (Hs.DHInfix _ tvb _) = [toTyVar tvb]+  toTyVars (Hs.DHApp _ h tvb) = toTyVars h ++ [toTyVar tvb]++instance ToNames a => ToNames (Maybe a) where+  toNames Nothing = []+  toNames (Just a) = toNames a++instance ToNames (Hs.Deriving l) where+  toNames (Hs.Deriving _ irules) = concatMap toNames irules+instance ToNames (Hs.InstRule l) where+  toNames (Hs.IParen _ irule) = toNames irule+  toNames (Hs.IRule _ _mtvbs _mcxt mihd) = toNames mihd+instance ToNames (Hs.InstHead l) where+  toNames (Hs.IHCon _ n) = [toName n]+  toNames (Hs.IHInfix _ _ n) = [toName n]+  toNames (Hs.IHParen _ h) = toNames h+  toNames (Hs.IHApp _ h _) = toNames h++instance ToCxt (Hs.InstRule l) where+  toCxt (Hs.IRule _ _ cxt _) = toCxt cxt+  toCxt (Hs.IParen _ irule) = toCxt irule++instance ToCxt (Hs.Context l) where+  toCxt x = case x of+              Hs.CxEmpty _ -> []+              Hs.CxSingle _ x' -> [toPred x']+              Hs.CxTuple _ xs -> fmap toPred xs++instance ToType (Hs.InstRule l) where+    toType (Hs.IRule _ _ _ h) = toType h+    toType (Hs.IParen _ irule) = toType irule++instance ToType (Hs.InstHead l) where+    toType (Hs.IHCon _ qn) = toType qn+    toType (Hs.IHInfix _ typ qn) = AppT (toType typ) (toType qn)+    toType (Hs.IHParen _ hd) = toType hd+    toType (Hs.IHApp _ hd typ) = AppT (toType hd) (toType typ)++qualConDeclToCon :: Hs.QualConDecl l -> Con+qualConDeclToCon (Hs.QualConDecl _ Nothing Nothing cdecl) = conDeclToCon cdecl+qualConDeclToCon (Hs.QualConDecl _ ns cxt cdecl) = ForallC (toTyVars ns)+                                                    (toCxt cxt)+                                                    (conDeclToCon cdecl)++instance ToTyVars a => ToTyVars (Maybe a) where+  toTyVars Nothing = []+  toTyVars (Just a) = toTyVars a++instance ToTyVars a => ToTyVars [a] where+  toTyVars = concatMap toTyVars++instance ToTyVars (Hs.TyVarBind l) where+  toTyVars tvb = [toTyVar tvb]++instance ToType (Hs.QName l) where+    toType = ConT . toName++conDeclToCon :: Hs.ConDecl l -> Con+conDeclToCon (Hs.ConDecl _ n tys)+  = NormalC (toName n) (map toStrictType tys)+conDeclToCon (Hs.RecDecl _ n fieldDecls)+  = RecC (toName n) (concatMap convField fieldDecls)+  where+    convField :: Hs.FieldDecl l -> [VarStrictType]+    convField (Hs.FieldDecl _ ns t) =+      let (strict, ty) = toStrictType t+      in map (\n' -> (toName n', strict, ty)) ns+++hsMatchesToFunD :: [Hs.Match l] -> Dec+hsMatchesToFunD [] = FunD (mkName []) []   -- errorish+hsMatchesToFunD xs@(Hs.Match _ n _ _ _ : _) = FunD (toName n) (fmap hsMatchToClause xs)+++hsMatchToClause :: Hs.Match l -> Clause+hsMatchToClause (Hs.Match _ _ ps rhs bnds) = Clause+                                                (fmap toPat ps)+                                                (hsRhsToBody rhs)+                                                (toDecs bnds)++++hsRhsToBody :: Hs.Rhs l -> Body+hsRhsToBody (Hs.UnGuardedRhs _ e) = NormalB (toExp e)+hsRhsToBody (Hs.GuardedRhss _ hsgrhs) = let fromGuardedB (GuardedB a) = a+                                      in GuardedB . concat+                                          . fmap (fromGuardedB . hsGuardedRhsToBody)+                                              $ hsgrhs++++hsGuardedRhsToBody :: Hs.GuardedRhs l -> Body+hsGuardedRhsToBody (Hs.GuardedRhs _ [] e)  = NormalB (toExp e)+hsGuardedRhsToBody (Hs.GuardedRhs _ [s] e) = GuardedB [(hsStmtToGuard s, toExp e)]+hsGuardedRhsToBody (Hs.GuardedRhs _ ss e)  = let ss' = fmap hsStmtToGuard ss+                                                 (pgs,ngs) = unzip [(p,n)+                                                               | (PatG p) <- ss'+                                                               , n@(NormalG _) <- ss']+                                                 e' = toExp e+                                                 patg = PatG (concat pgs)+                                            in GuardedB $ (patg,e') : zip ngs (repeat e')++++hsStmtToGuard :: Hs.Stmt l -> Guard+hsStmtToGuard (Hs.Generator _ p e) = PatG [BindS (toPat p) (toExp e)]+hsStmtToGuard (Hs.Qualifier _ e)     = NormalG (toExp e)+hsStmtToGuard (Hs.LetStmt _ bs)      = PatG [LetS (toDecs bs)]+++-----------------------------------------------------------------------------++-- * ToDecs InstDecl+instance ToDecs (Hs.InstDecl l) where+  toDecs (Hs.InsDecl _ decl) = toDecs decl+  toDecs d              = todo "toDec" d++-- * ToDecs HsDecl HsBinds++instance ToDecs (Hs.Decl l) where+  toDecs a@(Hs.TypeSig _ ns t)+    = let xs = fmap (flip SigD (fixForall $ toType t) . toName) ns+       in xs++  toDecs (Hs.InfixDecl l assoc Nothing ops) =+      toDecs (Hs.InfixDecl l assoc (Just 9) ops)+  toDecs (Hs.InfixDecl _ assoc (Just fixity) ops) =+    map (\op -> InfixD (Fixity fixity dir) (toName op)) ops+   where+    dir = case assoc of+      Hs.AssocNone _ -> InfixN+      Hs.AssocLeft _ -> InfixL+      Hs.AssocRight _ -> InfixR++  toDecs a = [toDec a]++collectVars e = case e of+  VarT n -> [PlainTV n]+  AppT t1 t2 -> nub $ collectVars t1 ++ collectVars t2+  ForallT ns _ t -> collectVars t \\ ns+  _          -> []++fixForall t@(ForallT _ _ _) = t+fixForall t = case vs of+  [] -> t+  _  -> ForallT vs [] t+  where vs = collectVars t++instance ToDecs a => ToDecs [a] where+  toDecs a = concatMap toDecs a++-----------------------------------------------------------------------------
+ doc/color_conversions.png view

binary file changed (absent → 904754 bytes)

+ doc/generated/FontHersheyComplex.png view

binary file changed (absent → 8710 bytes)

+ doc/generated/FontHersheyComplexSmall.png view

binary file changed (absent → 5691 bytes)

+ doc/generated/FontHersheyComplexSmall_slanted.png view

binary file changed (absent → 6119 bytes)

+ doc/generated/FontHersheyComplex_slanted.png view

binary file changed (absent → 9656 bytes)

+ doc/generated/FontHersheyDuplex.png view

binary file changed (absent → 7683 bytes)

+ doc/generated/FontHersheyDuplex_slanted.png view

binary file changed (absent → 7683 bytes)

+ doc/generated/FontHersheyPlain.png view

binary file changed (absent → 3248 bytes)

+ doc/generated/FontHersheyPlain_slanted.png view

binary file changed (absent → 3255 bytes)

+ doc/generated/FontHersheyScriptComplex.png view

binary file changed (absent → 7639 bytes)

+ doc/generated/FontHersheyScriptComplex_slanted.png view

binary file changed (absent → 7639 bytes)

+ doc/generated/FontHersheyScriptSimplex.png view

binary file changed (absent → 7607 bytes)

+ doc/generated/FontHersheyScriptSimplex_slanted.png view

binary file changed (absent → 7607 bytes)

+ doc/generated/FontHersheySimplex.png view

binary file changed (absent → 6557 bytes)

+ doc/generated/FontHersheySimplex_slanted.png view

binary file changed (absent → 6557 bytes)

+ doc/generated/FontHersheyTriplex.png view

binary file changed (absent → 9664 bytes)

+ doc/generated/FontHersheyTriplex_slanted.png view

binary file changed (absent → 10460 bytes)

+ doc/generated/LineType_4.png view

binary file changed (absent → 332 bytes)

+ doc/generated/LineType_8.png view

binary file changed (absent → 341 bytes)

+ doc/generated/LineType_AA.png view

binary file changed (absent → 415 bytes)

+ doc/generated/bikes_512x341.png view

binary file changed (absent → 355695 bytes)

+ doc/generated/birds_512x341.png view

binary file changed (absent → 266639 bytes)

+ doc/generated/examples/animation.gif view

binary file changed (absent → 20183 bytes)

+ doc/generated/examples/arrowedLineImg.png view

binary file changed (absent → 6294 bytes)

+ doc/generated/examples/bfMatcherImg.png view

binary file changed (absent → 509680 bytes)

+ doc/generated/examples/bitwiseAndImg.png view

binary file changed (absent → 8706 bytes)

+ doc/generated/examples/bitwiseNotImg.png view

binary file changed (absent → 7813 bytes)

+ doc/generated/examples/bitwiseOrImg.png view

binary file changed (absent → 10059 bytes)

+ doc/generated/examples/bitwiseXorImg.png view

binary file changed (absent → 11291 bytes)

+ doc/generated/examples/boxBlurImg.png view

binary file changed (absent → 440308 bytes)

+ doc/generated/examples/cannyImg.png view

binary file changed (absent → 1717 bytes)

+ doc/generated/examples/cascadeClassifierArnold.png view

binary file changed (absent → 661798 bytes)

+ doc/generated/examples/circleImg.png view

binary file changed (absent → 11850 bytes)

+ doc/generated/examples/colorMapAutumImg.png view

binary file changed (absent → 234 bytes)

+ doc/generated/examples/colorMapBoneImg.png view

binary file changed (absent → 350 bytes)

+ doc/generated/examples/colorMapCoolImg.png view

binary file changed (absent → 231 bytes)

+ doc/generated/examples/colorMapHotImg.png view

binary file changed (absent → 317 bytes)

+ doc/generated/examples/colorMapHsvImg.png view

binary file changed (absent → 270 bytes)

+ doc/generated/examples/colorMapJetImg.png view

binary file changed (absent → 259 bytes)

+ doc/generated/examples/colorMapOceanImg.png view

binary file changed (absent → 274 bytes)

+ doc/generated/examples/colorMapParulaImg.png view

binary file changed (absent → 445 bytes)

+ doc/generated/examples/colorMapPinkImg.png view

binary file changed (absent → 415 bytes)

+ doc/generated/examples/colorMapRainbowImg.png view

binary file changed (absent → 324 bytes)

+ doc/generated/examples/colorMapSpringImg.png view

binary file changed (absent → 230 bytes)

+ doc/generated/examples/colorMapSummerImg.png view

binary file changed (absent → 239 bytes)

+ doc/generated/examples/colorMapWinterImg.png view

binary file changed (absent → 248 bytes)

+ doc/generated/examples/cvtColorImg.png view

binary file changed (absent → 433263 bytes)

+ doc/generated/examples/dctDenoisingImg.png view

binary file changed (absent → 879420 bytes)

+ doc/generated/examples/decolorImg.png view

binary file changed (absent → 940483 bytes)

+ doc/generated/examples/denoise_TVL1Img.png view

binary file changed (absent → 1009258 bytes)

+ doc/generated/examples/dilateImg.png view

binary file changed (absent → 3105 bytes)

+ doc/generated/examples/ellipseImg.png view

binary file changed (absent → 11458 bytes)

+ doc/generated/examples/erodeImg.png view

binary file changed (absent → 3107 bytes)

+ doc/generated/examples/fastNlMeansDenoisingColoredImg.png view

binary file changed (absent → 913667 bytes)

+ doc/generated/examples/fastNlMeansDenoisingColoredMultiImg.png view

binary file changed (absent → 913667 bytes)

+ doc/generated/examples/fbMatcherImg.png view

binary file changed (absent → 513475 bytes)

+ doc/generated/examples/fillConvexPolyImg.png view

binary file changed (absent → 6152 bytes)

+ doc/generated/examples/fillPolyImg.png view

binary file changed (absent → 4750 bytes)

+ doc/generated/examples/filter2DImg.png view

binary file changed (absent → 651140 bytes)

+ doc/generated/examples/floodFillImg.png view

binary file changed (absent → 704232 bytes)

+ doc/generated/examples/flowerContours.png view

binary file changed (absent → 232432 bytes)

+ doc/generated/examples/fromImageImg.png view

binary file changed (absent → 523220 bytes)

+ doc/generated/examples/fromJuicyImg.png view

binary file changed (absent → 523220 bytes)

+ doc/generated/examples/fromJuicyPixelsImg.png view

binary file changed (absent → 523220 bytes)

+ doc/generated/examples/goodFeaturesToTrackTraces.png view

binary file changed (absent → 268834 bytes)

+ doc/generated/examples/grabCutBird.png view

binary file changed (absent → 92520 bytes)

+ doc/generated/examples/grayscaleImg.png view

binary file changed (absent → 134 bytes)

+ doc/generated/examples/grayworldWBImg.png view

file too large to diff

+ doc/generated/examples/houghCircleTraces.png view

binary file changed (absent → 701557 bytes)

+ doc/generated/examples/houghLinesPTraces.png view

binary file changed (absent → 64520 bytes)

+ doc/generated/examples/inpaintImg.png view

binary file changed (absent → 783985 bytes)

+ doc/generated/examples/laplacianImg.png view

binary file changed (absent → 84466 bytes)

+ doc/generated/examples/lineImg.png view

binary file changed (absent → 3948 bytes)

+ doc/generated/examples/markerImg.png view

binary file changed (absent → 575 bytes)

+ doc/generated/examples/matAbsDiffImg.png view

binary file changed (absent → 354361 bytes)

+ doc/generated/examples/matAddImg.png view

binary file changed (absent → 287078 bytes)

+ doc/generated/examples/matAddWeightedImg.png view

binary file changed (absent → 289585 bytes)

+ doc/generated/examples/matFlipImg.png view

binary file changed (absent → 296107 bytes)

+ doc/generated/examples/matFromFuncImg.png view

binary file changed (absent → 67119 bytes)

+ doc/generated/examples/matSplitImg.png view

binary file changed (absent → 390890 bytes)

+ doc/generated/examples/matSubRectImg.png view

binary file changed (absent → 477260 bytes)

+ doc/generated/examples/matSubtractImg.png view

binary file changed (absent → 196826 bytes)

+ doc/generated/examples/matSumImg.png view

binary file changed (absent → 3313 bytes)

+ doc/generated/examples/matTransposeImg.png view

binary file changed (absent → 298870 bytes)

+ doc/generated/examples/medianBlurImg.png view

binary file changed (absent → 455977 bytes)

+ doc/generated/examples/morphCrossImg.png view

binary file changed (absent → 173 bytes)

+ doc/generated/examples/morphEllipseImg.png view

binary file changed (absent → 647 bytes)

+ doc/generated/examples/morphRectImg.png view

binary file changed (absent → 151 bytes)

+ doc/generated/examples/orbDetectAndComputeImg.png view

binary file changed (absent → 279069 bytes)

+ doc/generated/examples/polylinesImg.png view

binary file changed (absent → 6384 bytes)

+ doc/generated/examples/putTextImg.png view

binary file changed (absent → 32827 bytes)

+ doc/generated/examples/rectangleImg.png view

binary file changed (absent → 2294 bytes)

+ doc/generated/examples/remapImg.png view

binary file changed (absent → 220259 bytes)

+ doc/generated/examples/resizeInterAreaImg.png view

binary file changed (absent → 779235 bytes)

+ doc/generated/examples/surfDetectAndComputeImg.png view

binary file changed (absent → 381700 bytes)

+ doc/generated/examples/threshBinaryBirds.png view

binary file changed (absent → 13500 bytes)

+ doc/generated/examples/threshBinaryInvBirds.png view

binary file changed (absent → 13504 bytes)

+ doc/generated/examples/threshToZeroBirds.png view

binary file changed (absent → 84693 bytes)

+ doc/generated/examples/threshToZeroInvBirds.png view

binary file changed (absent → 83193 bytes)

+ doc/generated/examples/threshTruncateBirds.png view

binary file changed (absent → 78049 bytes)

+ doc/generated/examples/toImageImg.png view

binary file changed (absent → 524412 bytes)

+ doc/generated/examples/undistortImg.png view

binary file changed (absent → 215796 bytes)

+ doc/generated/examples/vennCircleAImg.png view

binary file changed (absent → 2588 bytes)

+ doc/generated/examples/vennCircleBImg.png view

binary file changed (absent → 2473 bytes)

+ doc/generated/examples/warpAffineImg.png view

binary file changed (absent → 156486 bytes)

+ doc/generated/examples/warpAffineInvImg.png view

binary file changed (absent → 234899 bytes)

+ doc/generated/flower_512x341.png view

binary file changed (absent → 277498 bytes)

+ doc/generated/sailboat_512x341.png view

binary file changed (absent → 295814 bytes)

+ doc/images.hs view
@@ -0,0 +1,270 @@+{-# language TemplateHaskell #-}+{-# language OverloadedStrings #-}+{-# language FlexibleContexts #-}+{-# language CPP #-}++module Main where++import "base" Data.Functor ( void )+import "base" Data.Foldable ( forM_ )+import "base" Data.Int+import "base" Data.Monoid ( (<>) )+import "base" Data.Proxy+import "base" Data.Traversable+import "base" Data.Word+import "base" Foreign.C.Types ( CFloat )+import "base" GHC.TypeLits+import "base" System.IO.Unsafe ( unsafePerformIO )+import "data-default" Data.Default+import qualified "bytestring" Data.ByteString as B+import qualified "JuicyPixels" Codec.Picture+import qualified "linear" Linear.Metric as Linear ( norm )+import "linear" Linear ( M33 )+import "linear" Linear.Vector ( (^+^), (^-^) )+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.V3 ( V3(..) )+import "linear" Linear.V4 ( V4(..) )+import "opencv" OpenCV+import qualified "opencv" OpenCV.Juicy+import "opencv" OpenCV.Unsafe+#ifdef HAVE_OPENCV_EXTRA+import "opencv-extra" OpenCV.Extra+#endif+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState )+import qualified "text" Data.Text as T+import qualified "vector" Data.Vector as V+import "transformers" Control.Monad.Trans.Class ( lift )++import "this" ExampleExtractor++--------------------------------------------------------------------------------++transparent, white, black, blue, green, red :: Scalar+transparent = toScalar (V4 255 255 255   0 :: V4 Double)+white       = toScalar (V4 255 255 255 255 :: V4 Double)+black       = toScalar (V4   0   0   0 255 :: V4 Double)+blue        = toScalar (V4 255   0   0 255 :: V4 Double)+green       = toScalar (V4   0 255   0 255 :: V4 Double)+red         = toScalar (V4   0   0 255 255 :: V4 Double)++type Birds_768x512    = Mat (ShapeT [512, 768]) ('S 3) ('S Word8)+type Flower_768x512   = Mat (ShapeT [512, 768]) ('S 3) ('S Word8)+type Sailboat_768x512 = Mat (ShapeT [512, 768]) ('S 3) ('S Word8)+type Bikes_768x512    = Mat (ShapeT [512, 768]) ('S 3) ('S Word8)+type Birds_512x341    = Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+type Flower_512x341   = Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+type Sailboat_512x341 = Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+type Bikes_512x341    = Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+type Frog             = Mat (ShapeT [390, 500]) ('S 3) ('S Word8)+type Lambda           = Mat (ShapeT [256, 256]) ('S 1) ('S Word8)+type Circles_1000x625 = Mat (ShapeT [625, 1000]) ('S 3) ('S Word8)+type Building_868x600 = Mat (ShapeT [600, 868]) ('S 3) ('S Word8)+type DamageMask       = Mat (ShapeT [341, 512]) ('S 1) ('S Word8)+type Lenna_512x512    = Mat (ShapeT [512, 512]) ('S 3) ('S Word8)+type Arnold           = Mat (ShapeT [3504, 2336]) ('S 3) ('S Word8)+type Arnold_small     = Mat (ShapeT [ 900,  600]) ('S 3) ('S Word8)++birds_768x512 :: Birds_768x512+birds_768x512 = exceptError $ coerceMat $ unsafePerformIO $+                  imdecode ImreadUnchanged <$> B.readFile "data/kodim23.png"++flower_768x512 :: Flower_768x512+flower_768x512 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/kodim07.png"++sailboat_768x512 :: Sailboat_768x512+sailboat_768x512 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/kodim06.png"++bikes_768x512 :: Sailboat_768x512+bikes_768x512 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/kodim05.png"++damageMask :: DamageMask+damageMask =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/damage_mask.png"++smallerKodakImg+    :: Mat (ShapeT [512, 768]) ('S 3) ('S Word8)+    -> Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+smallerKodakImg img =+    exceptError $ coerceMat =<<+      resize (ResizeAbs $ toSize (V2 512 341 :: V2 Int32))+             InterArea+             img++birds_512x341 :: Birds_512x341+birds_512x341 = smallerKodakImg birds_768x512++flower_512x341 :: Flower_512x341+flower_512x341 = smallerKodakImg flower_768x512++sailboat_512x341 :: Flower_512x341+sailboat_512x341 = smallerKodakImg sailboat_768x512++bikes_512x341 :: Flower_512x341+bikes_512x341 = smallerKodakImg bikes_768x512++frog :: Frog+frog =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/kikker.jpg"++lambda :: Lambda+lambda =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadGrayscale <$> B.readFile "data/lambda.png"++circles_1000x625 :: Circles_1000x625+circles_1000x625 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/circles.png"++building_868x600 :: Building_868x600+building_868x600 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/building.jpg"++lenna_512x512 :: Lenna_512x512+lenna_512x512 =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/Lenna.png"++arnold :: Arnold+arnold =+    exceptError $ coerceMat $ unsafePerformIO $+      imdecode ImreadUnchanged <$> B.readFile "data/arnold-schwarzenegger.jpg"++arnold_small :: Arnold_small+arnold_small =+    exceptError $ coerceMat =<<+      resize (ResizeAbs $ toSize (V2 600 900 :: V2 Int32))+             InterArea+             arnold++--------------------------------------------------------------------------------++type CarOverhead = Animation (ShapeT [240, 320]) ('S 3) ('S Word8)++carOverhead :: CarOverhead+carOverhead = unsafePerformIO $ loadAnimation 4 "data/car-overhead-3.mp4"++--------------------------------------------------------------------------------++loadAnimation+    :: (ToNatDS (Proxy h), ToNatDS (Proxy w))+    => Int+    -> FilePath+    -> IO (Animation ('S [h, w]) ('S 3) ('S Word8))+loadAnimation delay fp = do+    cap <- newVideoCapture+    exceptErrorIO $ videoCaptureOpen cap (VideoFileSource fp Nothing)+    frames <- grabFrames cap []+    exceptErrorIO $ videoCaptureRelease cap+    pure $ map (delay, ) frames+  where+    grabFrames cap frames = do+        ok <- videoCaptureGrab cap+        if ok+        then do+          mbFrameRaw <- videoCaptureRetrieve cap+          case mbFrameRaw of+            Nothing -> pure $ reverse frames+            Just frameRaw -> do+              frame <- exceptErrorIO $ pureExcept $ coerceMat frameRaw+              grabFrames cap (frame : frames)+        else pure $ reverse frames++--------------------------------------------------------------------------------++-- We use some padding around the small image in which we draw the+-- lines. This is because antialiasing doesn't seem to work near the+-- edges of an image.+lineTypeImg+    :: forall (h :: Nat) (w :: Nat) (p :: Nat)+     . ( h ~ 5+       , w ~ (h * 3)+       , p ~ 20+       )+    => LineType+    -> Mat ('S ['D, 'D]) ('S 4) ('S Word8)+lineTypeImg lineType = exceptError $ do+    img <- withMatM (h + 2 * p ::: w + 2 * p ::: Z)+                    (Proxy :: Proxy 4)+                    (Proxy :: Proxy Word8)+                    transparent $ \imgM -> do+             lift $ line imgM (pure p + V2 0 h) (pure p + V2 w 0) black 1 lineType 0+    resize (ResizeRel $ pure zoom) InterNearest+           =<< matSubRect img (toRect $ HRect (pure p) (V2 w h))+  where+    w, h, p :: Int32+    w = fromInteger $ natVal (Proxy :: Proxy w)+    h = fromInteger $ natVal (Proxy :: Proxy h)+    p = fromInteger $ natVal (Proxy :: Proxy p)+    zoom = 8++fontImg+    :: Font+    -> Mat ('S ['D, 'D]) ('S 4) ('S Word8)+fontImg font = exceptError $+    withMatM (th * 3 ::: tw ::: Z)+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \imgM -> do+      putText+        imgM+        txt+        (V2 0 (th * 2 - baseLine) :: V2 Int32)+        font+        black+        thickness+        LineType_AA False+  where+    txt = "The quick brown fox jumps over the lazy dog"+    (size2i, baseLine) = getTextSize txt font thickness+    tw, th :: Int32+    V2 tw th = fromSize size2i+    thickness = 1++vennCircleA+    :: (PrimMonad m, ToScalar color)+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m)+    -> color+    -> Int32+    -> m ()+vennCircleA imgM color thickness =+    circle imgM (V2 100 100 :: V2 Int32) 90 color thickness LineType_AA 0++vennCircleB+    :: (PrimMonad m, ToScalar color)+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m)+    -> color+    -> Int32+    -> m ()+vennCircleB imgM color thickness =+    circle imgM (V2 220 100 :: V2 Int32) 90 color thickness LineType_AA 0++--------------------------------------------------------------------------------++extractExampleImages "src"++--------------------------------------------------------------------------------++main :: IO ()+main = do+    renderExampleImages+    renderImage "birds_512x341.png"    birds_512x341+    renderImage "flower_512x341.png"   flower_512x341+    renderImage "sailboat_512x341.png" sailboat_512x341+    renderImage "bikes_512x341.png"    bikes_512x341+    forM_ [minBound .. maxBound] $ \lineType ->+      renderImage (show lineType <> ".png") (lineTypeImg lineType)+    forM_ [minBound .. maxBound] $ \fontFace -> do+      renderImage (show fontFace <> ".png")         (fontImg $ Font fontFace NotSlanted 1)+      renderImage (show fontFace <> "_slanted.png") (fontImg $ Font fontFace Slanted    1)++--------------------------------------------------------------------------------
+ include/haskell_opencv_matx_typedefs.hpp view
@@ -0,0 +1,8 @@+#ifndef __HASKELL_OPENCV_MATX_TYPEDEFS_H__+#define __HASKELL_OPENCV_MATX_TYPEDEFS_H__++// Missing type aliases in OpenCV+namespace cv { typedef Matx<float, 5, 1> Matx51f; }+namespace cv { typedef Matx<double, 5, 1> Matx51d; }++#endif /* __HASKELL_OPENCV_MATX_TYPEDEFS_H__ */
+ include/hsc_macros.hpp view
@@ -0,0 +1,30 @@+#ifndef __HSC_MACROS_H__+#define __HSC_MACROS_H__++/*+This files defines some hsc2hs macros. For documentation on how to construct custom macros see:+https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/utils.html#custom-constructs+*/++#include <bindings.dsl.h>++#define bc_sizeof_varid(name) {printf("c'sizeof_");bc_word(name);}; \++/*+The #sizeof macro outputs a Haskell constant with the size of the C/C++ type in bytes.++For example the following:++  #sizeof Point2i++Results in the following Haskell code:++  c'sizeof_Point2i :: Int+  c'sizeof_Point2i = 8+*/+#define hsc_sizeof(name) \+  { bc_sizeof_varid(# name);printf(" :: Int\n"); \+    bc_sizeof_varid(# name);printf(" = %lu\n", sizeof(name)); \+  }; \++#endif /* __HSC_MACROS_H__ */
+ include/namespace.hpp view
@@ -0,0 +1,20 @@+#ifndef __THEA_NAMESPACE_H__+#define __THEA_NAMESPACE_H__++/*+Various .hsc files in this library need to refer to symbols in the cv namespace.+For example:++  #num EVENT_FLAG_LBUTTON++We can't just write:++  #num cv::EVENT_FLAG_LBUTTON++because that will result in invalid syntax. So instead we include this+header file which brings the cv namespace into scope.+*/++using namespace cv;++#endif /* __THEA_NAMESPACE_H__ */
+ include/orb.hpp view
@@ -0,0 +1,19 @@+#ifndef __THEA_ORB_H__+#define __THEA_ORB_H__++/*+This file defines some ORB related names that are used in++  src/OpenCV/Features2d.hsc.++The reason we need these names is that we can't directly reference their+definitions because that would result in invalid syntax in either hsc2hs and+inline-c.+*/++#define HARRIS_SCORE cv::ORB::HARRIS_SCORE+#define FAST_SCORE   cv::ORB::FAST_SCORE++typedef cv::Ptr<cv::ORB> Ptr_ORB;++#endif /* __THEA_ORB_H__ */
+ include/simple_blob_detector.hpp view
@@ -0,0 +1,16 @@+#ifndef __HASKELL_OPENCV_SIMPLE_BLOB_DETECTOR_H__+#define __HASKELL_OPENCV_SIMPLE_BLOB_DETECTOR_H__++/*+This file defines some SimpleBlobDetector related names that are used in++  src/OpenCV/Features2d.hsc.++The reason we need these names is that we can't directly reference their+definitions because that would result in invalid syntax in either hsc2hs and+inline-c.+*/++typedef cv::Ptr<cv::SimpleBlobDetector> Ptr_SimpleBlobDetector;++#endif /* __HASKELL_OPENCV_SIMPLE_BLOB_DETECTOR_H__ */
+ include/termcriteria.hpp view
@@ -0,0 +1,7 @@+#ifndef __THEA_TERMCRITERIA_H__+#define __THEA_TERMCRITERIA_H__++#define TERMCRITERIA_COUNT TermCriteria::COUNT+#define TERMCRITERIA_EPS   TermCriteria::EPS++#endif /* __THEA_TERMCRITERIA_H__ */
+ include/video_motion_analysis.hpp view
@@ -0,0 +1,7 @@+#ifndef __HASKELL_OPENCV_VIDEO_MOTION_ANALYSIS_H__+#define __HASKELL_OPENCV_VIDEO_MOTION_ANALYSIS_H__++typedef cv::Ptr<cv::BackgroundSubtractorKNN>  Ptr_BackgroundSubtractorKNN;+typedef cv::Ptr<cv::BackgroundSubtractorMOG2> Ptr_BackgroundSubtractorMOG2;++#endif /* __HASKELL_OPENCV_VIDEO_MOTION_ANALYSIS_H__ */
+ opencv.cabal view
@@ -0,0 +1,278 @@+name:          opencv+version:       0.0.0.0+homepage:      https://github.com/LumiGuide/haskell-opencv+license:       BSD3+license-file:  LICENSE+author:        Roel van Dijk <roel@lambdacube.nl>, Bas van Dijk <v.dijk.bas@gmail.com>+maintainer:    Roel van Dijk <roel@lambdacube.nl>, Bas van Dijk <v.dijk.bas@gmail.com>+build-type:    Custom+cabal-version: >=1.23+category:      AI, Graphics+synopsis:      Haskell binding to OpenCV-3.x+description:   This is a Haskell library providing a binding to OpenCV-3.x.+               It binds directly with the C++ API using the @inline-c@ Haskell library.+               .+               The library is far from complete but the framework is there to easily+               bind missing functionality.++extra-source-files:+    data/*.png+    data/*.jpg++extra-doc-files:+    doc/generated/*.png+    doc/generated/examples/*.png+    doc/generated/examples/*.gif+    doc/color_conversions.png++flag internal-documentation+    description: Enables documentation generation for internal modules.+    default: False+    manual: True++custom-setup+    setup-depends: base, Cabal++library+    hs-source-dirs: src+    include-dirs: include+    install-includes:+      haskell_opencv_matx_typedefs.hpp+      hsc_macros.hpp+      namespace.hpp+      orb.hpp+      simple_blob_detector.hpp+      termcriteria.hpp+      video_motion_analysis.hpp++    c-sources:+        src/OpenCV/Calib3d.cpp+      , src/OpenCV/Core/ArrayOps.cpp+      , src/OpenCV/Core/Types.cpp+      , src/OpenCV/Core/Types/Mat.cpp+      , src/OpenCV/Core/Types/Mat/Repa.cpp+      , src/OpenCV/Core/Types/Matx.cpp+      , src/OpenCV/Core/Types/Point.cpp+      , src/OpenCV/Core/Types/Rect.cpp+      , src/OpenCV/Core/Types/Size.cpp+      , src/OpenCV/Core/Types/Vec.cpp+      , src/OpenCV/Features2d.cpp+      , src/OpenCV/HighGui.cpp+      , src/OpenCV/ImgCodecs.cpp+      , src/OpenCV/ImgProc/ColorMaps.cpp+      , src/OpenCV/ImgProc/Drawing.cpp+      , src/OpenCV/ImgProc/FeatureDetection.cpp+      , src/OpenCV/ImgProc/GeometricImgTransform.cpp+      , src/OpenCV/ImgProc/ImgFiltering.cpp+      , src/OpenCV/ImgProc/MiscImgTransform.cpp+      , src/OpenCV/ImgProc/ObjectDetection.cpp+      , src/OpenCV/ImgProc/StructuralAnalysis.cpp+      , src/OpenCV/ImgProc/CascadeClassifier.cpp+      , src/OpenCV/Internal/Core/Types.cpp+      , src/OpenCV/Internal/Core/Types/Mat.cpp+      , src/OpenCV/Internal/Core/Types/Mat/ToFrom.cpp+      , src/OpenCV/Internal/Exception.cpp+      , src/OpenCV/Photo.cpp+      , src/OpenCV/Video.cpp+      , src/OpenCV/VideoIO/VideoCapture.cpp+      , src/OpenCV/VideoIO/VideoWriter.cpp+      , src/OpenCV/Video/MotionAnalysis.cpp++    cc-options: -Wall -std=c++11+    ghc-options: -Wall -fwarn-incomplete-patterns -funbox-strict-fields -O2+    if flag(internal-documentation)+        cpp-options: -DENABLE_INTERNAL_DOCUMENTATION++    build-depends:+        aeson             >= 0.9.0.1+      , base              >= 4.8     && <5+      , base64-bytestring >= 1.0.0.1+      , bindings-DSL      >= 1.0.23+      , bytestring        >= 0.10.6+      , containers        >= 0.5.6.2+      , data-default      >= 0.7.1.1+      , deepseq           >= 1.4.1.1+      , inline-c          >= 0.5.5.5+      , inline-c-cpp      >= 0.1+      , JuicyPixels       >= 3.2.8.1+      , linear            >= 1.20.4+      , primitive         >= 0.6.1+      , repa              >= 3.4.0.2+      , template-haskell  >= 2.10+      , text              >= 1.2.2.1+      , transformers      >= 0.4.2+      , vector            >= 0.11++    exposed-modules:+        OpenCV+        OpenCV.Calib3d+        OpenCV.Core.ArrayOps+        OpenCV.Core.Types+        OpenCV.Core.Types.Mat+        OpenCV.Core.Types.Mat.HMat+        OpenCV.Core.Types.Mat.Repa+        OpenCV.Core.Types.Matx+        OpenCV.Core.Types.Point+        OpenCV.Core.Types.Rect+        OpenCV.Core.Types.Size+        OpenCV.Core.Types.Vec+        OpenCV.Exception+        OpenCV.Features2d+        OpenCV.HighGui+        OpenCV.ImgCodecs+        OpenCV.ImgProc.ColorMaps+        OpenCV.ImgProc.Drawing+        OpenCV.ImgProc.FeatureDetection+        OpenCV.ImgProc.GeometricImgTransform+        OpenCV.ImgProc.ImgFiltering+        OpenCV.ImgProc.MiscImgTransform+        OpenCV.ImgProc.MiscImgTransform.ColorCodes+        OpenCV.ImgProc.ObjectDetection+        OpenCV.ImgProc.StructuralAnalysis+        OpenCV.ImgProc.Types+        OpenCV.ImgProc.CascadeClassifier+        OpenCV.JSON+        OpenCV.Photo+        OpenCV.TypeLevel+        OpenCV.Unsafe+        OpenCV.Video+        OpenCV.Video.MotionAnalysis+        OpenCV.VideoIO.Types+        OpenCV.VideoIO.VideoCapture+        OpenCV.VideoIO.VideoWriter++        OpenCV.Internal+        OpenCV.Internal.Mutable+        OpenCV.Internal.C.Inline+        OpenCV.Internal.C.PlacementNew+        OpenCV.Internal.C.PlacementNew.TH+        OpenCV.Internal.C.Types+        OpenCV.Internal.Calib3d.Constants+        OpenCV.Internal.Core.ArrayOps+        OpenCV.Internal.Core.Types+        OpenCV.Internal.Core.Types.Constants+        OpenCV.Internal.Core.Types.Mat+        OpenCV.Internal.Core.Types.Mat.Depth+        OpenCV.Internal.Core.Types.Mat.HMat+        OpenCV.Internal.Core.Types.Mat.Marshal+        OpenCV.Internal.Core.Types.Mat.ToFrom+        OpenCV.Internal.Core.Types.Matx+        OpenCV.Internal.Core.Types.Matx.TH+        OpenCV.Internal.Core.Types.Point+        OpenCV.Internal.Core.Types.Point.TH+        OpenCV.Internal.Core.Types.Rect+        OpenCV.Internal.Core.Types.Rect.TH+        OpenCV.Internal.Core.Types.Size+        OpenCV.Internal.Core.Types.Size.TH+        OpenCV.Internal.Core.Types.Vec+        OpenCV.Internal.Core.Types.Vec.TH+        OpenCV.Internal.Exception+        OpenCV.Internal.ImgCodecs+        OpenCV.Internal.ImgProc.MiscImgTransform+        OpenCV.Internal.ImgProc.MiscImgTransform.TypeLevel+        OpenCV.Internal.ImgProc.MiscImgTransform.ColorCodes+        OpenCV.Internal.ImgProc.Types+        OpenCV.Internal.Photo.Constants+        OpenCV.Internal.VideoIO.Constants+        OpenCV.Internal.VideoIO.Types+        OpenCV.Juicy++    default-extensions:+        BangPatterns+        DataKinds+        FlexibleContexts+        FlexibleInstances+        LambdaCase+        OverloadedStrings+        PackageImports+        PolyKinds+        ScopedTypeVariables+        TupleSections+        TypeFamilies+        TypeOperators++    default-language:   Haskell2010+    pkgconfig-depends:  opencv+    extra-libraries:    stdc++++test-suite doc-images-opencv+    type: exitcode-stdio-1.0+    hs-source-dirs: doc+    main-is: images.hs+    other-modules: ExampleExtractor+                   Language.Haskell.Meta.Syntax.Translate+    default-language: Haskell2010+    ghc-options: -Wall -fwarn-incomplete-patterns -threaded -funbox-strict-fields -O2 -rtsopts+    build-depends:+        base              >= 4.8 && < 5+      , bytestring        >= 0.10.6+      , containers        >= 0.5.6.2+      , data-default      >= 0.7.1.1+      , directory         >= 1.2.2+      , Glob              >= 0.7.5+      , haskell-src-exts  >= 1.18.2+      , JuicyPixels       >= 3.2.8.1+      , linear            >= 1.20.4+      , opencv            == 0.0.0+      , primitive         >= 0.6.1+      , template-haskell  >= 2.10+      , text              >= 1.2.2.1+      , transformers      >= 0.4.2+      , vector            >= 0.11++    default-extensions:+        BangPatterns+        DataKinds+        LambdaCase+        OverloadedStrings+        PackageImports+        PolyKinds+        ScopedTypeVariables+        TupleSections+        TypeFamilies+        TypeOperators++test-suite test-opencv+    type:             exitcode-stdio-1.0+    hs-source-dirs:   test+    main-is:          test.hs+    default-language: Haskell2010+    ghc-options:      -Wall -fwarn-incomplete-patterns -threaded -funbox-strict-fields -O2 -rtsopts+    build-depends:+        base              >= 4.8 && < 5+      , bytestring        >= 0.10.6+      , lens              >= 4.13+      , linear            >= 1.20.4+      , opencv            == 0.0.0+      , QuickCheck        >= 2.8.2+      , repa              >= 3.4.0.2+      , tasty             >= 0.11.0.2+      , tasty-hunit       >= 0.9.2+      , tasty-quickcheck  >= 0.8.4+      , transformers      >= 0.4.2+      , vector            >= 0.11++    default-extensions:+        DataKinds+        FlexibleContexts+        PackageImports+        RankNTypes+        ScopedTypeVariables+        TypeOperators++benchmark bench-opencv+    type:             exitcode-stdio-1.0+    hs-source-dirs:   bench+    main-is:          bench.hs+    default-language: Haskell2010+    ghc-options: -Wall -fwarn-incomplete-patterns -threaded -funbox-strict-fields -O2 -rtsopts+    build-depends:+        base              >= 4.8 && < 5+      , bytestring        >= 0.10.6+      , criterion         >= 1.1.1+      , opencv            == 0.0.0+      , repa              >= 3.4.0.2++    default-extensions:+        DataKinds+        PackageImports
+ src/OpenCV.hs view
@@ -0,0 +1,63 @@+{-# OPTIONS_GHC -fno-warn-dodgy-exports #-}++module OpenCV+  ( module OpenCV.Calib3d+  , module OpenCV.Core.ArrayOps+  , module OpenCV.Core.Types+  , module OpenCV.Core.Types.Mat+  , module OpenCV.Core.Types.Mat.HMat+  , module OpenCV.Core.Types.Mat.Repa+  , module OpenCV.Core.Types.Matx+  , module OpenCV.Core.Types.Point+  , module OpenCV.Features2d+  , module OpenCV.HighGui+  , module OpenCV.ImgCodecs+  , module OpenCV.ImgProc.CascadeClassifier+  , module OpenCV.ImgProc.ColorMaps+  , module OpenCV.ImgProc.Drawing+  , module OpenCV.ImgProc.FeatureDetection+  , module OpenCV.ImgProc.GeometricImgTransform+  , module OpenCV.ImgProc.ImgFiltering+  , module OpenCV.ImgProc.MiscImgTransform+  , module OpenCV.ImgProc.ObjectDetection+  , module OpenCV.ImgProc.StructuralAnalysis+  , module OpenCV.ImgProc.Types+  , module OpenCV.Photo+  , module OpenCV.Video+  , module OpenCV.Video.MotionAnalysis+  , module OpenCV.VideoIO.VideoCapture++  , module OpenCV.TypeLevel++  , module OpenCV.JSON+  ) where++import OpenCV.Calib3d+import OpenCV.Core.ArrayOps+import OpenCV.Core.Types+import OpenCV.Core.Types.Mat+import OpenCV.Core.Types.Mat.HMat+import OpenCV.Core.Types.Mat.Repa+import OpenCV.Core.Types.Matx+import OpenCV.Core.Types.Point+import OpenCV.Features2d+import OpenCV.HighGui+import OpenCV.ImgCodecs+import OpenCV.ImgProc.ColorMaps+import OpenCV.ImgProc.Drawing+import OpenCV.ImgProc.FeatureDetection+import OpenCV.ImgProc.GeometricImgTransform+import OpenCV.ImgProc.ImgFiltering+import OpenCV.ImgProc.MiscImgTransform+import OpenCV.ImgProc.ObjectDetection+import OpenCV.ImgProc.StructuralAnalysis+import OpenCV.ImgProc.Types+import OpenCV.ImgProc.CascadeClassifier+import OpenCV.Photo+import OpenCV.Video+import OpenCV.Video.MotionAnalysis+import OpenCV.VideoIO.VideoCapture++import OpenCV.TypeLevel++import OpenCV.JSON ( )
+ src/OpenCV/Calib3d.cpp view
@@ -0,0 +1,61 @@++#include "opencv2/core.hpp"++#include "opencv2/calib3d.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_Calib3d_0_82151bb63545e3ec9d63bdbbd099566678dac718(Point2d * pts1Ptr_inline_c_0, int32_t cnumPts1_27_inline_c_1, Point2d * pts2Ptr_inline_c_2, int32_t cnumPts2_27_inline_c_3, Mat * fmPtr_inline_c_4, int32_t cmethod_27_inline_c_5, double cp1_27_inline_c_6, double cp2_27_inline_c_7, Mat * pointMaskPtr_inline_c_8) {++  try+  {   +            cv::_InputArray pts1 = cv::_InputArray(pts1Ptr_inline_c_0, cnumPts1_27_inline_c_1);+            cv::_InputArray pts2 = cv::_InputArray(pts2Ptr_inline_c_2, cnumPts2_27_inline_c_3);+            *fmPtr_inline_c_4 =+              cv::findFundamentalMat+              ( pts1+              , pts2+              , cmethod_27_inline_c_5+              , cp1_27_inline_c_6+              , cp2_27_inline_c_7+              , *pointMaskPtr_inline_c_8+              );+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Calib3d_1_6580eb89fe56557059d953009d36dacf9f92ae43(Point2d * pointsPtr_inline_c_0, int32_t cnumPoints_27_inline_c_1, int32_t cwhichImage_27_inline_c_2, Mat * fmPtr_inline_c_3, Mat * epilinesPtr_inline_c_4) {++  try+  {   +          cv::_InputArray points =+            cv::_InputArray( pointsPtr_inline_c_0+                           , cnumPoints_27_inline_c_1+                           );+          cv::computeCorrespondEpilines+          ( points+          , cwhichImage_27_inline_c_2+          , *fmPtr_inline_c_3+          , *epilinesPtr_inline_c_4+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/Calib3d.hs view
@@ -0,0 +1,179 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.Calib3d+    ( FundamentalMatMethod(..)+    , WhichImage(..)+    -- , calibrateCamera+    , findFundamentalMat+    , computeCorrespondEpilines+    ) where++import "base" Data.Int+import "base" Data.Word+import "base" Foreign.C.Types+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Calib3d.Constants+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/calib3d.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------+-- Types++data FundamentalMatMethod+   = FM_7Point+   | FM_8Point+   | FM_Ransac !(Maybe Double) !(Maybe Double)+   | FM_Lmeds  !(Maybe Double)+     deriving (Show, Eq)++marshalFundamentalMatMethod :: FundamentalMatMethod -> (Int32, CDouble, CDouble)+marshalFundamentalMatMethod = \case+    FM_7Point       -> (c'CV_FM_7POINT, 0, 0)+    FM_8Point       -> (c'CV_FM_8POINT, 0, 0)+    FM_Ransac p1 p2 -> (c'CV_FM_RANSAC, maybe 3 realToFrac p1, maybe 0.99 realToFrac p2)+    FM_Lmeds     p2 -> (c'CV_FM_LMEDS, 0, maybe 0.99 realToFrac p2)++data WhichImage = Image1 | Image2 deriving (Show, Eq)++marshalWhichImage :: WhichImage -> Int32+marshalWhichImage = \case+    Image1 -> 1+    Image2 -> 2++--------------------------------------------------------------------------------++-- {- |+-- <http://docs.opencv.org/3.0-last-rst/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#calibratecamera OpenCV Sphinx doc>+-- -}+-- calibrateCamera+--     :: ( ToSize2i imageSize+--        , camMat ~ Mat (ShapeT [3, 3]) ('S 1) ('S Double)+--        )+--      . V.Vector () -- combine objectPoints and imagePoints+--     -> imageSize+--     -> camMat+--     -> flags+--     -> criteria+--     -> (camMat, distCoeffs, rvecs, tvecs)+-- calibrateCamera = _todo++{- | Calculates a fundamental matrix from the corresponding points in two images++The minimum number of points required depends on the 'FundamentalMatMethod'.++ * 'FM_7Point': @N == 7@+ * 'FM_8Point': @N >= 8@+ * 'FM_Ransac': @N >= 15@+ * 'FM_Lmeds': @N >= 8@++With 7 points the 'FM_7Point' method is used, despite the given method.++With more than 7 points the 'FM_7Point' method will be replaced by the+'FM_8Point' method.++Between 7 and 15 points the 'FM_Ransac' method will be replaced by the+'FM_Lmeds' method.++With the 'FM_7Point' method and with 7 points the result can contain up to 3+matrices, resulting in either 3, 6 or 9 rows. This is why the number of+resulting rows in tagged as 'D'ynamic. For all other methods the result always+contains 3 rows.++<http://docs.opencv.org/3.0-last-rst/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#findfundamentalmat OpenCV Sphinx doc>+-}+findFundamentalMat+    :: (IsPoint2 point2 CDouble)+    => V.Vector (point2 CDouble) -- ^ Points from the first image.+    -> V.Vector (point2 CDouble) -- ^ Points from the second image.+    -> FundamentalMatMethod+    -> CvExcept ( Maybe ( Mat ('S '[ 'D, 'S 3 ]) ('S 1) ('S Double)+                        , Mat ('S '[ 'D, 'D   ]) ('S 1) ('S Word8 )+                        )+                )+findFundamentalMat pts1 pts2 method = do+    (fm, pointMask) <- c'findFundamentalMat+    -- If the c++ function can't find a fundamental matrix it will+    -- retrun an empty matrix. We check for this case by trying to+    -- coerce the result to the desired type.+    catchE (Just . (, unsafeCoerceMat pointMask) <$> coerceMat fm)+           (\case CoerceMatError _msgs -> pure Nothing+                  otherError -> throwE otherError+           )+  where+    c'findFundamentalMat = unsafeWrapException $ do+      fm   <- newEmptyMat+      pointMask <- newEmptyMat+      handleCvException (pure (fm, pointMask)) $+        withPtr fm $ \fmPtr ->+        withPtr pointMask $ \pointMaskPtr ->+        withArrayPtr (V.map toPoint pts1) $ \pts1Ptr ->+        withArrayPtr (V.map toPoint pts2) $ \pts2Ptr ->+          [cvExcept|+            cv::_InputArray pts1 = cv::_InputArray($(Point2d * pts1Ptr), $(int32_t c'numPts1));+            cv::_InputArray pts2 = cv::_InputArray($(Point2d * pts2Ptr), $(int32_t c'numPts2));+            *$(Mat * fmPtr) =+              cv::findFundamentalMat+              ( pts1+              , pts2+              , $(int32_t c'method)+              , $(double c'p1)+              , $(double c'p2)+              , *$(Mat * pointMaskPtr)+              );+          |]++    c'numPts1 = fromIntegral $ V.length pts1+    c'numPts2 = fromIntegral $ V.length pts2+    (c'method, c'p1, c'p2) = marshalFundamentalMatMethod method++{- | For points in an image of a stereo pair, computes the corresponding epilines in the other image++<http://docs.opencv.org/3.0-last-rst/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#computecorrespondepilines OpenCV Sphinx doc>+-}+computeCorrespondEpilines+    :: (IsPoint2 point2 CDouble)+    => V.Vector (point2 CDouble) -- ^ Points.+    -> WhichImage -- ^ Image which contains the points.+    -> Mat (ShapeT [3, 3]) ('S 1) ('S Double) -- ^ Fundamental matrix.+    -> CvExcept (Mat ('S ['D, 'S 1]) ('S 3) ('S Double))+computeCorrespondEpilines points whichImage fm = unsafeWrapException $ do+    epilines <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat epilines) $+      withArrayPtr (V.map toPoint points) $ \pointsPtr ->+      withPtr fm       $ \fmPtr       ->+      withPtr epilines $ \epilinesPtr -> do+        -- Destroy type information about the pointsPtr. We wan't to generate+        -- C++ code that works for any type of point. Specifically Point2f and+        -- Point2d.+        [cvExcept|+          cv::_InputArray points =+            cv::_InputArray( $(Point2d * pointsPtr)+                           , $(int32_t c'numPoints)+                           );+          cv::computeCorrespondEpilines+          ( points+          , $(int32_t c'whichImage)+          , *$(Mat * fmPtr)+          , *$(Mat * epilinesPtr)+          );+        |]+  where+    c'numPoints = fromIntegral $ V.length points+    c'whichImage = marshalWhichImage whichImage
+ src/OpenCV/Core/ArrayOps.cpp view
@@ -0,0 +1,441 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_0_452974cb3d241811fc2c9eebbd71284be027cbd2(Mat * dstPtr_inline_c_0, Mat * srcPtr_inline_c_1, Scalar * xPtr_inline_c_2) {++            *dstPtr_inline_c_0 = *srcPtr_inline_c_1 + *xPtr_inline_c_2;+          +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_1_6b9fd3dd5862c8a194878d10a361086ee45501e6(Mat * dstPtr_inline_c_0, Mat * srcPtr_inline_c_1, double cx_27_inline_c_2) {++          *dstPtr_inline_c_0 = *srcPtr_inline_c_1 * cx_27_inline_c_2;+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_2_870402e1ddeaf3da6060607dc50250f3b9880a76(Mat * dstPtr_inline_c_0, Mat * srcPtr_inline_c_1) {++          *dstPtr_inline_c_0 = cv::abs(*srcPtr_inline_c_1);+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_3_53325319d2f26119f0d208466fac5bc7b34d5083(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++          cv::absdiff( *src1Ptr_inline_c_0+                     , *src2Ptr_inline_c_1+                     , *dstPtr_inline_c_2+                     );+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_4_1678b98e2628a48ea264d2a6123aff08ecd9e6f0(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++          cv::add+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          , cv::noArray()+          );+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_5_aa0c246bd1d6319e13424fd1e46e9b875cf24a0c(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++          cv::subtract+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          , cv::noArray()+          );+        +}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_6_47ff83e6532e31e45d281de520b46d3a4bb45d9e(Mat * src1Ptr_inline_c_0, double calpha_27_inline_c_1, Mat * src2Ptr_inline_c_2, double cbeta_27_inline_c_3, double cgamma_27_inline_c_4, Mat * dstPtr_inline_c_5, int32_t cdtype_27_inline_c_6) {++  try+  {   +        cv::addWeighted+          ( *src1Ptr_inline_c_0+          , calpha_27_inline_c_1+          , *src2Ptr_inline_c_2+          , cbeta_27_inline_c_3+          , cgamma_27_inline_c_4+          , *dstPtr_inline_c_5+          , cdtype_27_inline_c_6+          );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_7_267aab8568cb3235e703df09dbd516a54e638ec4(Mat * src1Ptr_inline_c_0, double cscale_27_inline_c_1, Mat * src2Ptr_inline_c_2, Mat * dstPtr_inline_c_3) {++  try+  {   +        cv::scaleAdd+          ( *src1Ptr_inline_c_0+          , cscale_27_inline_c_1+          , *src2Ptr_inline_c_2+          , *dstPtr_inline_c_3+          );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_8_31bccad32ca5c4e2dcad90d97216dd614c127146(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++  try+  {   +          cv::max+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_9_48ba65e091a4952ceeaf5f341d915f8b761aad98(Mat * srcPtr_inline_c_0, double cx_27_inline_c_1, Mat * dstPtr_inline_c_2, int32_t ccmpOp_27_inline_c_3) {++  try+  {   +          cv::compare+          ( *srcPtr_inline_c_0+          , cx_27_inline_c_1+          , *dstPtr_inline_c_2+          , ccmpOp_27_inline_c_3+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_10_1f4ed5f07e2b770709ecd921504e6a135e59e4fb(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1) {++  try+  {   +          cv::bitwise_not+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , cv::noArray()+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_11_dc8ccab3cbbcd17ec78dda97d0571ff60dd45782(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++  try+  {   +          cv::bitwise_and+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          , cv::noArray()+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_12_142520adebed49e1e1ef9bab34ab61eebe8235ae(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++  try+  {   +          cv::bitwise_or+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          , cv::noArray()+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_13_fb71306ade07cba36c0678f252b48d3b2832e50f(Mat * src1Ptr_inline_c_0, Mat * src2Ptr_inline_c_1, Mat * dstPtr_inline_c_2) {++  try+  {   +          cv::bitwise_xor+          ( *src1Ptr_inline_c_0+          , *src2Ptr_inline_c_1+          , *dstPtr_inline_c_2+          , cv::noArray()+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_14_147119876c05df67a629f003ff026fba111e5ac6(Mat * srcVecPtr_inline_c_0, size_t csrcVecLength_27_inline_c_1, Mat * dstPtr_inline_c_2) {++          cv::merge+          ( srcVecPtr_inline_c_0+          , csrcVecLength_27_inline_c_1+          , *dstPtr_inline_c_2+          );+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_15_217852e2dbdfadc92ed83393f4806a183113b805(Mat * srcPtr_inline_c_0, int32_t cnumChans_27_inline_c_1, Mat ** splitsArray_inline_c_2) {++        cv::Mat * srcPtr = srcPtr_inline_c_0;+        int32_t numChans = cnumChans_27_inline_c_1;+        cv::Mat *splits = new cv::Mat[numChans];+        cv::split(*srcPtr, splits);+        for(int i = 0; i < numChans; i++){+          splitsArray_inline_c_2[i] = new cv::Mat(splits[i]);+        }+        delete [] splits;+      +}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_16_e9c348936e1d574774205ac0bd609d25dd9804bc(Mat * srcPtr_inline_c_0, double * minValPtr_inline_c_1, double * maxValPtr_inline_c_2, Point2i * minLocPtr_inline_c_3, Point2i * maxLocPtr_inline_c_4) {++  try+  {   +            cv::minMaxLoc( *srcPtr_inline_c_0+                         , minValPtr_inline_c_1+                         , maxValPtr_inline_c_2+                         , minLocPtr_inline_c_3+                         , maxLocPtr_inline_c_4+                         );+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_17_7efee8680a1dc682471802948ff18b6fcb540c0a(Mat * mskPtr_inline_c_0, double * normPtr_inline_c_1, Mat * srcPtr_inline_c_2, int32_t cnormType_27_inline_c_3) {++  try+  {   +        Mat * mskPtr = mskPtr_inline_c_0;+        *normPtr_inline_c_1 =+          cv::norm( *srcPtr_inline_c_2+                  , cnormType_27_inline_c_3+                  , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                  );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_18_92a97241c6dbd1301c89df518de3170bbb2c2952(Mat * mskPtr_inline_c_0, double * normPtr_inline_c_1, Mat * src1Ptr_inline_c_2, Mat * src2Ptr_inline_c_3, int32_t cnormType_27_inline_c_4) {++  try+  {   +        Mat * mskPtr = mskPtr_inline_c_0;+        *normPtr_inline_c_1 =+          cv::norm( *src1Ptr_inline_c_2+                  , *src2Ptr_inline_c_3+                  , cnormType_27_inline_c_4+                  , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                  );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_19_a54daf4ae50af714d99ad385f88d0a894f1f7102(Mat * mskPtr_inline_c_0, Mat * srcPtr_inline_c_1, Mat * dstPtr_inline_c_2, double calpha_27_inline_c_3, double cbeta_27_inline_c_4, int32_t cnormType_27_inline_c_5, int32_t cdtype_27_inline_c_6) {++  try+  {   +          Mat * mskPtr = mskPtr_inline_c_0;+          cv::normalize( *srcPtr_inline_c_1+                       , *dstPtr_inline_c_2+                       , calpha_27_inline_c_3+                       , cbeta_27_inline_c_4+                       , cnormType_27_inline_c_5+                       , cdtype_27_inline_c_6+                       , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                       );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_20_697bd7b2cba259dcb319d55434ca80fd96f2bd7a(Scalar * sPtr_inline_c_0, Mat * srcPtr_inline_c_1) {++  try+  {   +          *sPtr_inline_c_0 = cv::sum(*srcPtr_inline_c_1);+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_ArrayOps_21_99a8d1550a5f02228e0ed2828fdb06705b9a69b8(Mat * maskPtr_inline_c_0, Mat * srcPtr_inline_c_1, Scalar * meanPtr_inline_c_2, Scalar * stddevPtr_inline_c_3) {++  try+  {   +          cv::Mat * maskPtr = maskPtr_inline_c_0;+          cv::meanStdDev+          ( *srcPtr_inline_c_1+          , *meanPtr_inline_c_2+          , *stddevPtr_inline_c_3+          , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(cv::noArray())+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_22_6d29e95be3bb248e3e9eb67e17905be7eb8bcad9(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t flipCode_inline_c_2) {++          cv::flip(*srcPtr_inline_c_0, *dstPtr_inline_c_1, flipCode_inline_c_2);+        +}++}++extern "C" {+void inline_c_OpenCV_Core_ArrayOps_23_dc3483f267722d4953a9984c842efd5bf72d4e85(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1) {++          cv::transpose(*srcPtr_inline_c_0, *dstPtr_inline_c_1);+        +}++}
+ src/OpenCV/Core/ArrayOps.hs view
@@ -0,0 +1,924 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++{- | Operations on arrays+-}+module OpenCV.Core.ArrayOps+    ( -- * Per element operations+      -- $per_element_intro+      matScalarAdd+    , matScalarMult+    , matAbs+    , matAbsDiff+    , matAdd+    , matSubtract+    , matAddWeighted+    , matScaleAdd+    , matMax+    , CmpType(..)+    , matScalarCompare+      -- ** Bitwise operations+      -- $bitwise_intro+    , bitwiseNot+    , bitwiseAnd+    , bitwiseOr+    , bitwiseXor+      -- * Channel operations+    , matMerge+    , matSplit+    , matChannelMapM+      -- * Other+    , minMaxLoc+    , NormType(..)+    , NormAbsRel(..)+    , norm+    , normDiff+    , normalize+    , matSum+    , matSumM+    , meanStdDev+    , matFlip, FlipDirection(..)+    , matTranspose+    ) where++import "base" Data.Proxy ( Proxy(..) )+import "base" Data.Word+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( allocaArray, peekArray )+import "base" Foreign.Ptr ( Ptr )+import "base" Foreign.Storable ( Storable(..), peek )+import "base" GHC.TypeLits+import "base" Data.Int ( Int32 )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.Vector ( zero )+import "linear" Linear.V2 ( V2(..) )+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.ArrayOps+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.Mutable+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------+-- Per element operations+--------------------------------------------------------------------------------++{- $per_element_intro++The following functions work on the individual elements of matrices.++Examples are based on the following two images:++<<doc/generated/flower_512x341.png Flower>>+<<doc/generated/sailboat_512x341.png Sailboat>>+-}++matScalarAdd+    :: (ToScalar scalar)+    => Mat shape channels depth -- ^+    -> scalar+    -> Mat shape channels depth+matScalarAdd src x = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr (toScalar x) $ \xPtr ->+      withPtr dst $ \dstPtr ->+        withPtr src $ \srcPtr ->+          [C.block| void {+            *$(Mat * dstPtr) = *$(Mat * srcPtr) + *$(Scalar * xPtr);+          }|]+    pure $ unsafeCoerceMat dst++matScalarMult+    :: Mat shape channels depth -- ^+    -> Double+    -> Mat shape channels depth+matScalarMult src x = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src $ \srcPtr ->+        [C.block| void {+          *$(Mat * dstPtr) = *$(Mat * srcPtr) * $(double c'x);+        }|]+    pure $ unsafeCoerceMat dst+  where+    c'x = realToFrac x++{- | Calculates an absolute value of each matrix element.++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#abs OpenCV Sphinx doc>+-}+matAbs+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+matAbs src = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src $ \srcPtr ->+        [C.block| void {+          *$(Mat * dstPtr) = cv::abs(*$(Mat * srcPtr));+        }|]+    pure $ unsafeCoerceMat dst++{- | Calculates the per-element absolute difference between two arrays.++Example:++@+matAbsDiffImg :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+matAbsDiffImg = matAbsDiff flower_512x341 sailboat_512x341+@++<<doc/generated/examples/matAbsDiffImg.png matAbsDiffImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#absdiff OpenCV Sphinx doc>+-}+matAbsDiff+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> Mat shape channels depth+matAbsDiff src1 src2 = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+        [C.block| void {+          cv::absdiff( *$(Mat * src1Ptr)+                     , *$(Mat * src2Ptr)+                     , *$(Mat * dstPtr )+                     );+        }|]+    pure $ unsafeCoerceMat dst++{- | Calculates the per-element sum of two arrays.++Example:++@+matAddImg :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+matAddImg = matAdd flower_512x341 sailboat_512x341+@++<<doc/generated/examples/matAddImg.png matAddImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#add OpenCV Sphinx doc>+-}+-- TODO (RvD): handle different depths+matAdd+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> Mat shape channels depth+matAdd src1 src2 = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+        [C.block| void {+          cv::add+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        }|]+    pure $ unsafeCoerceMat dst++{- | Calculates the per-element difference between two arrays++Example:++@+matSubtractImg :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+matSubtractImg = matSubtract flower_512x341 sailboat_512x341+@++<<doc/generated/examples/matSubtractImg.png matSubtractImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#subtract OpenCV Sphinx doc>+-}+-- TODO (RvD): handle different depths+matSubtract+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> Mat shape channels depth+matSubtract src1 src2 = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+        [C.block| void {+          cv::subtract+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        }|]+    pure $ unsafeCoerceMat dst++{- | Calculates the weighted sum of two arrays++Example:++@+matAddWeightedImg :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+matAddWeightedImg = exceptError $+    matAddWeighted flower_512x341 0.5 sailboat_512x341 0.5 0.0+@++<<doc/generated/examples/matAddWeightedImg.png matAddWeightedImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#addweighted OpenCV Sphinx doc>+-}++-- TODO (RvD): handle different depths+matAddWeighted+    :: forall shape channels srcDepth dstDepth+     . (ToDepthDS (Proxy dstDepth))+    => Mat shape channels srcDepth -- ^ src1+    -> Double -- ^ alpha+    -> Mat shape channels srcDepth -- ^ src2+    -> Double -- ^ beta+    -> Double -- ^ gamma+    -> CvExcept (Mat shape channels dstDepth)+matAddWeighted src1 alpha src2 beta gamma = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+      withPtr dst $ \dstPtr ->+      [cvExcept|+        cv::addWeighted+          ( *$(Mat * src1Ptr)+          , $(double c'alpha)+          , *$(Mat * src2Ptr)+          , $(double c'beta)+          , $(double c'gamma)+          , *$(Mat * dstPtr)+          , $(int32_t c'dtype)+          );+      |]+  where+    c'alpha = realToFrac alpha+    c'beta  = realToFrac beta+    c'gamma = realToFrac gamma+    c'dtype = maybe (-1) marshalDepth $ dsToMaybe $ toDepthDS (Proxy :: Proxy dstDepth)++{- | Calculates the sum of a scaled array and another array.++The function scaleAdd is one of the classical primitive linear algebra+operations, known as DAXPY or SAXPY in BLAS. It calculates the sum of a scaled+array and another array.++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#scaleadd OpenCV Sphinx doc>+-}+matScaleAdd+    :: Mat shape channels depth+       -- ^ First input array.+    -> Double+       -- ^ Scale factor for the first array.+    -> Mat shape channels depth+       -- ^ Second input array.+    -> CvExcept (Mat shape channels depth)+matScaleAdd src1 scale src2 = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+      withPtr dst  $ \dstPtr  ->+      [cvExcept|+        cv::scaleAdd+          ( *$(Mat * src1Ptr)+          , $(double c'scale)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          );+      |]+  where+    c'scale = realToFrac scale++matMax+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> CvExcept (Mat shape channels depth)+matMax src1 src2 = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr dst $ \dstPtr ->+      withPtr src1 $ \src1Ptr ->+      withPtr src2 $ \src2Ptr ->+        [cvExcept|+          cv::max+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          );+        |]++matScalarCompare+    :: Mat shape channels depth -- ^+    -> Double+    -> CmpType+    -> CvExcept (Mat shape channels depth)+matScalarCompare src x cmpType = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr dst $ \dstPtr ->+      withPtr src $ \srcPtr ->+        [cvExcept|+          cv::compare+          ( *$(Mat * srcPtr)+          , $(double c'x)+          , *$(Mat * dstPtr)+          , $(int32_t c'cmpOp)+          );+        |]+  where+    c'x = realToFrac x+    c'cmpOp = marshalCmpType cmpType++--------------------------------------------------------------------------------+-- Per element bitwise operations+--------------------------------------------------------------------------------++{- $bitwise_intro++The examples for the bitwise operations make use of the following images:++Example:++@+type VennShape = [200, 320]++vennCircleAImg :: Mat (ShapeT VennShape) ('S 1) ('S Word8)+vennCircleAImg = exceptError $+    withMatM+      (Proxy :: Proxy VennShape)+      (Proxy :: Proxy 1)+      (Proxy :: Proxy Word8)+      black $ \\imgM -> lift $ vennCircleA imgM white (-1)++vennCircleBImg :: Mat (ShapeT VennShape) ('S 1) ('S Word8)+vennCircleBImg = exceptError $+    withMatM+      (Proxy :: Proxy VennShape)+      (Proxy :: Proxy 1)+      (Proxy :: Proxy Word8)+      black $ \\imgM -> lift $ vennCircleB imgM white (-1)+@++<<doc/generated/examples/vennCircleAImg.png vennCircleAImg>>+<<doc/generated/examples/vennCircleBImg.png vennCircleBImg>>+-}++{- |++Example:++@+bitwiseNotImg :: Mat (ShapeT VennShape) ('S 3) ('S Word8)+bitwiseNotImg = exceptError $ do+    img <- bitwiseNot vennCircleAImg+    imgBgr <- cvtColor gray bgr img+    createMat $ do+      imgM <- lift $ thaw imgBgr+      lift $ vennCircleA imgM blue 2+      pure imgM+@++<<doc/generated/examples/bitwiseNotImg.png bitwiseNotImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#bitwise-not OpenCV Sphinx doc>+-}+bitwiseNot+    :: Mat shape channels depth -- ^+    -> CvExcept (Mat shape channels depth)+bitwiseNot src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr ->+      withPtr dst    $ \dstPtr ->+        [cvExcept|+          cv::bitwise_not+          ( *$(Mat * srcPtr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        |]++{- |++Example:++@+bitwiseAndImg :: Mat (ShapeT VennShape) ('S 3) ('S Word8)+bitwiseAndImg = exceptError $ do+    img <- bitwiseAnd vennCircleAImg vennCircleBImg+    imgBgr <- cvtColor gray bgr img+    createMat $ do+      imgM <- lift $ thaw imgBgr+      lift $ vennCircleA imgM blue 2+      lift $ vennCircleB imgM red  2+      pure imgM+@++<<doc/generated/examples/bitwiseAndImg.png bitwiseAndImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#bitwise-and OpenCV Sphinx doc>+-}+bitwiseAnd+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> CvExcept (Mat shape channels depth)+bitwiseAnd src1 src2 = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src1   $ \src1Ptr ->+      withPtr src2   $ \src2Ptr ->+      withPtr dst    $ \dstPtr  ->+        [cvExcept|+          cv::bitwise_and+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        |]++{- |++Example:++@+bitwiseOrImg :: Mat (ShapeT VennShape) ('S 3) ('S Word8)+bitwiseOrImg = exceptError $ do+    img <- bitwiseOr vennCircleAImg vennCircleBImg+    imgBgr <- cvtColor gray bgr img+    createMat $ do+      imgM <- lift $ thaw imgBgr+      lift $ vennCircleA imgM blue 2+      lift $ vennCircleB imgM red  2+      pure imgM+@++<<doc/generated/examples/bitwiseOrImg.png bitwiseOrImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#bitwise-or OpenCV Sphinx doc>+-}+bitwiseOr+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> CvExcept (Mat shape channels depth)+bitwiseOr src1 src2 = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src1   $ \src1Ptr ->+      withPtr src2   $ \src2Ptr ->+      withPtr dst    $ \dstPtr  ->+        [cvExcept|+          cv::bitwise_or+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        |]++{- |++Example:++@+bitwiseXorImg :: Mat (ShapeT VennShape) ('S 3) ('S Word8)+bitwiseXorImg = exceptError $ do+    img <- bitwiseXor vennCircleAImg vennCircleBImg+    imgBgr <- cvtColor gray bgr img+    createMat $ do+      imgM <- lift $ thaw imgBgr+      lift $ vennCircleA imgM blue 2+      lift $ vennCircleB imgM red  2+      pure imgM+@++<<doc/generated/examples/bitwiseXorImg.png bitwiseXorImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#bitwise-xor OpenCV Sphinx doc>+-}+bitwiseXor+    :: Mat shape channels depth -- ^+    -> Mat shape channels depth+    -> CvExcept (Mat shape channels depth)+bitwiseXor src1 src2 = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src1   $ \src1Ptr ->+      withPtr src2   $ \src2Ptr ->+      withPtr dst    $ \dstPtr  ->+        [cvExcept|+          cv::bitwise_xor+          ( *$(Mat * src1Ptr)+          , *$(Mat * src2Ptr)+          , *$(Mat * dstPtr)+          , cv::noArray()+          );+        |]++{- | Creates one multichannel array out of several single-channel ones.++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#merge OpenCV Sphinx doc>+-}+matMerge+    :: V.Vector (Mat shape ('S 1) depth) -- ^+    -> Mat shape 'D depth+matMerge srcVec = unsafePerformIO $ do+    dst <- newEmptyMat+    withArrayPtr srcVec $ \srcVecPtr ->+      withPtr dst $ \dstPtr ->+        [C.block| void {+          cv::merge+          ( $(Mat * srcVecPtr)+          , $(size_t c'srcVecLength)+          , *$(Mat * dstPtr)+          );+        }|]+    pure $ unsafeCoerceMat dst+  where+    c'srcVecLength = fromIntegral $ V.length srcVec++{- | Divides a multi-channel array into several single-channel arrays.++Example:++@+matSplitImg+    :: forall (width    :: Nat)+              (width3   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Birds_512x341+       , width3 ~ ((*) width 3)+       )+    => Mat (ShapeT [height, width3]) ('S channels) ('S depth)+matSplitImg = exceptError $ do+    zeroImg <- mkMat (Proxy :: Proxy [height, width])+                     (Proxy :: Proxy 1)+                     (Proxy :: Proxy depth)+                     black+    let blueImg  = matMerge $ V.fromList [channelImgs V.! 0, zeroImg, zeroImg]+        greenImg = matMerge $ V.fromList [zeroImg, channelImgs V.! 1, zeroImg]+        redImg   = matMerge $ V.fromList [zeroImg, zeroImg, channelImgs V.! 2]++    withMatM (Proxy :: Proxy [height, width3])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      matCopyToM imgM (V2 (w*0) 0) (unsafeCoerceMat blueImg)  Nothing+      matCopyToM imgM (V2 (w*1) 0) (unsafeCoerceMat greenImg) Nothing+      matCopyToM imgM (V2 (w*2) 0) (unsafeCoerceMat redImg)   Nothing+  where+    channelImgs = matSplit birds_512x341++    w :: Int32+    w = fromInteger $ natVal (Proxy :: Proxy width)+@++<<doc/generated/examples/matSplitImg.png matSplitImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#split OpenCV Sphinx doc>+-}+matSplit+    :: Mat shape channels depth -- ^+    -> V.Vector (Mat shape ('S 1) depth)+matSplit src = unsafePerformIO $+    withPtr src $ \srcPtr ->+    allocaArray numChans $ \(splitsArray :: Ptr (Ptr C'Mat)) -> do+      [C.block| void {+        cv::Mat * srcPtr = $(Mat * srcPtr);+        int32_t numChans = $(int32_t c'numChans);+        cv::Mat *splits = new cv::Mat[numChans];+        cv::split(*srcPtr, splits);+        for(int i = 0; i < numChans; i++){+          $(Mat * * splitsArray)[i] = new cv::Mat(splits[i]);+        }+        delete [] splits;+      }|]+      fmap V.fromList . mapM (fromPtr . pure) =<< peekArray numChans splitsArray+  where+    numChans = fromIntegral $ miChannels $ matInfo src++    c'numChans :: Int32+    c'numChans = fromIntegral numChans++{- | Apply the same 1 dimensional action to every channel+-}+matChannelMapM+   :: Monad m+   => (Mat shape ('S 1) depth -> m (Mat shape ('S 1) depth))+   -> Mat shape channelsOut depth+   -> m (Mat shape channelsOut depth)+matChannelMapM f img = unsafeCoerceMat . matMerge <$> V.mapM f (matSplit img)++{- | Finds the global minimum and maximum in an array++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#minmaxloc OpenCV Sphinx doc>+-}+-- TODO (RvD): implement mask+minMaxLoc+    :: Mat ('S [height, width]) channels depth -- ^+    -> CvExcept (Double, Double, Point2i, Point2i)+minMaxLoc src = unsafeWrapException $ do+    minLoc <- toPointIO $ V2 0 0+    maxLoc <- toPointIO $ V2 0 0+    withPtr src $ \srcPtr ->+      withPtr minLoc $ \minLocPtr ->+      withPtr maxLoc $ \maxLocPtr ->+      alloca $ \minValPtr ->+      alloca $ \maxValPtr -> do+        handleCvException+          ( (,, minLoc, maxLoc)+            <$> (realToFrac <$> peek minValPtr)+            <*> (realToFrac <$> peek maxValPtr)+          )+          [cvExcept|+            cv::minMaxLoc( *$(Mat * srcPtr)+                         , $(double * minValPtr)+                         , $(double * maxValPtr)+                         , $(Point2i * minLocPtr)+                         , $(Point2i * maxLocPtr)+                         );+          |]++{- | Calculates an absolute array norm++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#norm OpenCV Sphinx doc>+-}+norm+    :: NormType+    -> Maybe (Mat shape ('S 1) ('S Word8))+       -- ^ Optional operation mask; it must have the same size as the input+       -- array, depth 'Depth_8U' and 1 channel.+    -> Mat shape channels depth -- ^ Input array.+    -> CvExcept Double  -- ^ Calculated norm.+norm normType mbMask src = unsafeWrapException $+    withPtr src    $ \srcPtr  ->+    withPtr mbMask $ \mskPtr  ->+    alloca         $ \normPtr ->+    handleCvException (realToFrac <$> peek normPtr) $+      [cvExcept|+        Mat * mskPtr = $(Mat * mskPtr);+        *$(double * normPtr) =+          cv::norm( *$(Mat * srcPtr)+                  , $(int32_t c'normType)+                  , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                  );+      |]+  where+    c'normType = marshalNormType NormAbsolute normType++{- | Calculates an absolute difference norm, or a relative difference norm++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#norm OpenCV Sphinx doc>+-}+normDiff+    :: NormAbsRel -- ^ Absolute or relative norm.+    -> NormType+    -> Maybe (Mat shape ('S 1) ('S Word8))+       -- ^ Optional operation mask; it must have the same size as the input+       -- array, depth 'Depth_8U' and 1 channel.+    -> Mat shape channels depth -- ^ First input array.+    -> Mat shape channels depth -- ^ Second input array of the same size and type as the first.+    -> CvExcept Double -- ^ Calculated norm.+normDiff absRel normType mbMask src1 src2 = unsafeWrapException $+    withPtr src1   $ \src1Ptr ->+    withPtr src2   $ \src2Ptr ->+    withPtr mbMask $ \mskPtr  ->+    alloca         $ \normPtr ->+    handleCvException (realToFrac <$> peek normPtr) $+      [cvExcept|+        Mat * mskPtr = $(Mat * mskPtr);+        *$(double * normPtr) =+          cv::norm( *$(Mat * src1Ptr)+                  , *$(Mat * src2Ptr)+                  , $(int32_t c'normType)+                  , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                  );+      |]+  where+    c'normType = marshalNormType absRel normType++{- | Normalizes the norm or value range of an array++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#normalize OpenCV Sphinx doc>+-}+normalize+    :: forall shape channels srcDepth dstDepth+     . (ToDepthDS (Proxy dstDepth))+    => Double+       -- ^ Norm value to normalize to or the lower range boundary in case of+       -- the range normalization.+    -> Double+       -- ^ Upper range boundary in case of the range normalization; it is not+       -- used for the norm normalization.+    -> NormType+    -> Maybe (Mat shape ('S 1) ('S Word8)) -- ^ Optional operation mask.+    -> Mat shape channels srcDepth -- ^ Input array.+    -> CvExcept (Mat shape channels dstDepth)+normalize alpha beta normType mbMask src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr ->+      withPtr dst    $ \dstPtr ->+      withPtr mbMask $ \mskPtr ->+        [cvExcept|+          Mat * mskPtr = $(Mat * mskPtr);+          cv::normalize( *$(Mat * srcPtr)+                       , *$(Mat * dstPtr)+                       , $(double c'alpha)+                       , $(double c'beta)+                       , $(int32_t c'normType)+                       , $(int32_t c'dtype)+                       , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+                       );+        |]+  where+    c'alpha    = realToFrac alpha+    c'beta     = realToFrac beta+    c'normType = marshalNormType NormAbsolute normType+    c'dtype    = maybe (-1) marshalDepth $ dsToMaybe $ toDepthDS (Proxy :: Proxy dstDepth)++{- | Calculates the sum of array elements++Example:++@+matSumImg :: Mat (ShapeT [201, 201]) ('S 3) ('S Word8)+matSumImg = exceptError $+    withMatM+      (Proxy :: Proxy [201, 201])+      (Proxy :: Proxy 3)+      (Proxy :: Proxy Word8)+      black $ \\imgM -> do+        -- Draw a filled circle. Each pixel has a value of (255,255,255)+        lift $ circle imgM (pure radius :: V2 Int32) radius white (-1) LineType_8 0+        -- Calculate the sum of all pixels.+        scalar <- matSumM imgM+        let V4 area _y _z _w = fromScalar scalar :: V4 Double+        -- Circle area = pi * radius * radius+        let approxPi = area \/ 255 \/ (radius * radius)+        lift $ putText imgM+                       (T.pack $ show approxPi)+                       (V2 40 110 :: V2 Int32)+                       (Font FontHersheyDuplex NotSlanted 1)+                       blue+                       1+                       LineType_AA+                       False+  where+    radius :: forall a. Num a => a+    radius = 100+@++<<doc/generated/examples/matSumImg.png matSumImg>>++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#sum OpenCV Sphinx doc>+-}+matSum+    :: Mat shape channels depth+       -- ^ Input array that must have from 1 to 4 channels.+    -> CvExcept Scalar+matSum src = runCvExceptST $ matSumM =<< unsafeThaw src++matSumM+    :: (PrimMonad m)+    => Mut (Mat shape channels depth) (PrimState m)+       -- ^ Input array that must have from 1 to 4 channels.+    -> CvExceptT m Scalar+matSumM srcM = ExceptT $ unsafePrimToPrim $ do+    s <- newScalar zero+    handleCvException (pure s) $+      withPtr srcM $ \srcPtr ->+      withPtr s    $ \sPtr   ->+        [cvExcept|+          *$(Scalar * sPtr) = cv::sum(*$(Mat * srcPtr));+        |]++{- | Calculates a mean and standard deviation of array elements++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/operations_on_arrays.html#meanstddev OpenCV Sphinx doc>+-}+meanStdDev+    :: (1 <= channels, channels <= 4)+    => Mat shape ('S channels) depth+    -> Maybe (Mat shape ('S 1) ('S Word8))+       -- ^ Optional operation mask.+    -> CvExcept (Scalar, Scalar)+meanStdDev src mask = unsafeWrapException $ do+    mean   <- newScalar $ pure 0+    stddev <- newScalar $ pure 0+    handleCvException (pure (mean, stddev)) $+      withPtr src    $ \srcPtr    ->+      withPtr mask   $ \maskPtr   ->+      withPtr mean   $ \meanPtr   ->+      withPtr stddev $ \stddevPtr ->+        [cvExcept|+          cv::Mat * maskPtr = $(Mat * maskPtr);+          cv::meanStdDev+          ( *$(Mat * srcPtr)+          , *$(Scalar * meanPtr)+          , *$(Scalar * stddevPtr)+          , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(cv::noArray())+          );+        |]++{- | Flips a 2D matrix around vertical, horizontal, or both axes.++The example scenarios of using the function are the following: Vertical flipping+of the image ('FlipVertically') to switch between top-left and bottom-left image+origin. This is a typical operation in video processing on Microsoft Windows*+OS. Horizontal flipping of the image with the subsequent horizontal shift and+absolute difference calculation to check for a vertical-axis symmetry+('FlipHorizontally'). Simultaneous horizontal and vertical flipping of the image+with the subsequent shift and absolute difference calculation to check for a+central symmetry ('FlipBoth'). Reversing the order of point arrays+('FlipHorizontally' or 'FlipVertically').++Example:++@+matFlipImg :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+matFlipImg = matFlip sailboat_512x341 FlipBoth+@++<<doc/generated/examples/matFlipImg.png matFlipImg>>+-}+matFlip+    :: Mat ('S '[height, width]) channels depth+    -> FlipDirection -- ^ How to flip.+    -> Mat ('S '[height, width]) channels depth+matFlip src flipDir = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src $ \srcPtr ->+        [C.block| void {+          cv::flip(*$(Mat * srcPtr), *$(Mat * dstPtr), $(int32_t flipCode));+        }|]+    pure $ unsafeCoerceMat dst+  where+    flipCode :: Int32+    flipCode = marshallFlipDirection flipDir++data FlipDirection = FlipVertically   -- ^ Flip around the x-axis.+                   | FlipHorizontally -- ^ Flip around the y-axis.+                   | FlipBoth         -- ^ Flip around both x and y-axis.+                     deriving (Show, Eq)++marshallFlipDirection :: FlipDirection -> Int32+marshallFlipDirection = \case+    FlipVertically   ->  0+    FlipHorizontally ->  1+    FlipBoth         -> -1++{- | Transposes a matrix.++Example:++@+matTransposeImg :: Mat (ShapeT [512, 341]) ('S 3) ('S Word8)+matTransposeImg = matTranspose sailboat_512x341+@++<<doc/generated/examples/matTransposeImg.png matTransposeImg>>+-}+matTranspose+    :: Mat ('S '[height, width]) channels depth -- ^+    -> Mat ('S '[width, height]) channels depth+matTranspose src = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr dst $ \dstPtr ->+      withPtr src $ \srcPtr ->+        [C.block| void {+          cv::transpose(*$(Mat * srcPtr), *$(Mat * dstPtr));+        }|]+    pure $ unsafeCoerceMat dst
+ src/OpenCV/Core/Types.cpp view
@@ -0,0 +1,147 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+Point2f * inline_c_OpenCV_Core_Types_0_e5b42cc0974a53721799faffb0b442af4bbe4a81(RotatedRect * rotRectPtr_inline_c_0) {+return ( new Point2f(rotRectPtr_inline_c_0->center) );+}++}++extern "C" {+Size2f * inline_c_OpenCV_Core_Types_1_fb6b3d7a5fc2db9553bcae3227927a44ffddd9a8(RotatedRect * rotRectPtr_inline_c_0) {+return ( new Size2f(rotRectPtr_inline_c_0->size) );+}++}++extern "C" {+float inline_c_OpenCV_Core_Types_2_891e2a28d3f3f2e839bd031b2f480ca167e9e6cd(RotatedRect * rotRectPtr_inline_c_0) {+return ( rotRectPtr_inline_c_0->angle );+}++}++extern "C" {+Rect2i * inline_c_OpenCV_Core_Types_3_2ead237e4d4def0d0ca44ca5ad0c3328e032c167(RotatedRect * rotRectPtr_inline_c_0) {+return ( new Rect2i(rotRectPtr_inline_c_0->boundingRect()) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_4_5d0207dad9e659b71d3d8607dde889c79092626f(RotatedRect * rotRectPtr_inline_c_0, Point2f * p1Ptr_inline_c_1, Point2f * p2Ptr_inline_c_2, Point2f * p3Ptr_inline_c_3, Point2f * p4Ptr_inline_c_4) {++          Point2f vertices[4];+          rotRectPtr_inline_c_0->points(vertices);+          *p1Ptr_inline_c_1 = vertices[0];+          *p2Ptr_inline_c_2 = vertices[1];+          *p3Ptr_inline_c_3 = vertices[2];+          *p4Ptr_inline_c_4 = vertices[3];+        +}++}++extern "C" {+void inline_c_OpenCV_Core_Types_5_45080693b2e4cf60c491e408d010cdba0bea094e(KeyPoint * dst_inline_c_0, KeyPoint * src_inline_c_1) {+ new(dst_inline_c_0) cv::KeyPoint(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_6_e5ee841a2c46c5b14208d74daf99dacb2116cf35(KeyPoint * ptr_inline_c_0) {+ ptr_inline_c_0->~KeyPoint() ;+}++}++extern "C" {+KeyPoint * inline_c_OpenCV_Core_Types_7_15a2fd2dc48409980f89973a3754a199f53777a4(float cx_27_inline_c_0, float cy_27_inline_c_1, float ckptSize_27_inline_c_2, float ckptAngle_27_inline_c_3, float ckptResponse_27_inline_c_4, int32_t kptOctave_inline_c_5, int32_t kptClassId_inline_c_6) {+return (+      new cv::KeyPoint+          ( cv::Point2f(cx_27_inline_c_0, cy_27_inline_c_1)+          , ckptSize_27_inline_c_2+          , ckptAngle_27_inline_c_3+          , ckptResponse_27_inline_c_4+          , kptOctave_inline_c_5+          , kptClassId_inline_c_6+          )+    );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_8_06dd8b8ef918074e4901eaf5565602eb16add198(KeyPoint * kptPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2, float * sizePtr_inline_c_3, float * anglePtr_inline_c_4, float * responsePtr_inline_c_5, int32_t * octavePtr_inline_c_6, int32_t * classIdPtr_inline_c_7) {++        KeyPoint * kpt = kptPtr_inline_c_0;+        *xPtr_inline_c_1 = kpt->pt.x    ;+        *yPtr_inline_c_2 = kpt->pt.y    ;+        *sizePtr_inline_c_3 = kpt->size    ;+        *anglePtr_inline_c_4 = kpt->angle   ;+        *responsePtr_inline_c_5 = kpt->response;+        *octavePtr_inline_c_6 = kpt->octave  ;+        *classIdPtr_inline_c_7 = kpt->class_id;+      +}++}++extern "C" {+void inline_c_OpenCV_Core_Types_9_f9fc50076fb8ce439d325154369233a66494792a(KeyPoint * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_10_d10678090e9d04ea683ea9dea1b3596910e05ead(DMatch * dst_inline_c_0, DMatch * src_inline_c_1) {+ new(dst_inline_c_0) cv::DMatch(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_11_3a9482d88464980c5462e7f2dc4451f1d502bcfc(DMatch * ptr_inline_c_0) {+ ptr_inline_c_0->~DMatch() ;+}++}++extern "C" {+DMatch * inline_c_OpenCV_Core_Types_12_925bd2b3768db79d4aa15d94dd905f3c2e4c5e55(int32_t dmatchQueryIdx_inline_c_0, int32_t dmatchTrainIdx_inline_c_1, int32_t dmatchImgIdx_inline_c_2, float cdistance_27_inline_c_3) {+return (+      new cv::DMatch+          ( dmatchQueryIdx_inline_c_0+          , dmatchTrainIdx_inline_c_1+          , dmatchImgIdx_inline_c_2+          , cdistance_27_inline_c_3+          )+    );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_13_7d9d6365e269b4b622abd551b0ff585b27ac418c(DMatch * dmatchPtr_inline_c_0, int32_t * queryIdxPtr_inline_c_1, int32_t * trainIdxPtr_inline_c_2, int32_t * imgIdxPtr_inline_c_3, float * distancePtr_inline_c_4) {++        DMatch * dmatch = dmatchPtr_inline_c_0;+        *queryIdxPtr_inline_c_1 = dmatch->queryIdx;+        *trainIdxPtr_inline_c_2 = dmatch->trainIdx;+        *imgIdxPtr_inline_c_3 = dmatch->imgIdx  ;+        *distancePtr_inline_c_4 = dmatch->distance;+      +}++}++extern "C" {+void inline_c_OpenCV_Core_Types_14_d42014346527f57acc835683dd35ac0b571325f4(DMatch * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/Core/Types.hsc view
@@ -0,0 +1,364 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE RecordWildCards #-}++{-# OPTIONS_GHC -fno-warn-orphans #-} -- For Show instances++module OpenCV.Core.Types+    ( -- * Mutable values+      Mut+    , Mutable+    , FreezeThaw(..)+      -- * Point+    , module OpenCV.Core.Types.Point+      -- * Size+    , module OpenCV.Core.Types.Size+      -- * Scalar+    , Scalar+    , ToScalar(..), FromScalar(..)+      -- * Rect+    , module OpenCV.Core.Types.Rect+      -- * RotatedRect+    , RotatedRect+    , mkRotatedRect+    , rotatedRectCenter+    , rotatedRectSize+    , rotatedRectAngle+    , rotatedRectBoundingRect+    , rotatedRectPoints+      -- * TermCriteria+    , TermCriteria+    , mkTermCriteria+      -- * Range+    , Range+    , mkRange+    , wholeRange+      -- * KeyPoint+    , KeyPoint+    , KeyPointRec(..)+    , mkKeyPoint+    , keyPointAsRec+      -- * DMatch+    , DMatch+    , DMatchRec(..)+    , mkDMatch+    , dmatchAsRec+      -- * Matrix+    , module OpenCV.Core.Types.Mat+    , module OpenCV.Core.Types.Matx+      -- * Vec+    , module OpenCV.Core.Types.Vec+      -- * Exception+    , module OpenCV.Exception+     -- * Algorithm+    , Algorithm(..)+      -- * Polymorphic stuff+    , WithPtr+    , FromPtr+    , CSizeOf+    , PlacementNew+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.Vector ( zero )+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState )+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Core.Types.Matx+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Core.Types.Rect+import "this" OpenCV.Core.Types.Size+import "this" OpenCV.Core.Types.Vec+import "this" OpenCV.Exception+import "this" OpenCV.Internal+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.PlacementNew+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Constants+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Mutable++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------+--  RotatedRect+--------------------------------------------------------------------------------++mkRotatedRect+    :: ( IsPoint2 point2 CFloat+       , IsSize   size   CFloat+       )+    => point2 CFloat -- ^ Rectangle mass center+    -> size   CFloat -- ^ Width and height of the rectangle+    -> Float+       -- ^ The rotation angle (in degrees). When the angle is 0, 90,+       -- 180, 270 etc., the rectangle becomes an up-right rectangle.+    -> RotatedRect+mkRotatedRect center size angle =+    unsafePerformIO $ newRotatedRect center size (realToFrac angle)++-- | Rectangle mass center+rotatedRectCenter :: RotatedRect -> Point2f+rotatedRectCenter rotRect = unsafePerformIO $ fromPtr $+      withPtr rotRect $ \rotRectPtr ->+        [CU.exp| Point2f * { new Point2f($(RotatedRect * rotRectPtr)->center) }|]++-- | Width and height of the rectangle+rotatedRectSize :: RotatedRect -> Size2f+rotatedRectSize rotRect = unsafePerformIO $ fromPtr $+      withPtr rotRect $ \rotRectPtr ->+        [CU.exp| Size2f * { new Size2f($(RotatedRect * rotRectPtr)->size) }|]++-- | The rotation angle (in degrees)+--+-- When the angle is 0, 90, 180, 270 etc., the rectangle becomes an+-- up-right rectangle.+rotatedRectAngle :: RotatedRect -> Float+rotatedRectAngle rotRect = realToFrac $ unsafePerformIO $+    withPtr rotRect $ \rotRectPtr ->+      [CU.exp| float { $(RotatedRect * rotRectPtr)->angle }|]++-- | The minimal up-right rectangle containing the rotated rectangle+rotatedRectBoundingRect :: RotatedRect -> Rect2i+rotatedRectBoundingRect rotRect =+    unsafePerformIO $ fromPtr $ withPtr rotRect $ \rotRectPtr ->+      [CU.exp| Rect2i * { new Rect2i($(RotatedRect * rotRectPtr)->boundingRect()) }|]++rotatedRectPoints :: RotatedRect -> (Point2f, Point2f, Point2f, Point2f)+rotatedRectPoints rotRect = unsafePerformIO $ do+    p1 <- toPointIO (zero :: V2 CFloat)+    p2 <- toPointIO (zero :: V2 CFloat)+    p3 <- toPointIO (zero :: V2 CFloat)+    p4 <- toPointIO (zero :: V2 CFloat)+    withPtr rotRect $ \rotRectPtr ->+      withPtr p1 $ \p1Ptr ->+      withPtr p2 $ \p2Ptr ->+      withPtr p3 $ \p3Ptr ->+      withPtr p4 $ \p4Ptr ->+        [C.block| void {+          Point2f vertices[4];+          $(RotatedRect * rotRectPtr)->points(vertices);+          *$(Point2f * p1Ptr) = vertices[0];+          *$(Point2f * p2Ptr) = vertices[1];+          *$(Point2f * p3Ptr) = vertices[2];+          *$(Point2f * p4Ptr) = vertices[3];+        }|]+    pure (p1, p2, p3, p4)+++--------------------------------------------------------------------------------+--  TermCriteria+--------------------------------------------------------------------------------++mkTermCriteria+    :: Maybe Int    -- ^ Optionally the maximum number of iterations/elements.+    -> Maybe Double -- ^ Optionally the desired accuracy.+    -> TermCriteria+mkTermCriteria mbMaxCount mbEpsilon =+    unsafePerformIO $ newTermCriteria mbMaxCount mbEpsilon+++--------------------------------------------------------------------------------+-- Range+--------------------------------------------------------------------------------++mkRange :: Int32 -> Int32 -> Range+mkRange start end = unsafePerformIO $ newRange start end++wholeRange :: Range+wholeRange = unsafePerformIO newWholeRange+++--------------------------------------------------------------------------------+-- KeyPoint+--------------------------------------------------------------------------------++{- | Data structure for salient point detectors++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#keypoint OpenCV Sphinx doc>+-}+newtype KeyPoint = KeyPoint {unKeyPoint :: ForeignPtr C'KeyPoint}++type instance C KeyPoint = C'KeyPoint++mkPlacementNewInstance ''KeyPoint++instance WithPtr KeyPoint where+    withPtr = withForeignPtr . unKeyPoint++instance FromPtr KeyPoint where+    fromPtr = objFromPtr KeyPoint $ \ptr ->+                [CU.exp| void { delete $(KeyPoint * ptr) }|]++instance CSizeOf C'KeyPoint where+    cSizeOf _proxy = c'sizeof_KeyPoint++data KeyPointRec+   = KeyPointRec+     { kptPoint :: !(V2 Float)+       -- ^ Coordinates of the keypoints.+     , kptSize :: !Float+       -- ^ Diameter of the meaningful keypoint neighborhood.+     , kptAngle :: !Float+       -- ^ Computed orientation of the keypoint (-1 if not applicable); it's in+       -- [0,360) degrees and measured relative to image coordinate system, ie+       -- in clockwise.+     , kptResponse :: !Float+       -- ^ The response by which the most strong keypoints have been+       -- selected. Can be used for the further sorting or subsampling.+     , kptOctave :: !Int32+       -- ^ Octave (pyramid layer) from which the keypoint has been extracted.+     , kptClassId :: !Int32+       -- ^ Object class (if the keypoints need to be clustered by an object+       -- they belong to).+     } deriving (Eq, Show)++newKeyPoint :: KeyPointRec -> IO KeyPoint+newKeyPoint KeyPointRec{..} = fromPtr $+    [CU.exp|KeyPoint * {+      new cv::KeyPoint+          ( cv::Point2f($(float c'x), $(float c'y))+          , $(float c'kptSize)+          , $(float c'kptAngle)+          , $(float c'kptResponse)+          , $(int32_t kptOctave)+          , $(int32_t kptClassId)+          )+    }|]+  where+    V2 c'x c'y = realToFrac <$> kptPoint+    c'kptSize     = realToFrac kptSize+    c'kptAngle    = realToFrac kptAngle+    c'kptResponse = realToFrac kptResponse++mkKeyPoint :: KeyPointRec -> KeyPoint+mkKeyPoint = unsafePerformIO . newKeyPoint++keyPointAsRec :: KeyPoint -> KeyPointRec+keyPointAsRec kpt = unsafePerformIO $+    withPtr kpt $ \kptPtr ->+    alloca $ \xPtr        ->+    alloca $ \yPtr        ->+    alloca $ \sizePtr     ->+    alloca $ \anglePtr    ->+    alloca $ \responsePtr ->+    alloca $ \octavePtr   ->+    alloca $ \classIdPtr  -> do+      [CU.block|void {+        KeyPoint * kpt = $(KeyPoint * kptPtr);+        *$(float   * xPtr       ) = kpt->pt.x    ;+        *$(float   * yPtr       ) = kpt->pt.y    ;+        *$(float   * sizePtr    ) = kpt->size    ;+        *$(float   * anglePtr   ) = kpt->angle   ;+        *$(float   * responsePtr) = kpt->response;+        *$(int32_t * octavePtr  ) = kpt->octave  ;+        *$(int32_t * classIdPtr ) = kpt->class_id;+      }|]+      KeyPointRec+        <$> ( V2 <$> (realToFrac <$> peek xPtr)+                 <*> (realToFrac <$> peek yPtr)+            )+        <*> (realToFrac <$> peek sizePtr    )+        <*> (realToFrac <$> peek anglePtr   )+        <*> (realToFrac <$> peek responsePtr)+        <*> peek octavePtr+        <*> peek classIdPtr++--------------------------------------------------------------------------------+-- DMatch+--------------------------------------------------------------------------------++{- | Class for matching keypoint descriptors: query descriptor index, train+descriptor index, train image index, and distance between descriptors++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#dmatch OpenCV Sphinx Doc>+-}+newtype DMatch = DMatch {unDMatch :: ForeignPtr C'DMatch}++type instance C DMatch = C'DMatch++mkPlacementNewInstance ''DMatch++instance WithPtr DMatch where+    withPtr = withForeignPtr . unDMatch++instance FromPtr DMatch where+    fromPtr = objFromPtr DMatch $ \ptr ->+                [CU.exp| void { delete $(DMatch * ptr) }|]++instance CSizeOf C'DMatch where+    cSizeOf _proxy = c'sizeof_DMatch++data DMatchRec+   = DMatchRec+     { dmatchQueryIdx :: !Int32+       -- ^ Query descriptor index.+     , dmatchTrainIdx :: !Int32+       -- ^ Train descriptor index.+     , dmatchImgIdx   :: !Int32+       -- ^ Train image index.+     , dmatchDistance :: !Float+     } deriving (Eq, Show)++newDMatch :: DMatchRec -> IO DMatch+newDMatch DMatchRec{..} = fromPtr $+    [CU.exp|DMatch * {+      new cv::DMatch+          ( $(int32_t dmatchQueryIdx)+          , $(int32_t dmatchTrainIdx)+          , $(int32_t dmatchImgIdx)+          , $(float c'distance)+          )+    }|]+  where+    c'distance = realToFrac dmatchDistance++mkDMatch :: DMatchRec -> DMatch+mkDMatch = unsafePerformIO . newDMatch++dmatchAsRec :: DMatch -> DMatchRec+dmatchAsRec dmatch = unsafePerformIO $+    withPtr dmatch $ \dmatchPtr ->+    alloca $ \queryIdxPtr ->+    alloca $ \trainIdxPtr ->+    alloca $ \imgIdxPtr ->+    alloca $ \distancePtr -> do+      [CU.block|void {+        DMatch * dmatch = $(DMatch * dmatchPtr);+        *$(int32_t * queryIdxPtr) = dmatch->queryIdx;+        *$(int32_t * trainIdxPtr) = dmatch->trainIdx;+        *$(int32_t * imgIdxPtr  ) = dmatch->imgIdx  ;+        *$(float   * distancePtr) = dmatch->distance;+      }|]+      DMatchRec+        <$> peek queryIdxPtr+        <*> peek trainIdxPtr+        <*> peek imgIdxPtr+        <*> (realToFrac <$> peek distancePtr)++--------------------------------------------------------------------------------+-- Algorithm+--------------------------------------------------------------------------------++class Algorithm a where+    algorithmClearState :: (PrimMonad m) => a (PrimState m) -> m ()+    algorithmIsEmpty    :: (PrimMonad m) => a (PrimState m) -> m Bool
+ src/OpenCV/Core/Types/Mat.cpp view
@@ -0,0 +1,88 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+Mat * inline_c_OpenCV_Core_Types_Mat_0_aec6440342a3a3b538a2682b90656c83ca688dbd(int32_t cheight_27_inline_c_0, int32_t cwidth_27_inline_c_1, int32_t ctype_27_inline_c_2) {+return (+      new Mat(Mat::eye( cheight_27_inline_c_0+                      , cwidth_27_inline_c_1+                      , ctype_27_inline_c_2+                      ))+    );+}++}++extern "C" {+Exception * inline_c_OpenCV_Core_Types_Mat_1_8d35f6d3e6bcc195bd496c0496e5a557ede4c888(Mat * matOutPtr_inline_c_0, Mat * matInPtr_inline_c_1, Rect2i * rectPtr_inline_c_2) {++  try+  {   +          *matOutPtr_inline_c_0 =+            Mat( *matInPtr_inline_c_1+               , *rectPtr_inline_c_2+               );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_Types_Mat_2_28121ccc1bca77b68036dd041ceeb27ec3b1354d(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t crtype_27_inline_c_2, double calpha_27_inline_c_3, double cbeta_27_inline_c_4) {++  try+  {   +          srcPtr_inline_c_0->+            convertTo( *dstPtr_inline_c_1+                     , crtype_27_inline_c_2+                     , calpha_27_inline_c_3+                     , cbeta_27_inline_c_4+                     );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Core_Types_Mat_3_1f86d28ec864caf3dc84c4aa5822106a8859bd51(const Mat *const srcPtr_inline_c_0, int32_t x_inline_c_1, int32_t y_inline_c_2, Mat * srcMaskPtr_inline_c_3, Mat * dstPtr_inline_c_4) {++  try+  {   +        const cv::Mat * const srcPtr = srcPtr_inline_c_0;+        const int32_t x = x_inline_c_1;+        const int32_t y = y_inline_c_2;+        cv::Mat * srcMaskPtr = srcMaskPtr_inline_c_3;+        srcPtr->copyTo( dstPtr_inline_c_4+                      ->rowRange(y, y + srcPtr->rows)+                       .colRange(x, x + srcPtr->cols)+                      , srcMaskPtr+                        ? cv::_InputArray(*srcMaskPtr)+                        : cv::_InputArray(cv::noArray())+                      );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/Core/Types/Mat.hs view
@@ -0,0 +1,360 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}++{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}++module OpenCV.Core.Types.Mat+    ( -- * Matrix+      Mat+    , MatShape+    , MatChannels+    , MatDepth+    , ToMat(..), FromMat(..)++    , typeCheckMat+    , relaxMat+    , coerceMat++    , emptyMat+    , mkMat+    , eyeMat+    , cloneMat+    , matSubRect+    , matCopyTo+    , matConvertTo++    , matFromFunc++      -- * Mutable Matrix+    , typeCheckMatM+    , relaxMatM+    , coerceMatM++    , freeze+    , thaw+    , mkMatM+    , createMat+    , withMatM+    , cloneMatM+    , matCopyToM++    , All+    , IsStatic+    , foldMat++      -- * Meta information+    , MatInfo(..)+    , matInfo++    , Depth(..)++    , ShapeT+    , ChannelsT+    , DepthT++    , ToShape(toShape)+    , ToShapeDS(toShapeDS)+    , ToChannels, toChannels+    , ToChannelsDS, toChannelsDS+    , ToDepth(toDepth)+    , ToDepthDS(toDepthDS)+    ) where++import "base" Control.Monad ( forM, forM_ )+import "base" Control.Monad.ST ( runST )+import "base" Data.Int ( Int32 )+import "base" Data.List ( foldl' )+import "base" Data.Proxy ( Proxy(..) )+import "base" Data.Word ( Word8 )+import "base" Foreign.Marshal.Array ( peekArray )+import "base" Foreign.Ptr ( Ptr, castPtr, plusPtr )+import "base" Foreign.Storable ( Storable )+import "base" GHC.TypeLits+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.V4 ( V4(..) )+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "this" OpenCV.Core.Types.Rect ( Rect2i )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Core.Types.Mat.ToFrom+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.Mutable+import "this" OpenCV.TypeLevel+import "this" OpenCV.Unsafe ( unsafeWrite )+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V+import qualified "vector" Data.Vector.Storable as DV++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------+-- Matrix+--------------------------------------------------------------------------------++emptyMat :: Mat ('S '[]) ('S 1) ('S Word8)+emptyMat = unsafePerformIO newEmptyMat++-- | Identity matrix+--+-- <http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#mat-eye OpenCV Sphinx doc>+eyeMat+    :: ( ToInt32    height+       , ToInt32    width+       , ToChannels channels+       , ToDepth    depth+       )+    => height   -- ^+    -> width    -- ^+    -> channels -- ^+    -> depth    -- ^+    -> Mat (ShapeT (height ::: width ::: Z)) (ChannelsT channels) (DepthT depth)+eyeMat height width channels depth = unsafeCoerceMat $ unsafePerformIO $+    fromPtr [CU.exp|Mat * {+      new Mat(Mat::eye( $(int32_t c'height)+                      , $(int32_t c'width)+                      , $(int32_t c'type)+                      ))+    }|]+  where+    c'type = marshalFlags depth' channels'++    c'height  = toInt32    height+    c'width   = toInt32    width+    channels' = toChannels channels+    depth'    = toDepth    depth++{- | Extract a sub region from a 2D-matrix (image)++Example:++@+matSubRectImg :: Mat ('S ['D, 'D]) ('S 3) ('S Word8)+matSubRectImg = exceptError $+    withMatM (h ::: 2 * w ::: Z)+             (Proxy :: Proxy 3)+             (Proxy :: Proxy Word8)+             white $ \\imgM -> do+      matCopyToM imgM (V2 0 0) birds_512x341 Nothing+      matCopyToM imgM (V2 w 0) subImg        Nothing+      lift $ rectangle imgM subRect blue 1 LineType_4 0+      lift $ rectangle imgM (toRect $ HRect (V2 w 0) (V2 w h) :: Rect2i) blue 1 LineType_4 0+  where+    subRect = toRect $ HRect (V2 96 131) (V2 90 60)+    subImg = exceptError $+               resize (ResizeAbs $ toSize $ V2 w h) InterCubic =<<+               matSubRect birds_512x341 subRect+    [h, w] = miShape $ matInfo birds_512x341+@++<<doc/generated/examples/matSubRectImg.png matSubRectImg>>+-}+matSubRect+    :: Mat ('S [height, width]) channels depth+    -> Rect2i+    -> CvExcept (Mat ('S ['D, 'D]) channels depth)+matSubRect matIn rect = unsafeWrapException $ do+    matOut <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat matOut) $+      withPtr matIn  $ \matInPtr  ->+      withPtr matOut $ \matOutPtr ->+      withPtr rect   $ \rectPtr   ->+        [cvExceptU|+          *$(Mat * matOutPtr) =+            Mat( *$(Mat * matInPtr)+               , *$(Rect2i * rectPtr)+               );+        |]++matCopyTo+    :: Mat ('S [dstHeight, dstWidth]) channels depth -- ^+    -> V2 Int32 -- ^+    -> Mat ('S [srcHeight, srcWidth]) channels depth -- ^+    -> Maybe (Mat ('S [srcHeight, srcWidth]) ('S 1) ('S Word8))+    -> CvExcept (Mat ('S [dstHeight, dstWidth]) channels depth)+matCopyTo dst topLeft src mbSrcMask = runST $ do+    dstM <- thaw dst+    eResult <- runExceptT $ matCopyToM dstM topLeft src mbSrcMask+    case eResult of+      Left err -> pure $ throwE err+      Right () -> pure <$> unsafeFreeze dstM+++{- | Converts an array to another data type with optional scaling++<http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html?highlight=convertto#mat-convertto OpenCV Sphinx doc>+-}+matConvertTo+    :: forall shape channels srcDepth dstDepth+     . (ToDepthDS (Proxy dstDepth))+    => Maybe Double -- ^ Optional scale factor.+    -> Maybe Double -- ^ Optional delta added to the scaled values.+    -> Mat shape channels srcDepth+    -> CvExcept (Mat shape channels dstDepth)+matConvertTo alpha beta src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          $(Mat * srcPtr)->+            convertTo( *$(Mat * dstPtr)+                     , $(int32_t c'rtype)+                     , $(double c'alpha)+                     , $(double c'beta)+                     );+        |]+  where+    rtype :: Maybe Depth+    rtype = dsToMaybe $ toDepthDS (Proxy :: Proxy dstDepth)++    c'rtype = maybe (-1) marshalDepth rtype+    c'alpha = maybe 1 realToFrac alpha+    c'beta  = maybe 0 realToFrac beta++{- | Create a matrix whose elements are defined by a function.++Example:++@+matFromFuncImg+  :: forall size. (size ~ 300)+  => Mat (ShapeT [size, size]) ('S 4) ('S Word8)+matFromFuncImg = exceptError $+    matFromFunc+      (Proxy :: Proxy [size, size])+      (Proxy :: Proxy 4)+      (Proxy :: Proxy Word8)+      example+  where+    example [y, x] 0 = 255 - normDist (V2 x y ^-^ bluePt )+    example [y, x] 1 = 255 - normDist (V2 x y ^-^ greenPt)+    example [y, x] 2 = 255 - normDist (V2 x y ^-^ redPt  )+    example [y, x] 3 =       normDist (V2 x y ^-^ alphaPt)+    example _pos _channel = error "impossible"++    normDist :: V2 Int -> Word8+    normDist v = floor $ min 255 $ 255 * Linear.norm (fromIntegral \<$> v) / s'++    bluePt  = V2 0 0+    greenPt = V2 s s+    redPt   = V2 s 0+    alphaPt = V2 0 s++    s = fromInteger $ natVal (Proxy :: Proxy size) :: Int+    s' = fromIntegral s :: Double+@++<<doc/generated/examples/matFromFuncImg.png matFromFuncImg>>+-}+matFromFunc+    :: forall shape channels depth+     . ( ToShape    shape+       , ToChannels channels+       , ToDepth    depth+       , Storable   (StaticDepthT depth)+       )+    => shape+    -> channels+    -> depth+    -> ([Int] -> Int -> StaticDepthT depth) -- ^+    -> CvExcept (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth))+matFromFunc shape channels depth func =+    withMatM shape channels depth (0 :: V4 Double) $ \matM ->+      forM_ positions $ \pos ->+        forM_ [0 .. fromIntegral channels' - 1] $ \channel ->+           unsafeWrite matM pos channel $ func pos channel+  where+    positions :: [[Int]]+    positions = dimPositions $ V.toList $ V.map fromIntegral shapeVec++    shapeVec :: V.Vector Int32+    shapeVec = toShape shape++    channels' :: Int32+    channels' = toChannels channels++--------------------------------------------------------------------------------+-- Mutable Matrix+--------------------------------------------------------------------------------++matCopyToM+    :: (PrimMonad m)+    => Mut (Mat ('S [dstHeight, dstWidth]) channels depth) (PrimState m) -- ^+    -> V2 Int32 -- ^+    -> Mat ('S [srcHeight, srcWidth]) channels depth -- ^+    -> Maybe (Mat ('S [srcHeight, srcWidth]) ('S 1) ('S Word8))+    -> CvExceptT m ()+matCopyToM dstM (V2 x y) src mbSrcMask = ExceptT $+    unsafePrimToPrim $ handleCvException (pure ()) $+    withPtr dstM $ \dstPtr ->+    withPtr src $ \srcPtr ->+    withPtr mbSrcMask $ \srcMaskPtr ->+      [cvExcept|+        const cv::Mat * const srcPtr = $(const Mat * const srcPtr);+        const int32_t x = $(int32_t x);+        const int32_t y = $(int32_t y);+        cv::Mat * srcMaskPtr = $(Mat * srcMaskPtr);+        srcPtr->copyTo( $(Mat * dstPtr)+                      ->rowRange(y, y + srcPtr->rows)+                       .colRange(x, x + srcPtr->cols)+                      , srcMaskPtr+                        ? cv::_InputArray(*srcMaskPtr)+                        : cv::_InputArray(cv::noArray())+                      );+      |]++          -- Mat * srcPtr = $(Mat * srcPtr);+          -- Mat dstRoi = Mat( *$(Mat * matOutPtr)+          --                 , Rect( *$(Point2i * topLeftPtr)+          --                       , srcPtr->size()+          --                       )+          --                 );+          -- srcPtr->copyTo(dstRoi);+++-- |Transforms a given list of matrices of equal shape, channels, and depth,+-- by folding the given function over all matrix elements at each position.+foldMat :: forall (shape :: [DS Nat]) (channels :: Nat) (depth :: *) a+         . ( Storable depth+           , Storable a+           , All IsStatic shape+           )+        => (a -> DV.Vector depth -> a) -- ^+        -> a+        -> [Mat ('S shape) ('S channels) ('S depth)]+        -> Maybe (DV.Vector a)+foldMat _ _ []   = Nothing+foldMat f z mats = Just . DV.fromList . unsafePerformIO $ mapM go (dimPositions shape)+  where+    go :: [Int32] -> IO a+    go pos = pixelsAt pos >>= return . foldl' f z++    MatInfo !shape _ !channels = matInfo (head mats)++    stepsAndPtrs :: IO [([Int32], Ptr depth)]+    stepsAndPtrs = forM mats $ \mat ->+        withMatData mat $ \step ptr ->+            return (fromIntegral <$> step, castPtr ptr)++    pixelsAt :: [Int32] -> IO [DV.Vector depth]+    pixelsAt pos = mapM go' =<< stepsAndPtrs+      where+        go' :: ([Int32], Ptr depth) -> IO (DV.Vector depth)+        go' (step, dataPtr) = do+            let !offset = fromIntegral . sum $ zipWith (*) step pos+            vals <- peekArray (fromIntegral channels) (dataPtr `plusPtr` offset)+            return $ DV.fromList vals
+ src/OpenCV/Core/Types/Mat/HMat.hs view
@@ -0,0 +1,16 @@+module OpenCV.Core.Types.Mat.HMat+    ( HMat+    , hmShape+    , hmChannels+    , hmElems+    , HElems(..)+    , hElemsDepth+    , hElemsLength+    , ToHElems+    , toHElems++    , matToHMat+    , hMatToMat+    ) where++import "this" OpenCV.Internal.Core.Types.Mat.HMat
+ src/OpenCV/Core/Types/Mat/Repa.cpp view
@@ -0,0 +1,16 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Mat_Repa_0_ed529332643b0925ec50dffef40211e93fda01ed(Mat * matPtr_inline_c_0, int32_t **const sizePtr_inline_c_1, size_t **const stepPtr_inline_c_2, uint8_t **const dataPtrPtr_inline_c_3) {++        const Mat * const matPtr = matPtr_inline_c_0;+        *sizePtr_inline_c_1 = matPtr->size.p;+        *stepPtr_inline_c_2 = matPtr->step.p;+        *dataPtrPtr_inline_c_3 = matPtr->data;+      +}++}
+ src/OpenCV/Core/Types/Mat/Repa.hs view
@@ -0,0 +1,172 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language InstanceSigs #-}+{-# language ConstraintKinds #-}+{-# language TemplateHaskell #-}+{-# language UndecidableInstances #-}+{-# language MultiParamTypeClasses #-}+{-# language ExistentialQuantification #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.Core.Types.Mat.Repa+    ( M+    , DIM+    , toRepa+    ) where++import "base" Data.Int+import "base" Data.Monoid+import "base" Data.Proxy+import "base" Data.Word+import "base" Foreign.C.Types+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( peekArray )+import "base" Foreign.Ptr ( Ptr, plusPtr )+import "base" Foreign.Storable ( Storable(..), peek, sizeOf )+import "base" GHC.TypeLits+import "base" System.IO.Unsafe ( unsafePerformIO )+import "deepseq" Control.DeepSeq (NFData, rnf)+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import qualified "repa" Data.Array.Repa as Repa+import           "repa" Data.Array.Repa.Index ( (:.) )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.TypeLevel+++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------+--  Repa+--------------------------------------------------------------------------------++-- | Representation tag for Repa @'Repa.Array's@ for OpenCV @'Mat's@.+data M (shape :: [DS Nat]) (channels :: Nat)++type family DIM (n :: Nat) :: * where+    DIM 0 = Repa.Z+    DIM n = DIM (n-1) :. Int++-- | Converts an OpenCV @'Mat'rix@ into a Repa array.+--+-- This is a zero-copy operation.+toRepa+    :: forall (shape    :: [DS Nat])+              (channels :: Nat)+              (depth    :: *)+              (dims     :: Nat)+              (sh       :: *)+     . ( Storable depth+       , KnownNat channels+       , KnownNat dims+       , dims ~ Length shape+       , sh ~ DIM ((dims + 1))+       )+    => Mat ('S shape) ('S channels) ('S depth) -- ^+    -> Repa.Array (M shape channels) sh depth+toRepa mat = unsafePerformIO $ withPtr mat $ \matPtr ->+    alloca $ \(sizePtr    :: Ptr (Ptr Int32)) ->+    alloca $ \(stepPtr    :: Ptr (Ptr CSize)) ->+    alloca $ \(dataPtrPtr :: Ptr (Ptr Word8)) -> do+      [CU.block| void {+        const Mat * const matPtr = $(Mat * matPtr);+        *$(int32_t * * const sizePtr   ) = matPtr->size.p;+        *$(size_t  * * const stepPtr   ) = matPtr->step.p;+        *$(uint8_t * * const dataPtrPtr) = matPtr->data;+      }|]+      let dims = fromInteger $ natVal (Proxy :: Proxy dims)++      (size :: Ptr Int32) <- peek sizePtr+      sizeShape <- map fromIntegral <$> peekArray dims size+      let sizes = sizeShape <> [fromInteger $ natVal (Proxy :: Proxy channels)]++      (step :: Ptr CSize) <- peek stepPtr+      stepShape <- map fromIntegral <$> peekArray dims step+      let steps = stepShape <> [sizeOf (undefined :: depth)]++      (dataPtr :: Ptr Word8) <- peek dataPtrPtr+      pure $ Array mat dataPtr sizes steps++instance (Repa.Shape sh, Storable depth) => NFData (Repa.Array (M shape channels) sh depth) where+    rnf a = Repa.deepSeqArray a ()++instance (Storable depth) => Repa.Source (M shape channels) depth where+    -- TODO (BvD): We might want to check for isContinuous() to optimize certain operations.++    data Array (M shape channels) sh depth =+          Array !(Mat ('S shape) ('S channels) ('S depth))+                 -- The Mat is kept around so that the data doesn't get garbage collected.+                !(Ptr Word8) -- Pointer to the data.+                ![Int] -- The shape of the extent which is determined by mat->dims and mat->size.p.+                ![Int] -- The shape of the data which is determined by mat->dims and mat->step.p.++    extent :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> sh+    extent (Array _ _ sizeShape _) = Repa.shapeOfList sizeShape++    index :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> sh -> depth+    index (Array mat dataPtr sizeShape stepShape) ix =+        unsafePerformIO $ keepMatAliveDuring mat $ peek elemPtr+      where+        elemPtr :: Ptr depth+        elemPtr = dataPtr `plusPtr` offset++        offset :: Int+        offset = sum $ zipWith3 mul sizeShape stepShape (Repa.listOfShape ix)++        mul size step i+            | i < size  = step * i+            | otherwise = error $+                "Index " <> show i <> " >= size: " <> show size++    unsafeIndex :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> sh -> depth+    unsafeIndex (Array mat dataPtr _ stepShape) ix =+        unsafePerformIO $ keepMatAliveDuring mat $ peek elemPtr+      where+        elemPtr :: Ptr depth+        elemPtr = matElemAddress dataPtr stepShape (Repa.listOfShape ix)++    linearIndex :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> Int -> depth+    linearIndex a ix = Repa.index a sh+        where+          sh = Repa.fromIndex (Repa.extent a) ix++    unsafeLinearIndex :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> Int -> depth+    unsafeLinearIndex a ix = Repa.unsafeIndex a sh+        where+          sh = Repa.fromIndex (Repa.extent a) ix++    deepSeqArray :: (Repa.Shape sh) => Repa.Array (M shape channels) sh depth -> b -> b+    deepSeqArray = seq++-- TODO (BvD): Is it possible to define something like the following?+--+-- instance (Storable depth) => Repa.Target (M shape channels) depth where+--+--     newtype MVec (M shape channels) depth = MVec IOMat+--+--     newMVec :: Int -> IO (MVec (M shape channels) depth)+--     newMVec size = _todo_newMVec+--+--     unsafeWriteMVec :: MVec (M shape channels) depth -> Int -> depth -> IO ()+--     unsafeWriteMVec = _todo_unsafeWriteMVec+--+--     unsafeFreezeMVec :: sh  -> MVec (M shape channels) depth -> IO (Array (M shape channels) sh depth)+--     unsafeFreezeMVec = _todo_unsafeFreezeMVec+--+--     deepSeqMVec :: MVec (M shape channels) depth -> a -> a+--     deepSeqMVec = _todo_deepSeqMVec+--+--     touchMVec :: MVec (M shape channels) depth -> IO ()+--     touchMVec = _todo_touchMVec
+ src/OpenCV/Core/Types/Matx.cpp view
@@ -0,0 +1,944 @@++#include "opencv2/core.hpp"++#include "haskell_opencv_matx_typedefs.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_0_ecc0aea5264d88a93f3198f3f74b7e772d7e135b(Matx12f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx12f * inline_c_OpenCV_Core_Types_Matx_1_fb8da77ff92a9bb05e8aab30d9984bb5ec1ddb72(float f11_inline_c_0, float f12_inline_c_1) {+return ( new cv::Matx<float, 1, 2>(f11_inline_c_0, f12_inline_c_1));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_2_1c84c42bdc9f7b3ada5769613cd32dbcbff603a5(Matx12f * dst_inline_c_0, Matx12f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx12f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_3_a1a740c9625197899332bc82a3e8c165e13d86d9(Matx12f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx12f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_4_357f36170e27df1054eccb8ff672050f3a0e8946(Matx12d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx12d * inline_c_OpenCV_Core_Types_Matx_5_346fc1f702eddc96083c2fcfb9b14b69944bc3ec(double f11_inline_c_0, double f12_inline_c_1) {+return ( new cv::Matx<double, 1, 2>(f11_inline_c_0, f12_inline_c_1));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_6_95b918fe3dc7efa16e17380f0d404b135b417cdb(Matx12d * dst_inline_c_0, Matx12d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx12d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_7_a33160048231055b813bc4419b4ab2757fb276fe(Matx12d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx12d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_8_9fb0861969a347ec6ae2ffb981bea3733d504ee1(Matx13f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx13f * inline_c_OpenCV_Core_Types_Matx_9_dd792afe93422c8de89075299be8ab0a47f4966f(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2) {+return ( new cv::Matx<float, 1, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_10_7fdce466881f5c6581623c3e4e029b3b4ac434bd(Matx13f * dst_inline_c_0, Matx13f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx13f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_11_7eef2eaba25087bd730faead16222330046c1510(Matx13f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx13f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_12_e5e848f55240fa84a16b967fd3975a921b7fce38(Matx13d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx13d * inline_c_OpenCV_Core_Types_Matx_13_d546c2c8f0e1bdb247f2aa8afadcd9af28bcd0fa(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2) {+return ( new cv::Matx<double, 1, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_14_f0b1b6e64967ccc82108ed5d120da5ba4b792513(Matx13d * dst_inline_c_0, Matx13d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx13d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_15_8e4b5410e2971c04c64cc6b65cedad7b7c4a1f18(Matx13d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx13d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_16_554fc7fe535e59bb3dc663b0ef60d9a4ea403c88(Matx14f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx14f * inline_c_OpenCV_Core_Types_Matx_17_32d2241d5268e5c2e95c7e43f890d6061c004c63(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f14_inline_c_3) {+return ( new cv::Matx<float, 1, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_18_6754bf25c403d9f3541b6ed593b595ef14c413af(Matx14f * dst_inline_c_0, Matx14f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx14f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_19_5958fb9d776f9f708ff1e97d653b9704c1cdac99(Matx14f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx14f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_20_76b511b85c5f0c709ebd92e41f59df24da362f6f(Matx14d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx14d * inline_c_OpenCV_Core_Types_Matx_21_94e36916752cfddc6539ac06db0a41e93d83bf86(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f14_inline_c_3) {+return ( new cv::Matx<double, 1, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_22_8be3b874e6ddfd14e8c9292dbe4dbb7febfe718b(Matx14d * dst_inline_c_0, Matx14d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx14d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_23_c44f16b7809469acdfa6f1093b56cd856f2583c8(Matx14d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx14d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_24_e931a27d6ca3a911fbcdb3f99da90704ae03c4f2(Matx16f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx16f * inline_c_OpenCV_Core_Types_Matx_25_ddfc330d15e7a5050ed9051ab006af00a19d3f12(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f14_inline_c_3, float f15_inline_c_4, float f16_inline_c_5) {+return ( new cv::Matx<float, 1, 6>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f15_inline_c_4, f16_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_26_ccd6452c7cb4ef33bbdf247bc80ab97430b3f108(Matx16f * dst_inline_c_0, Matx16f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx16f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_27_69dbedaa4755805a515476dd41d156e7b38dc7ee(Matx16f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx16f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_28_88580a7f44470f96eee3b9cfc2adeeff6d672934(Matx16d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx16d * inline_c_OpenCV_Core_Types_Matx_29_79e31d1238b61036d7f57caf1611ef7b82306764(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f14_inline_c_3, double f15_inline_c_4, double f16_inline_c_5) {+return ( new cv::Matx<double, 1, 6>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f15_inline_c_4, f16_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_30_18210c540fc473aedb15eba9df7b3fe2d22462c7(Matx16d * dst_inline_c_0, Matx16d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx16d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_31_53b1cb2c033499ac599ff85cd7c583b960188d81(Matx16d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx16d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_32_db496641dcfe557f141bb9882960e324caf7edb2(Matx21f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx21f * inline_c_OpenCV_Core_Types_Matx_33_671f33c55c067f94f3c49117b2dee51b27aaa3c4(float f11_inline_c_0, float f21_inline_c_1) {+return ( new cv::Matx<float, 2, 1>(f11_inline_c_0, f21_inline_c_1));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_34_89cd945a0053581614fede243bceab846e83dc5a(Matx21f * dst_inline_c_0, Matx21f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx21f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_35_03ae0fbb42c4bf865e36ec9e7960a7ad456747e8(Matx21f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx21f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_36_d77ece2ae4136f68abf1ab461dc1d9e7fe48d37a(Matx21d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx21d * inline_c_OpenCV_Core_Types_Matx_37_d838f2c4138bb4a75b3b1d5d717119d12fecd63d(double f11_inline_c_0, double f21_inline_c_1) {+return ( new cv::Matx<double, 2, 1>(f11_inline_c_0, f21_inline_c_1));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_38_321cab012775ef6c2d93b558ee7a69f56affbf9f(Matx21d * dst_inline_c_0, Matx21d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx21d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_39_2fefacaf137a288c7e95eda42878527f39f0bcd7(Matx21d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx21d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_40_f41e528a9ba7a823d3b6273592513f7eb00d5b4c(Matx22f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx22f * inline_c_OpenCV_Core_Types_Matx_41_f92caa84793f6e4b7d6d9b513331da4e074eb899(float f11_inline_c_0, float f12_inline_c_1, float f21_inline_c_2, float f22_inline_c_3) {+return ( new cv::Matx<float, 2, 2>(f11_inline_c_0, f12_inline_c_1, f21_inline_c_2, f22_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_42_17de5feab7a3cb0f499a1cdea31249978b1d7379(Matx22f * dst_inline_c_0, Matx22f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx22f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_43_c975a8bcc6f15379bb7b515f10e523ef2430d310(Matx22f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx22f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_44_c57d19e319737e6b6675c39f49b1813a6ae3961e(Matx22d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx22d * inline_c_OpenCV_Core_Types_Matx_45_d344812730325f3db83bff3410f0a5d2382e4369(double f11_inline_c_0, double f12_inline_c_1, double f21_inline_c_2, double f22_inline_c_3) {+return ( new cv::Matx<double, 2, 2>(f11_inline_c_0, f12_inline_c_1, f21_inline_c_2, f22_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_46_4cd9e3ddb68a7420af5a62d4b8e674fbc05f0039(Matx22d * dst_inline_c_0, Matx22d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx22d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_47_0ee2d38d0351aa0c259f98c04b1824850efd142c(Matx22d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx22d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_48_bcf09c6d33bbe18a85c1bcb71ad4011f10d02994(Matx23f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx23f * inline_c_OpenCV_Core_Types_Matx_49_166cdb24ef3f5e441f895c8aef38b478b6401dd8(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f21_inline_c_3, float f22_inline_c_4, float f23_inline_c_5) {+return ( new cv::Matx<float, 2, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_50_4e81fe68d3719ee8034e61319ca375dddb18a6fd(Matx23f * dst_inline_c_0, Matx23f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx23f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_51_95566ebbdb0a916fbd924b6b19096c9d9f581388(Matx23f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx23f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_52_fb14f4a788de99616cafab7daf200307318d0536(Matx23d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx23d * inline_c_OpenCV_Core_Types_Matx_53_919defd104b3e7b42f4c366ef47bfbaaefb5de75(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f21_inline_c_3, double f22_inline_c_4, double f23_inline_c_5) {+return ( new cv::Matx<double, 2, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_54_c9256b30f91a917c17e9410040ce45101dd55058(Matx23d * dst_inline_c_0, Matx23d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx23d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_55_e728e1914495bd63b6bdfe951a536c87ab1bff8c(Matx23d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx23d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_56_aedb5254eb38137a593dc8e6de1b99e092dddc92(Matx31f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx31f * inline_c_OpenCV_Core_Types_Matx_57_b48ea0caa7a591aa65e2235d943fb0856f4a73c7(float f11_inline_c_0, float f21_inline_c_1, float f31_inline_c_2) {+return ( new cv::Matx<float, 3, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_58_aea38048429c3f9f58c9d937f0c19fbb5f1e7fea(Matx31f * dst_inline_c_0, Matx31f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx31f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_59_d8f4eabf3bfc5ef6cb984604bf2835b7b09fdf15(Matx31f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx31f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_60_5dc65b4a633b162429ae3f31d4a415b90f942bee(Matx31d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx31d * inline_c_OpenCV_Core_Types_Matx_61_5ab9941b3a87247afaef157feabe7b855387c828(double f11_inline_c_0, double f21_inline_c_1, double f31_inline_c_2) {+return ( new cv::Matx<double, 3, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_62_37b8b5b69dd8cd7fa3110cfb0d770bd784ee10cc(Matx31d * dst_inline_c_0, Matx31d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx31d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_63_738557b34baf2f9ebb210ccc0a2d6a14635da89a(Matx31d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx31d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_64_4caeceee736d6c5285cc5f6177314b1e3ff1d4b4(Matx32f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx32f * inline_c_OpenCV_Core_Types_Matx_65_c7c133dc746adf8a86ffd7a1dc27b6a35e97d6b5(float f11_inline_c_0, float f12_inline_c_1, float f21_inline_c_2, float f22_inline_c_3, float f31_inline_c_4, float f32_inline_c_5) {+return ( new cv::Matx<float, 3, 2>(f11_inline_c_0, f12_inline_c_1, f21_inline_c_2, f22_inline_c_3, f31_inline_c_4, f32_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_66_1c32b1ccf1625d3e3fa447e32a8e54dbee5485ba(Matx32f * dst_inline_c_0, Matx32f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx32f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_67_1ae7db01b605ed8247e108ccea9da6ee85b1576c(Matx32f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx32f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_68_e81e053372e9b203f508b5a1be1aaafada501c84(Matx32d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx32d * inline_c_OpenCV_Core_Types_Matx_69_c3506943947fa3bd9f8fdcd57ab2ba87af463c4c(double f11_inline_c_0, double f12_inline_c_1, double f21_inline_c_2, double f22_inline_c_3, double f31_inline_c_4, double f32_inline_c_5) {+return ( new cv::Matx<double, 3, 2>(f11_inline_c_0, f12_inline_c_1, f21_inline_c_2, f22_inline_c_3, f31_inline_c_4, f32_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_70_47d26c134c9a257524d349a1f2fb46120e091576(Matx32d * dst_inline_c_0, Matx32d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx32d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_71_cefe63c762390d7a12eec665aa68428c22766e29(Matx32d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx32d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_72_b63f326b15e215b8e56bfc1c3e53db176a26aaeb(Matx33f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx33f * inline_c_OpenCV_Core_Types_Matx_73_3484300f9db08025060be432db735876641a681b(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f21_inline_c_3, float f22_inline_c_4, float f23_inline_c_5, float f31_inline_c_6, float f32_inline_c_7, float f33_inline_c_8) {+return ( new cv::Matx<float, 3, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5, f31_inline_c_6, f32_inline_c_7, f33_inline_c_8));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_74_2d9faeba8f715d60cbc2319d6bc7b417eb76178d(Matx33f * dst_inline_c_0, Matx33f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx33f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_75_dcaf6054dd53fe44f13ecfd2dc580ff81c9efd1a(Matx33f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx33f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_76_125734cf190ec61af4b9c5c4aa46950d79ed856e(Matx33d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx33d * inline_c_OpenCV_Core_Types_Matx_77_e99e24aa2e52614a3bafa2e5e256807bcc19cb3d(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f21_inline_c_3, double f22_inline_c_4, double f23_inline_c_5, double f31_inline_c_6, double f32_inline_c_7, double f33_inline_c_8) {+return ( new cv::Matx<double, 3, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5, f31_inline_c_6, f32_inline_c_7, f33_inline_c_8));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_78_d5d8983f6444b21b62c6d0180100950346d27a87(Matx33d * dst_inline_c_0, Matx33d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx33d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_79_6e53e44ba5b2542f27b7b8b33dd74798f6acabd5(Matx33d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx33d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_80_9a093ee30d030fabdcf340004217f89618463931(Matx34f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx34f * inline_c_OpenCV_Core_Types_Matx_81_ca19bba3590dcef56e46240b8a7acd357647f070(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f14_inline_c_3, float f21_inline_c_4, float f22_inline_c_5, float f23_inline_c_6, float f24_inline_c_7, float f31_inline_c_8, float f32_inline_c_9, float f33_inline_c_10, float f34_inline_c_11) {+return ( new cv::Matx<float, 3, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f21_inline_c_4, f22_inline_c_5, f23_inline_c_6, f24_inline_c_7, f31_inline_c_8, f32_inline_c_9, f33_inline_c_10, f34_inline_c_11));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_82_cd829afb745dd049a2886e8649b81ce142adc8aa(Matx34f * dst_inline_c_0, Matx34f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx34f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_83_e565dfe74916a4aadaf98e7208712956b6bb4de1(Matx34f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx34f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_84_a1ffadb3fcf5316d39955cd1710cc341963ddaa7(Matx34d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx34d * inline_c_OpenCV_Core_Types_Matx_85_47ac8970971e717e36c105b7c7f942c335dbf99c(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f14_inline_c_3, double f21_inline_c_4, double f22_inline_c_5, double f23_inline_c_6, double f24_inline_c_7, double f31_inline_c_8, double f32_inline_c_9, double f33_inline_c_10, double f34_inline_c_11) {+return ( new cv::Matx<double, 3, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f21_inline_c_4, f22_inline_c_5, f23_inline_c_6, f24_inline_c_7, f31_inline_c_8, f32_inline_c_9, f33_inline_c_10, f34_inline_c_11));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_86_48e2c72ef708ef6922da982165f42e3d2aaf0978(Matx34d * dst_inline_c_0, Matx34d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx34d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_87_649c36fe976a2c64f1ed45ddad48ee5680373ef5(Matx34d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx34d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_88_544d823770baa46d1ccc3fa6319d770d18b3a306(Matx41f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx41f * inline_c_OpenCV_Core_Types_Matx_89_f259e678948d720471bd840f2666c4832a20d832(float f11_inline_c_0, float f21_inline_c_1, float f31_inline_c_2, float f41_inline_c_3) {+return ( new cv::Matx<float, 4, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_90_ad18e320d648c62a8d681eb392aebb69752c166e(Matx41f * dst_inline_c_0, Matx41f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx41f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_91_4eae7d25d3fdceed3f5a4b36353b93e425bf79e1(Matx41f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx41f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_92_2d5c9ebe3cfe3a0f0c43872ece5b8e884f4e0150(Matx41d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx41d * inline_c_OpenCV_Core_Types_Matx_93_6a7473824354e2fa29ed260d9f9a397fc4dbbb1b(double f11_inline_c_0, double f21_inline_c_1, double f31_inline_c_2, double f41_inline_c_3) {+return ( new cv::Matx<double, 4, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_94_e8f29ed53c833fe9bd90c79cd4c811f10c7f38c1(Matx41d * dst_inline_c_0, Matx41d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx41d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_95_d137e413aca15cb0f949afa656a61703d02c6c67(Matx41d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx41d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_96_7dbb15428397cc59f0f6f7a5013aad3c2a4593d4(Matx43f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx43f * inline_c_OpenCV_Core_Types_Matx_97_c63ca9f1a492e644a0dba8f53f7717b3ca6f9590(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f21_inline_c_3, float f22_inline_c_4, float f23_inline_c_5, float f31_inline_c_6, float f32_inline_c_7, float f33_inline_c_8, float f41_inline_c_9, float f42_inline_c_10, float f43_inline_c_11) {+return ( new cv::Matx<float, 4, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5, f31_inline_c_6, f32_inline_c_7, f33_inline_c_8, f41_inline_c_9, f42_inline_c_10, f43_inline_c_11));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_98_158b31730cb4058e8d44c4c4f754739b06ccd61f(Matx43f * dst_inline_c_0, Matx43f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx43f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_99_587e941b95f98b11ae72fcbafcb3c05f9a0ada90(Matx43f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx43f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_100_d2e69c94e35f2821acb96e80d42723b6f1c88109(Matx43d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx43d * inline_c_OpenCV_Core_Types_Matx_101_6cd7600446c189784350025019a2dd9093a3a0ae(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f21_inline_c_3, double f22_inline_c_4, double f23_inline_c_5, double f31_inline_c_6, double f32_inline_c_7, double f33_inline_c_8, double f41_inline_c_9, double f42_inline_c_10, double f43_inline_c_11) {+return ( new cv::Matx<double, 4, 3>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f21_inline_c_3, f22_inline_c_4, f23_inline_c_5, f31_inline_c_6, f32_inline_c_7, f33_inline_c_8, f41_inline_c_9, f42_inline_c_10, f43_inline_c_11));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_102_27c91b2c0c0694e6dd496fe73bbaa16e85646815(Matx43d * dst_inline_c_0, Matx43d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx43d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_103_aa86bf92a4ce09bb07a34703621e33b398bd3f93(Matx43d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx43d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_104_9a5c2f3156f5cbce80c7cf2eaec77adb8fd4c775(Matx44f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx44f * inline_c_OpenCV_Core_Types_Matx_105_7040d0979afd3acb647e57685e3fa845c69cea98(float f11_inline_c_0, float f12_inline_c_1, float f13_inline_c_2, float f14_inline_c_3, float f21_inline_c_4, float f22_inline_c_5, float f23_inline_c_6, float f24_inline_c_7, float f31_inline_c_8, float f32_inline_c_9, float f33_inline_c_10, float f34_inline_c_11, float f41_inline_c_12, float f42_inline_c_13, float f43_inline_c_14, float f44_inline_c_15) {+return ( new cv::Matx<float, 4, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f21_inline_c_4, f22_inline_c_5, f23_inline_c_6, f24_inline_c_7, f31_inline_c_8, f32_inline_c_9, f33_inline_c_10, f34_inline_c_11, f41_inline_c_12, f42_inline_c_13, f43_inline_c_14, f44_inline_c_15));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_106_686b89c6e61ea871263a084f858680649b40a09d(Matx44f * dst_inline_c_0, Matx44f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx44f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_107_39f8f56420d11b97b36ad9ffa7af5ca7d3514482(Matx44f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx44f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_108_a114155b10958523c9a714122bf36a637a7ba100(Matx44d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx44d * inline_c_OpenCV_Core_Types_Matx_109_1753edede667749e7e562104238ab0c09636474f(double f11_inline_c_0, double f12_inline_c_1, double f13_inline_c_2, double f14_inline_c_3, double f21_inline_c_4, double f22_inline_c_5, double f23_inline_c_6, double f24_inline_c_7, double f31_inline_c_8, double f32_inline_c_9, double f33_inline_c_10, double f34_inline_c_11, double f41_inline_c_12, double f42_inline_c_13, double f43_inline_c_14, double f44_inline_c_15) {+return ( new cv::Matx<double, 4, 4>(f11_inline_c_0, f12_inline_c_1, f13_inline_c_2, f14_inline_c_3, f21_inline_c_4, f22_inline_c_5, f23_inline_c_6, f24_inline_c_7, f31_inline_c_8, f32_inline_c_9, f33_inline_c_10, f34_inline_c_11, f41_inline_c_12, f42_inline_c_13, f43_inline_c_14, f44_inline_c_15));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_110_1ce140751a04ebfe3a85a04b69c6dbdf4c020c57(Matx44d * dst_inline_c_0, Matx44d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx44d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_111_85a4ae342aa6be5b5c81bab59544c99dd9b2c2c5(Matx44d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx44d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_112_d48ec1cd5d7800f7e70d3559eba99ac9b44770c4(Matx51f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx51f * inline_c_OpenCV_Core_Types_Matx_113_fdacfa7b3291214cdc410df34dabb74dcbe87f69(float f11_inline_c_0, float f21_inline_c_1, float f31_inline_c_2, float f41_inline_c_3, float f51_inline_c_4) {+return ( new cv::Matx<float, 5, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3, f51_inline_c_4));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_114_d7887e33ea0da2b8f5ab12d84428001faf958b28(Matx51f * dst_inline_c_0, Matx51f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx51f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_115_575d7660855bb437f9b24f7a5937e01f9bad0b65(Matx51f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx51f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_116_3eb846870eb373320a31912477c9f12c9b740447(Matx51d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx51d * inline_c_OpenCV_Core_Types_Matx_117_92875d62e418a45e4aee4d562df35cdbe43e55ca(double f11_inline_c_0, double f21_inline_c_1, double f31_inline_c_2, double f41_inline_c_3, double f51_inline_c_4) {+return ( new cv::Matx<double, 5, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3, f51_inline_c_4));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_118_f6b1fd1fc2495bc8814f504cf5581b6b2cfcbcf5(Matx51d * dst_inline_c_0, Matx51d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx51d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_119_bec01f17acace040f313fc20f3bb8a02b4e3ae9a(Matx51d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx51d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_120_290d967d3b74622af9162142871b0474b2a8bd85(Matx61f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx61f * inline_c_OpenCV_Core_Types_Matx_121_88beb79fbf4fac58359963ce03d72d9d1860b39d(float f11_inline_c_0, float f21_inline_c_1, float f31_inline_c_2, float f41_inline_c_3, float f51_inline_c_4, float f61_inline_c_5) {+return ( new cv::Matx<float, 6, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3, f51_inline_c_4, f61_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_122_adb3e91425e827d5e5b5a7a0ce2c4c67907d17f7(Matx61f * dst_inline_c_0, Matx61f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx61f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_123_f7de6dd79872f040addd23ea38243e7440d00623(Matx61f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx61f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_124_4587bc094cc72a31060b4b5c4cfab3020597d4f3(Matx61d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Matx61d * inline_c_OpenCV_Core_Types_Matx_125_0024ed44353a0ae7a6e52a8f87caf9eda5ec75b9(double f11_inline_c_0, double f21_inline_c_1, double f31_inline_c_2, double f41_inline_c_3, double f51_inline_c_4, double f61_inline_c_5) {+return ( new cv::Matx<double, 6, 1>(f11_inline_c_0, f21_inline_c_1, f31_inline_c_2, f41_inline_c_3, f51_inline_c_4, f61_inline_c_5));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_126_a9425b9b70fc8f8ef7320a1a2f9c64f5a5dc6474(Matx61d * dst_inline_c_0, Matx61d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx61d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_127_352b0dc6d6305cb4d443f78185b87d746f4deadd(Matx61d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx61d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_128_075a9dc2a0e226d16af311d9ec46734fea493a8f(Matx66f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_129_fa1bc687b8e0135d9208e2869fdba7f5ca20d683(Matx66f * dst_inline_c_0, Matx66f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx66f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_130_5032037b0b440c629d27ce0edca36b8a2bd8cb99(Matx66f * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx66f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_131_6f6df408218406aeb4f4493ac2fcc0006c983f48(Matx66d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_132_308dc8fe1a439220b85267f35fab5db6c8a271ff(Matx66d * dst_inline_c_0, Matx66d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Matx66d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Matx_133_c896033f5bc5e69a3a469f54213b6216f12f9b75(Matx66d * ptr_inline_c_0) {+ ptr_inline_c_0->~Matx66d() ;+}++}
+ src/OpenCV/Core/Types/Matx.hs view
@@ -0,0 +1,99 @@+{-# language MultiParamTypeClasses #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.Core.Types.Matx+    ( -- * Abstract Matx+      Matx+    , MatxDimR+    , MatxDimC+    , IsMatx(..)++      -- * Matx's of specific sizes+    , Matx12f, Matx12d+    , Matx13f, Matx13d+    , Matx14f, Matx14d+    , Matx16f, Matx16d+    , Matx21f, Matx21d+    , Matx22f, Matx22d+    , Matx23f, Matx23d+    , Matx31f, Matx31d+    , Matx32f, Matx32d+    , Matx33f, Matx33d+    , Matx34f, Matx34d+    , Matx41f, Matx41d+    , Matx43f, Matx43d+    , Matx44f, Matx44d+    , Matx51f, Matx51d+    , Matx61f, Matx61d+    , Matx66f, Matx66d++      -- * Constructors+    , newMatx12f, newMatx12d+    , newMatx13f, newMatx13d+    , newMatx14f, newMatx14d+    , newMatx16f, newMatx16d+    , newMatx21f, newMatx21d+    , newMatx22f, newMatx22d+    , newMatx23f, newMatx23d+    , newMatx31f, newMatx31d+    , newMatx32f, newMatx32d+    , newMatx33f, newMatx33d+    , newMatx34f, newMatx34d+    , newMatx41f, newMatx41d+    , newMatx43f, newMatx43d+    , newMatx44f, newMatx44d+    , newMatx51f, newMatx51d+    , newMatx61f, newMatx61d+    ) where++import "base" Foreign.C.Types+import qualified "inline-c"     Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C ( using )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Matx+import "this" OpenCV.Internal.Core.Types.Matx.TH++--------------------------------------------------------------------------------++C.context openCvCtx+C.include "opencv2/core.hpp"+C.include "haskell_opencv_matx_typedefs.hpp"+C.using "namespace cv"++mkMatxType "Matx12f" 1 2 ''CFloat  "float"+mkMatxType "Matx12d" 1 2 ''CDouble "double"+mkMatxType "Matx13f" 1 3 ''CFloat  "float"+mkMatxType "Matx13d" 1 3 ''CDouble "double"+mkMatxType "Matx14f" 1 4 ''CFloat  "float"+mkMatxType "Matx14d" 1 4 ''CDouble "double"+mkMatxType "Matx16f" 1 6 ''CFloat  "float"+mkMatxType "Matx16d" 1 6 ''CDouble "double"+mkMatxType "Matx21f" 2 1 ''CFloat  "float"+mkMatxType "Matx21d" 2 1 ''CDouble "double"+mkMatxType "Matx22f" 2 2 ''CFloat  "float"+mkMatxType "Matx22d" 2 2 ''CDouble "double"+mkMatxType "Matx23f" 2 3 ''CFloat  "float"+mkMatxType "Matx23d" 2 3 ''CDouble "double"+mkMatxType "Matx31f" 3 1 ''CFloat  "float"+mkMatxType "Matx31d" 3 1 ''CDouble "double"+mkMatxType "Matx32f" 3 2 ''CFloat  "float"+mkMatxType "Matx32d" 3 2 ''CDouble "double"+mkMatxType "Matx33f" 3 3 ''CFloat  "float"+mkMatxType "Matx33d" 3 3 ''CDouble "double"+mkMatxType "Matx34f" 3 4 ''CFloat  "float"+mkMatxType "Matx34d" 3 4 ''CDouble "double"+mkMatxType "Matx41f" 4 1 ''CFloat  "float"+mkMatxType "Matx41d" 4 1 ''CDouble "double"+mkMatxType "Matx43f" 4 3 ''CFloat  "float"+mkMatxType "Matx43d" 4 3 ''CDouble "double"+mkMatxType "Matx44f" 4 4 ''CFloat  "float"+mkMatxType "Matx44d" 4 4 ''CDouble "double"+mkMatxType "Matx51f" 5 1 ''CFloat  "float"+mkMatxType "Matx51d" 5 1 ''CDouble "double"+mkMatxType "Matx61f" 6 1 ''CFloat  "float"+mkMatxType "Matx61d" 6 1 ''CDouble "double"+mkMatxType "Matx66f" 6 6 ''CFloat  "float"+mkMatxType "Matx66d" 6 6 ''CDouble "double"
+ src/OpenCV/Core/Types/Point.cpp view
@@ -0,0 +1,235 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Point_0_4c1092f465636708903a1e55c9ecbdeabd8dbb4e(Point2i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2i * inline_c_OpenCV_Core_Types_Point_1_ff12c6c6f284402f3fcb567a543408d4d5e19736(int32_t x_inline_c_0, int32_t y_inline_c_1) {+return ( new cv::Point_<int32_t>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_2_36fc588cdfcab60ba98c5c647d8fef351c89db7a(Point2i * pointPtr_inline_c_0, int32_t * xPtr_inline_c_1, int32_t * yPtr_inline_c_2) {+const cv::Point_<int32_t> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_3_e96ace6d8309077979d03c129b3190b421f8c86f(Point2i * dst_inline_c_0, Point2i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point2i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_4_3d0253537d58326b8b58148c4f9ca64dcf7baf96(Point2i * ptr_inline_c_0) {+ ptr_inline_c_0->~Point2i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_5_437f1664107aa8e50cd3791f8308eff14a5626ca(Point2f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2f * inline_c_OpenCV_Core_Types_Point_6_1c59054097b6c9e61c1e892798e944e1ff0c3a30(float x_inline_c_0, float y_inline_c_1) {+return ( new cv::Point_<float>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_7_6f41b4e6aa3bba43baad41ed0affd6f1ee2be9fc(Point2f * pointPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2) {+const cv::Point_<float> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_8_ab8c69bd58d183c62fb2d434f078c17f73ab2340(Point2f * dst_inline_c_0, Point2f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point2f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_9_424d9064784dff209a6a1f7d5a91967ad8d9c9f2(Point2f * ptr_inline_c_0) {+ ptr_inline_c_0->~Point2f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_10_769fd8ff9cd8c8697e0ce0d4590fa74c3f4886a1(Point2d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2d * inline_c_OpenCV_Core_Types_Point_11_45f70672566f9082b4518ddb07eb73291f7c67b1(double x_inline_c_0, double y_inline_c_1) {+return ( new cv::Point_<double>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_12_4eb865d20dc87fb594c62c6042350384c4e71661(Point2d * pointPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2) {+const cv::Point_<double> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_13_b809b9643ed71aa47abef75c0919c3b76d0ed2fc(Point2d * dst_inline_c_0, Point2d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point2d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_14_d9bd99c8394df6debc379195cf23453e5f32538d(Point2d * ptr_inline_c_0) {+ ptr_inline_c_0->~Point2d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_15_ac8c5a37eb6ce6d17879d6faaba5345fef64c1c0(Point3i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point3i * inline_c_OpenCV_Core_Types_Point_16_eb9bbb8a0db9a0eec73d5d060e0052cbde743ff4(int32_t x_inline_c_0, int32_t y_inline_c_1, int32_t z_inline_c_2) {+return ( new cv::Point3_<int32_t>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_17_92f1f8191764ae3d7ce1e5f04ae61f88dd229efc(Point3i * pointPtr_inline_c_0, int32_t * xPtr_inline_c_1, int32_t * yPtr_inline_c_2, int32_t * zPtr_inline_c_3) {+const cv::Point3_<int32_t> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;+*zPtr_inline_c_3 = p.z;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_18_7d001d545e9d4eca68fb056cb0d3e35e01d97bb2(Point3i * dst_inline_c_0, Point3i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point3i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_19_5c3d561e8841e5271fd465bfb109504b1d56b3f6(Point3i * ptr_inline_c_0) {+ ptr_inline_c_0->~Point3i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_20_47a48e736968a91f839f3878f329dae25dc4d44c(Point3f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point3f * inline_c_OpenCV_Core_Types_Point_21_d421f1efe69726d7c6f34739986fa1e6349d86dd(float x_inline_c_0, float y_inline_c_1, float z_inline_c_2) {+return ( new cv::Point3_<float>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_22_4897152901f708dca15a4c5d911fa1fbcec2f9da(Point3f * pointPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2, float * zPtr_inline_c_3) {+const cv::Point3_<float> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;+*zPtr_inline_c_3 = p.z;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_23_aa5379e6758c3f064378958a62572e251b1786d5(Point3f * dst_inline_c_0, Point3f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point3f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_24_f6c7ab928947a9a6edb6aa80f82f1fe67d9f97a0(Point3f * ptr_inline_c_0) {+ ptr_inline_c_0->~Point3f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_25_a25f256af3d64b9da2e48cd781d9b3ab53c9055e(Point3d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point3d * inline_c_OpenCV_Core_Types_Point_26_362d4fbcaa0d2f6e3bf384b3c8b75e3ddaa10e38(double x_inline_c_0, double y_inline_c_1, double z_inline_c_2) {+return ( new cv::Point3_<double>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_27_46f3905c37aded90c4877e1f261d3c2493b3f34f(Point3d * pointPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2, double * zPtr_inline_c_3) {+const cv::Point3_<double> & p = *pointPtr_inline_c_0;+*xPtr_inline_c_1 = p.x;+*yPtr_inline_c_2 = p.y;+*zPtr_inline_c_3 = p.z;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_28_6966815a8dcc93abfca6f17f31b5301c754d464f(Point3d * dst_inline_c_0, Point3d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Point3d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Point_29_3e82d58d154914c55fd819b6c8fc989749e787b6(Point3d * ptr_inline_c_0) {+ ptr_inline_c_0->~Point3d() ;+}++}
+ src/OpenCV/Core/Types/Point.hs view
@@ -0,0 +1,38 @@+{-# language MultiParamTypeClasses #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.Core.Types.Point+    ( Point+    , PointDim+    , IsPoint(..)+    , IsPoint2+    , IsPoint3++    , Point2i, Point2f, Point2d+    , Point3i, Point3f, Point3d+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types+import qualified "inline-c"     Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C ( using )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Point+import "this" OpenCV.Internal.Core.Types.Point.TH++--------------------------------------------------------------------------------++C.context openCvCtx+C.include "opencv2/core.hpp"+C.using "namespace cv"++mkPointType "Point2i" 2 "Point_"  ''Int32   "int32_t"+mkPointType "Point2f" 2 "Point_"  ''CFloat  "float"+mkPointType "Point2d" 2 "Point_"  ''CDouble "double"++mkPointType "Point3i" 3 "Point3_" ''Int32   "int32_t"+mkPointType "Point3f" 3 "Point3_" ''CFloat  "float"+mkPointType "Point3d" 3 "Point3_" ''CDouble "double"
+ src/OpenCV/Core/Types/Rect.cpp view
@@ -0,0 +1,193 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_0_2a03833d3782c5d114273430f1b66c14ab3cc116(Rect2i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2i * inline_c_OpenCV_Core_Types_Rect_1_e88ee65dc4fd80a5e02c7a7ffd67ee311564baa4(Rect2i * rectPtr_inline_c_0) {+return ( new Point2i(rectPtr_inline_c_0->tl()) );+}++}++extern "C" {+Point2i * inline_c_OpenCV_Core_Types_Rect_2_dcbe7fb07489378839abd73274d02bf0b1dfe595(Rect2i * rectPtr_inline_c_0) {+return ( new Point2i(rectPtr_inline_c_0->br()) );+}++}++extern "C" {+Size2i * inline_c_OpenCV_Core_Types_Rect_3_fee2c7d398c9f0a125180587b20ed5d1846ec104(Rect2i * rectPtr_inline_c_0) {+return ( new Size2i(rectPtr_inline_c_0->size()) );+}++}++extern "C" {+int32_t inline_c_OpenCV_Core_Types_Rect_4_73faa5315716a776ac7931fbdf1877b4812b167b(Rect2i * rectPtr_inline_c_0) {+return ( rectPtr_inline_c_0->area() );+}++}++extern "C" {+int inline_c_OpenCV_Core_Types_Rect_5_0225df883d2169db13e9eee85a40b1e8553f3f41(Rect2i * rectPtr_inline_c_0, Point2i * pointPtr_inline_c_1) {+return ( rectPtr_inline_c_0->contains(*pointPtr_inline_c_1) );+}++}++extern "C" {+Rect2i * inline_c_OpenCV_Core_Types_Rect_6_d5d1a676fc6c97ff167fdbcc6cbe7f2b0fd7a855(int32_t x_inline_c_0, int32_t y_inline_c_1, int32_t w_inline_c_2, int32_t h_inline_c_3) {+return ( new cv::Rect_<int32_t>(x_inline_c_0, y_inline_c_1, w_inline_c_2, h_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_7_e4b911966f836003b9d7755d1eedf6d8cbb7a2b2(Rect2i * dst_inline_c_0, Rect2i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Rect2i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_8_7c4416a9e3fcf2a789b8b1b8ed564708e00242a5(Rect2i * ptr_inline_c_0) {+ ptr_inline_c_0->~Rect2i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_9_ea9d5db520e06210fa6fc99b6d365cf1362243d4(Rect2f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2f * inline_c_OpenCV_Core_Types_Rect_10_4d55b94263389918b9a65679cc5a07255ed1bb31(Rect2f * rectPtr_inline_c_0) {+return ( new Point2f(rectPtr_inline_c_0->tl()) );+}++}++extern "C" {+Point2f * inline_c_OpenCV_Core_Types_Rect_11_627bc66aa680ebd7004d347c661fc6fb1ad0bb71(Rect2f * rectPtr_inline_c_0) {+return ( new Point2f(rectPtr_inline_c_0->br()) );+}++}++extern "C" {+Size2f * inline_c_OpenCV_Core_Types_Rect_12_e98b6862b86d12450cd6d30615b1ab8d2ea116fe(Rect2f * rectPtr_inline_c_0) {+return ( new Size2f(rectPtr_inline_c_0->size()) );+}++}++extern "C" {+float inline_c_OpenCV_Core_Types_Rect_13_16aef11090458219db53802aadf1d0f5b808d19e(Rect2f * rectPtr_inline_c_0) {+return ( rectPtr_inline_c_0->area() );+}++}++extern "C" {+int inline_c_OpenCV_Core_Types_Rect_14_c1fc2bc1e7e300731b568d6c4a87782abac455d3(Rect2f * rectPtr_inline_c_0, Point2f * pointPtr_inline_c_1) {+return ( rectPtr_inline_c_0->contains(*pointPtr_inline_c_1) );+}++}++extern "C" {+Rect2f * inline_c_OpenCV_Core_Types_Rect_15_9b26325d49184116b872dc2bd6952db50b947311(float x_inline_c_0, float y_inline_c_1, float w_inline_c_2, float h_inline_c_3) {+return ( new cv::Rect_<float>(x_inline_c_0, y_inline_c_1, w_inline_c_2, h_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_16_0b307b841dded7c0b465b56e7788a2f448662302(Rect2f * dst_inline_c_0, Rect2f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Rect2f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_17_8d8f6d8c774fc2f238b6c18c682876dbf1da631e(Rect2f * ptr_inline_c_0) {+ ptr_inline_c_0->~Rect2f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_18_c8f0ad0e7f99e37b71ab16061d6ff30b61054a43(Rect2d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Point2d * inline_c_OpenCV_Core_Types_Rect_19_508e81a88fc4f50ac6837d4e7f1edc71ae058d2b(Rect2d * rectPtr_inline_c_0) {+return ( new Point2d(rectPtr_inline_c_0->tl()) );+}++}++extern "C" {+Point2d * inline_c_OpenCV_Core_Types_Rect_20_645032c326d4d286854c9aa28563bf2a20e807ad(Rect2d * rectPtr_inline_c_0) {+return ( new Point2d(rectPtr_inline_c_0->br()) );+}++}++extern "C" {+Size2d * inline_c_OpenCV_Core_Types_Rect_21_2386fcaccd38ce874d37c745a6ec30bf94d6a49e(Rect2d * rectPtr_inline_c_0) {+return ( new Size2d(rectPtr_inline_c_0->size()) );+}++}++extern "C" {+double inline_c_OpenCV_Core_Types_Rect_22_5e47a0497a31309cd6b309d9d36bd6b55cb40f38(Rect2d * rectPtr_inline_c_0) {+return ( rectPtr_inline_c_0->area() );+}++}++extern "C" {+int inline_c_OpenCV_Core_Types_Rect_23_05e33e41465b0473f41dc94c0192610e25c67f18(Rect2d * rectPtr_inline_c_0, Point2d * pointPtr_inline_c_1) {+return ( rectPtr_inline_c_0->contains(*pointPtr_inline_c_1) );+}++}++extern "C" {+Rect2d * inline_c_OpenCV_Core_Types_Rect_24_0b0c40305dcffc0bda363a99d135f673037e9f38(double x_inline_c_0, double y_inline_c_1, double w_inline_c_2, double h_inline_c_3) {+return ( new cv::Rect_<double>(x_inline_c_0, y_inline_c_1, w_inline_c_2, h_inline_c_3));+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_25_251289a591b14ee0f63b7f031449ec42f539cb05(Rect2d * dst_inline_c_0, Rect2d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Rect2d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Rect_26_d5f41a503bb952930172daeb6e0bc176112e0fd4(Rect2d * ptr_inline_c_0) {+ ptr_inline_c_0->~Rect2d() ;+}++}
+ src/OpenCV/Core/Types/Rect.hs view
@@ -0,0 +1,49 @@+{-# language ConstraintKinds #-}+{-# language MultiParamTypeClasses #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.Core.Types.Rect+  ( Rect+  , HRect(..)++  , RectPoint+  , RectSize+  , IsRect(..)++  , Rect2i+  , Rect2f+  , Rect2d++  , fmapRect+  ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types+import qualified "inline-c"     Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C ( using )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Rect+import "this" OpenCV.Internal.Core.Types.Rect.TH++--------------------------------------------------------------------------------++C.context openCvCtx+C.include "opencv2/core.hpp"+C.using "namespace cv"++mkRectType "Rect2i" ''Int32   "int32_t" "Point2i" "Size2i"+mkRectType "Rect2f" ''CFloat  "float"   "Point2f" "Size2f"+mkRectType "Rect2d" ''CDouble "double"  "Point2d" "Size2d"++fmapRect :: forall a b. (IsRect Rect a, IsRect HRect a, IsRect Rect b, IsRect HRect b)+   => (a -> b) -> Rect a -> Rect b+fmapRect f r = toRect hrB+  where+    hrA :: HRect a+    hrA = fromRect r++    hrB :: HRect b+    hrB = fmap f hrA
+ src/OpenCV/Core/Types/Size.cpp view
@@ -0,0 +1,118 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Size_0_32bf1f9fa11367334eb5e82acfd147a8e7f79ecc(Size2i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Size2i * inline_c_OpenCV_Core_Types_Size_1_64a321c7dd7b04eb97b84811b17e53cf6b27f617(int32_t width_inline_c_0, int32_t height_inline_c_1) {+return ( new cv::Size_<int32_t>(width_inline_c_0, height_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_2_c63519756fa60c6fdd2a694874215def881d038c(Size2i * sizePtr_inline_c_0, int32_t * widthPtr_inline_c_1, int32_t * heightPtr_inline_c_2) {+const cv::Size_<int32_t> & p = *sizePtr_inline_c_0;+*widthPtr_inline_c_1 = p.width;+*heightPtr_inline_c_2 = p.height;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_3_859419933e0232667597f4884e13d5916280981d(Size2i * dst_inline_c_0, Size2i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Size2i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_4_616eab004b2b554610add9842ce37a509c4c82fc(Size2i * ptr_inline_c_0) {+ ptr_inline_c_0->~Size2i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_5_b7958046176feafd41be4accec7a556438e5c3fb(Size2f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Size2f * inline_c_OpenCV_Core_Types_Size_6_a3e9dfac9a56d9141c6c24fa3f71e551bbf998e9(float width_inline_c_0, float height_inline_c_1) {+return ( new cv::Size_<float>(width_inline_c_0, height_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_7_27a41d9b7beb05a85456d0e5ffe48adc69009d43(Size2f * sizePtr_inline_c_0, float * widthPtr_inline_c_1, float * heightPtr_inline_c_2) {+const cv::Size_<float> & p = *sizePtr_inline_c_0;+*widthPtr_inline_c_1 = p.width;+*heightPtr_inline_c_2 = p.height;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_8_03a67537d8ac66ecd30c1f281952bef45fd2a630(Size2f * dst_inline_c_0, Size2f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Size2f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_9_60b3405b2dd407e91e6b7aaf545f5626d14e36a2(Size2f * ptr_inline_c_0) {+ ptr_inline_c_0->~Size2f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_10_5bf047e657221b4c0c4239926d71df74082493e9(Size2d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Size2d * inline_c_OpenCV_Core_Types_Size_11_4bfe7c6c8a1760cc3ce046e944838d75fd8b7287(double width_inline_c_0, double height_inline_c_1) {+return ( new cv::Size_<double>(width_inline_c_0, height_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_12_d48c98941fac6f4bb7860cc21ff084e932c30dd2(Size2d * sizePtr_inline_c_0, double * widthPtr_inline_c_1, double * heightPtr_inline_c_2) {+const cv::Size_<double> & p = *sizePtr_inline_c_0;+*widthPtr_inline_c_1 = p.width;+*heightPtr_inline_c_2 = p.height;++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_13_c75b0ea696663c9ab3d8fdebfddbeb41c3057c0a(Size2d * dst_inline_c_0, Size2d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Size2d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Size_14_da100e8455f8f216556ea391bb42864390e1cd4d(Size2d * ptr_inline_c_0) {+ ptr_inline_c_0->~Size2d() ;+}++}
+ src/OpenCV/Core/Types/Size.hs view
@@ -0,0 +1,30 @@+{-# language MultiParamTypeClasses #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.Core.Types.Size+    ( Size+    , IsSize(..)++    , Size2i, Size2f, Size2d+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types+import qualified "inline-c"     Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C ( using )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Size+import "this" OpenCV.Internal.Core.Types.Size.TH++--------------------------------------------------------------------------------++C.context openCvCtx+C.include "opencv2/core.hpp"+C.using "namespace cv"++mkSizeType "Size2i" ''Int32   "int32_t"+mkSizeType "Size2f" ''CFloat  "float"+mkSizeType "Size2d" ''CDouble "double"
+ src/OpenCV/Core/Types/Vec.cpp view
@@ -0,0 +1,355 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_0_bd90a53d8e34a42571859deb4c1c0e490fa468b8(Vec2i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec2i * inline_c_OpenCV_Core_Types_Vec_1_c2682acbcc1e690f6a479e8e291fc4690d615c30(int32_t x_inline_c_0, int32_t y_inline_c_1) {+return ( new cv::Vec<int32_t, 2>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_2_814334e0438e1a63b54e6ce83f624f4dc7fd474e(Vec2i * vecPtr_inline_c_0, int32_t * xPtr_inline_c_1, int32_t * yPtr_inline_c_2) {+const cv::Vec<int32_t, 2> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_3_1b970fea639df1aeaf8bd626cd353748a703276e(Vec2i * dst_inline_c_0, Vec2i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec2i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_4_c17782ca3797c35a642af252c7e4bd52d9efd365(Vec2i * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec2i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_5_369fbba76e661422a46c2986f4908b94895d571d(Vec2f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec2f * inline_c_OpenCV_Core_Types_Vec_6_eb9b40a7a6c5fb414b3020b78f02b3c90004abf7(float x_inline_c_0, float y_inline_c_1) {+return ( new cv::Vec<float, 2>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_7_ca623c450ec9e141c47884040ebcc00c5b39e8fe(Vec2f * vecPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2) {+const cv::Vec<float, 2> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_8_acab7dd6947550a11cfd5ee94f9e199615f00762(Vec2f * dst_inline_c_0, Vec2f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec2f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_9_a72a0b0c10755846aba8f382352136fbe20b50d6(Vec2f * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec2f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_10_54ac694dca066ae202393ad3b0d96f824a537a1f(Vec2d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec2d * inline_c_OpenCV_Core_Types_Vec_11_ef593eb9f46ebe6f548568269aa0d20bcc874fed(double x_inline_c_0, double y_inline_c_1) {+return ( new cv::Vec<double, 2>(x_inline_c_0, y_inline_c_1) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_12_36e65dd7a90fe56c8b42fdcef0fc5946df532d88(Vec2d * vecPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2) {+const cv::Vec<double, 2> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_13_dda485106eea8b62ce7328b30643852cf11391e6(Vec2d * dst_inline_c_0, Vec2d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec2d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_14_46ee73b43db2a74615ca8ef8854087e026861c3d(Vec2d * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec2d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_15_f8335ca02691a51ad1e76c686cd563027ba3628d(Vec3i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec3i * inline_c_OpenCV_Core_Types_Vec_16_d97c555fbf19006c0ce54a8e8edcb90a88c6e756(int32_t x_inline_c_0, int32_t y_inline_c_1, int32_t z_inline_c_2) {+return ( new cv::Vec<int32_t, 3>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_17_b490915472cc80580674c67d463d04c645fb5462(Vec3i * vecPtr_inline_c_0, int32_t * xPtr_inline_c_1, int32_t * yPtr_inline_c_2, int32_t * zPtr_inline_c_3) {+const cv::Vec<int32_t, 3> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_18_1c6668c2bd1f3bb11d1fc2e84d75c51853fc4b86(Vec3i * dst_inline_c_0, Vec3i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec3i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_19_109e1ab1fb029dd161d06ce89250d921c1128978(Vec3i * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec3i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_20_91b908cfeae8b98203b8bd531742626ff5f53c8a(Vec3f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec3f * inline_c_OpenCV_Core_Types_Vec_21_fa060470dc508d0bb9bd79b6168cfefe45fcc0da(float x_inline_c_0, float y_inline_c_1, float z_inline_c_2) {+return ( new cv::Vec<float, 3>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_22_94daa5083f78a31e98a081ce12989a4b37694858(Vec3f * vecPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2, float * zPtr_inline_c_3) {+const cv::Vec<float, 3> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_23_abdda6f78559aaa967a2b2cdba3d1e324b5b289d(Vec3f * dst_inline_c_0, Vec3f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec3f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_24_868135adcc75b3b5515e158b86191f31669f0803(Vec3f * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec3f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_25_c17e46388d705916ce3f180f18dc95cb19548894(Vec3d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec3d * inline_c_OpenCV_Core_Types_Vec_26_cbfdfd5c790d4b8aca9e5fac0905d17790bc3959(double x_inline_c_0, double y_inline_c_1, double z_inline_c_2) {+return ( new cv::Vec<double, 3>(x_inline_c_0, y_inline_c_1, z_inline_c_2) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_27_927fe079641601dfdf2e5a033f8fc5f3cb33357e(Vec3d * vecPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2, double * zPtr_inline_c_3) {+const cv::Vec<double, 3> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_28_7afa319750c112112ecf5695bc47cb94796d9871(Vec3d * dst_inline_c_0, Vec3d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec3d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_29_d14b2318148691baf560aa7586c48a98d5f9ba71(Vec3d * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec3d() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_30_80a659ecf510418217b7a41de2100e08300fed62(Vec4i * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec4i * inline_c_OpenCV_Core_Types_Vec_31_0ae99afb6a03e793d17c781a872bf1be8306c8e1(int32_t x_inline_c_0, int32_t y_inline_c_1, int32_t z_inline_c_2, int32_t w_inline_c_3) {+return ( new cv::Vec<int32_t, 4>(x_inline_c_0, y_inline_c_1, z_inline_c_2, w_inline_c_3) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_32_c34ce15118daef551bdae306fcefb01334cd6b39(Vec4i * vecPtr_inline_c_0, int32_t * xPtr_inline_c_1, int32_t * yPtr_inline_c_2, int32_t * zPtr_inline_c_3, int32_t * wPtr_inline_c_4) {+const cv::Vec<int32_t, 4> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];+*wPtr_inline_c_4 = p[3];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_33_22c2d27a5f24fcbcf39421501b19c458d49bb6f3(Vec4i * dst_inline_c_0, Vec4i * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec4i(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_34_9b9e5cbd6edcf7f4ee49a222b137eb6c46b92fdf(Vec4i * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec4i() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_35_9760fbae2ee6131b7974b26f37ad96908668d70f(Vec4f * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec4f * inline_c_OpenCV_Core_Types_Vec_36_d7c59efd631649caf759aaa2dc180e73011f6e93(float x_inline_c_0, float y_inline_c_1, float z_inline_c_2, float w_inline_c_3) {+return ( new cv::Vec<float, 4>(x_inline_c_0, y_inline_c_1, z_inline_c_2, w_inline_c_3) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_37_d38530096dcc50e4a3786ffaf9fd81ddc3bc8e03(Vec4f * vecPtr_inline_c_0, float * xPtr_inline_c_1, float * yPtr_inline_c_2, float * zPtr_inline_c_3, float * wPtr_inline_c_4) {+const cv::Vec<float, 4> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];+*wPtr_inline_c_4 = p[3];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_38_f6a12031e0f6f6332384d5179f7e1889d1277ecd(Vec4f * dst_inline_c_0, Vec4f * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec4f(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_39_f50abbe64a09c89abb4c1890256cfaf4eb75d2c4(Vec4f * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec4f() ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_40_71e0c612f928c42e0d9bf1653d0e9f861bbc6cf1(Vec4d * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+Vec4d * inline_c_OpenCV_Core_Types_Vec_41_e33402e2b80c6e38e230ec4148770e0e95684837(double x_inline_c_0, double y_inline_c_1, double z_inline_c_2, double w_inline_c_3) {+return ( new cv::Vec<double, 4>(x_inline_c_0, y_inline_c_1, z_inline_c_2, w_inline_c_3) );+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_42_e6588cf44cf5ec6d83f4b4734b1c3273e90ad581(Vec4d * vecPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2, double * zPtr_inline_c_3, double * wPtr_inline_c_4) {+const cv::Vec<double, 4> & p = *vecPtr_inline_c_0;+*xPtr_inline_c_1 = p[0];+*yPtr_inline_c_2 = p[1];+*zPtr_inline_c_3 = p[2];+*wPtr_inline_c_4 = p[3];++}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_43_5363c43cb6c2a163c53acab25538fc4e19d61cda(Vec4d * dst_inline_c_0, Vec4d * src_inline_c_1) {+ new(dst_inline_c_0) cv::Vec4d(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Core_Types_Vec_44_0a476e8310288423c9baf620a098c92b7174c847(Vec4d * ptr_inline_c_0) {+ ptr_inline_c_0->~Vec4d() ;+}++}
+ src/OpenCV/Core/Types/Vec.hs view
@@ -0,0 +1,42 @@+{-# language ConstraintKinds #-}+{-# language MultiParamTypeClasses #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.Core.Types.Vec+    ( Vec+    , VecDim+    , IsVec(..)++    , Vec2i, Vec2f, Vec2d+    , Vec3i, Vec3f, Vec3d+    , Vec4i, Vec4f, Vec4d+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types+import qualified "inline-c"     Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C ( using )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Vec+import "this" OpenCV.Internal.Core.Types.Vec.TH++--------------------------------------------------------------------------------++C.context openCvCtx+C.include "opencv2/core.hpp"+C.using "namespace cv"++mkVecType "Vec2i" 2 ''Int32   "int32_t"+mkVecType "Vec2f" 2 ''CFloat  "float"+mkVecType "Vec2d" 2 ''CDouble "double"++mkVecType "Vec3i" 3 ''Int32   "int32_t"+mkVecType "Vec3f" 3 ''CFloat  "float"+mkVecType "Vec3d" 3 ''CDouble "double"++mkVecType "Vec4i" 4 ''Int32   "int32_t"+mkVecType "Vec4f" 4 ''CFloat  "float"+mkVecType "Vec4d" 4 ''CDouble "double"
+ src/OpenCV/Exception.hs view
@@ -0,0 +1,24 @@+{-# language DeriveFunctor #-}+{-# language QuasiQuotes #-}+{-# language RankNTypes #-}+{-# language TemplateHaskell #-}++module OpenCV.Exception+    ( -- * Exception type+      CvException(..)+    , CoerceMatError(..)+    , ExpectationError(..)+    , CvCppException++      -- * Monadic interface+    , CvExcept+    , CvExceptT+    , pureExcept++      -- * Promoting exceptions to errors+    , exceptError+    , exceptErrorIO+    , exceptErrorM+    ) where++import "this" OpenCV.Internal.Exception
+ src/OpenCV/Features2d.cpp view
@@ -0,0 +1,371 @@++#include "opencv2/core.hpp"++#include "opencv2/features2d.hpp"++#include "orb.hpp"++#include "simple_blob_detector.hpp"++using namespace cv;++using namespace cv::flann;++extern "C" {+void inline_c_OpenCV_Features2d_0_c20526c404a6fe4a0e071193ba0c68f0b5fe2c85(Mat * trainVecPtr_inline_c_0, Mat * trainVecPtr_inline_c_1, int32_t ctrainVecLength_27_inline_c_2, DescriptorMatcher * dmPtr_inline_c_3) {++                std::vector<Mat> buffer( trainVecPtr_inline_c_0+                                       , trainVecPtr_inline_c_1 + ctrainVecLength_27_inline_c_2 );+                dmPtr_inline_c_3->add(buffer);+            +}++}++extern "C" {+void inline_c_OpenCV_Features2d_1_2813de60614f1b2e1d0142d271069dc9106fb99d(DescriptorMatcher * dmPtr_inline_c_0) {+ dmPtr_inline_c_0->train(); +}++}++extern "C" {+void inline_c_OpenCV_Features2d_2_3de0409117ca129a76f8d5b6e877199877ed9bf5(Mat * maskPtr_inline_c_0, DescriptorMatcher * dmPtr_inline_c_1, Mat * queryPtr_inline_c_2, Mat * trainPtr_inline_c_3, int32_t * numMatchesPtr_inline_c_4, DMatch *** arrayPtrPtr_inline_c_5) {++                cv::Mat * maskPtr = maskPtr_inline_c_0;+                std::vector<cv::DMatch> matches = std::vector<cv::DMatch>();+                dmPtr_inline_c_1->match+                    ( *queryPtr_inline_c_2+                    , *trainPtr_inline_c_3+                    , matches+                    , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+                    );+                *numMatchesPtr_inline_c_4 = matches.size();+                cv::DMatch * * * arrayPtrPtr = arrayPtrPtr_inline_c_5;+                cv::DMatch * * arrayPtr = new cv::DMatch * [matches.size()];+                *arrayPtrPtr = arrayPtr;+                for (std::vector<cv::DMatch>::size_type ix = 0; ix != matches.size(); ix++)+                {+                    cv::DMatch & org = matches[ix];+                    cv::DMatch * newMatch =+                        new cv::DMatch( org.queryIdx+                                      , org.trainIdx+                                      , org.imgIdx+                                      , org.distance+                                      );+                    arrayPtr[ix] = newMatch;+                }+            +}++}++extern "C" {+void inline_c_OpenCV_Features2d_3_c754e0d048d4bef52c712950b7974557eb9337ca(DMatch *** arrayPtrPtr_inline_c_0) {++                delete [] *arrayPtrPtr_inline_c_0;+            +}++}++extern "C" {+void inline_c_OpenCV_Features2d_4_f81e11a4cba05db7138b02901752eba162a82674(Mat * maskPtr_inline_c_0, DescriptorMatcher * dmPtr_inline_c_1, Mat * queryPtr_inline_c_2, int32_t * numMatchesPtr_inline_c_3, DMatch *** arrayPtrPtr_inline_c_4) {++                cv::Mat * maskPtr = maskPtr_inline_c_0;+                std::vector<cv::DMatch> matches = std::vector<cv::DMatch>();+                dmPtr_inline_c_1->match+                    ( *queryPtr_inline_c_2+                    , matches+                    , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+                    );+                *numMatchesPtr_inline_c_3 = matches.size();+                cv::DMatch * * * arrayPtrPtr = arrayPtrPtr_inline_c_4;+                cv::DMatch * * arrayPtr = new cv::DMatch * [matches.size()];+                *arrayPtrPtr = arrayPtr;+                for (std::vector<cv::DMatch>::size_type ix = 0; ix != matches.size(); ix++)+                {+                    cv::DMatch & org = matches[ix];+                    cv::DMatch * newMatch =+                        new cv::DMatch( org.queryIdx+                                      , org.trainIdx+                                      , org.imgIdx+                                      , org.distance+                                      );+                    arrayPtr[ix] = newMatch;+                }+            +}++}++extern "C" {+void inline_c_OpenCV_Features2d_5_c754e0d048d4bef52c712950b7974557eb9337ca(DMatch *** arrayPtrPtr_inline_c_0) {++                delete [] *arrayPtrPtr_inline_c_0;+            +}++}++extern "C" {+Ptr_ORB * inline_c_OpenCV_Features2d_6_6b7f5143762c2c000af552afd3a3d686bdefea20(int32_t orb_nfeatures_inline_c_0, float cscaleFactor_27_inline_c_1, int32_t orb_nlevels_inline_c_2, int32_t orb_edgeThreshold_inline_c_3, int32_t orb_firstLevel_inline_c_4, int32_t cWTA_K_27_inline_c_5, int32_t cscoreType_27_inline_c_6, int32_t orb_patchSize_inline_c_7, int32_t orb_fastThreshold_inline_c_8) {++      cv::Ptr<cv::ORB> orbPtr =+        cv::ORB::create+        ( orb_nfeatures_inline_c_0+        , cscaleFactor_27_inline_c_1+        , orb_nlevels_inline_c_2+        , orb_edgeThreshold_inline_c_3+        , orb_firstLevel_inline_c_4+        , cWTA_K_27_inline_c_5+        , cscoreType_27_inline_c_6+        , orb_patchSize_inline_c_7+        , orb_fastThreshold_inline_c_8+        );+      return new cv::Ptr<cv::ORB>(orbPtr);+    +}++}++extern "C" {+Exception * inline_c_OpenCV_Features2d_7_ab5c3c7294768d603136931b15d35c34105db400(Ptr_ORB * orbPtr_inline_c_0, Mat * maskPtr_inline_c_1, Mat * imgPtr_inline_c_2, Mat * descPtr_inline_c_3, int32_t * numPtsPtr_inline_c_4, KeyPoint *** arrayPtrPtr_inline_c_5) {++  try+  {   +          cv::ORB * orb = *orbPtr_inline_c_0;+          cv::Mat * maskPtr = maskPtr_inline_c_1;++          std::vector<cv::KeyPoint> keypoints = std::vector<cv::KeyPoint>();+          orb->+            detectAndCompute+            ( *imgPtr_inline_c_2+            , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+            , keypoints+            , *descPtr_inline_c_3+            , false+            );++          *numPtsPtr_inline_c_4 = keypoints.size();++          cv::KeyPoint * * * arrayPtrPtr = arrayPtrPtr_inline_c_5;+          cv::KeyPoint * * arrayPtr = new cv::KeyPoint * [keypoints.size()];+          *arrayPtrPtr = arrayPtr;++          for (std::vector<cv::KeyPoint>::size_type ix = 0; ix != keypoints.size(); ix++)+          {+            cv::KeyPoint & org = keypoints[ix];+            cv::KeyPoint * newPt =+              new cv::KeyPoint( org.pt+                              , org.size+                              , org.angle+                              , org.response+                              , org.octave+                              , org.class_id+                              );+            arrayPtr[ix] = newPt;+          }+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Features2d_8_cf7ed8abd0aadc595f02b1ca9ec2ba13285a12cd(KeyPoint *** arrayPtrPtr_inline_c_0) {++            delete [] *arrayPtrPtr_inline_c_0;+          +}++}++extern "C" {+Ptr_SimpleBlobDetector * inline_c_OpenCV_Features2d_9_6d49cdf958cb32caa9373b05297fc3fae472250c(unsigned char cblobColor_27_inline_c_0, bool cfilterByArea_27_inline_c_1, bool cfilterByCircularity_27_inline_c_2, bool cfilterByColor_27_inline_c_3, bool cfilterByConvexity_27_inline_c_4, bool cfilterByInertia_27_inline_c_5, float cmaxArea_27_inline_c_6, float cmaxCircularity_27_inline_c_7, float cmaxConvexity_27_inline_c_8, float cmaxInertiaRatio_27_inline_c_9, float cmaxThreshold_27_inline_c_10, float cminArea_27_inline_c_11, float cminCircularity_27_inline_c_12, float cminConvexity_27_inline_c_13, float cminDistBetweenBlobs_27_inline_c_14, float cminInertiaRatio_27_inline_c_15, float cminRepeatability_27_inline_c_16, float cminThreshold_27_inline_c_17, float cthresholdStep_27_inline_c_18) {++      cv::SimpleBlobDetector::Params params;+      params.blobColor           = cblobColor_27_inline_c_0;+      params.filterByArea        = cfilterByArea_27_inline_c_1;+      params.filterByCircularity = cfilterByCircularity_27_inline_c_2;+      params.filterByColor       = cfilterByColor_27_inline_c_3;+      params.filterByConvexity   = cfilterByConvexity_27_inline_c_4;+      params.filterByInertia     = cfilterByInertia_27_inline_c_5;+      params.maxArea             = cmaxArea_27_inline_c_6;+      params.maxCircularity      = cmaxCircularity_27_inline_c_7;+      params.maxConvexity        = cmaxConvexity_27_inline_c_8;+      params.maxInertiaRatio     = cmaxInertiaRatio_27_inline_c_9;+      params.maxThreshold        = cmaxThreshold_27_inline_c_10;+      params.minArea             = cminArea_27_inline_c_11;+      params.minCircularity      = cminCircularity_27_inline_c_12;+      params.minConvexity        = cminConvexity_27_inline_c_13;+      params.minDistBetweenBlobs = cminDistBetweenBlobs_27_inline_c_14;+      params.minInertiaRatio     = cminInertiaRatio_27_inline_c_15;+      params.minRepeatability    = cminRepeatability_27_inline_c_16;+      params.minThreshold        = cminThreshold_27_inline_c_17;+      params.thresholdStep       = cthresholdStep_27_inline_c_18;+      cv::Ptr<cv::SimpleBlobDetector> detectorPtr =+        cv::SimpleBlobDetector::create(params);+      return new cv::Ptr<cv::SimpleBlobDetector>(detectorPtr);+    +}++}++extern "C" {+Exception * inline_c_OpenCV_Features2d_10_d7dbc50e18a0ed3c0249b015e18a47ba992cc422(Ptr_SimpleBlobDetector * detectorPtr_inline_c_0, Mat * maskPtr_inline_c_1, Mat * imgPtr_inline_c_2, int32_t * numPtsPtr_inline_c_3, KeyPoint *** arrayPtrPtr_inline_c_4) {++  try+  {   +          cv::SimpleBlobDetector * detector = *detectorPtr_inline_c_0;+          cv::Mat * maskPtr = maskPtr_inline_c_1;++          std::vector<cv::KeyPoint> keypoints = std::vector<cv::KeyPoint>();+          detector->+            detect+            ( *imgPtr_inline_c_2+            , keypoints+            , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+            );++          *numPtsPtr_inline_c_3 = keypoints.size();++          cv::KeyPoint * * * arrayPtrPtr = arrayPtrPtr_inline_c_4;+          cv::KeyPoint * * arrayPtr = new cv::KeyPoint * [keypoints.size()];+          *arrayPtrPtr = arrayPtr;++          for (std::vector<cv::KeyPoint>::size_type ix = 0; ix != keypoints.size(); ix++)+          {+            arrayPtr[ix] = new cv::KeyPoint(keypoints[ix]);+          }+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Features2d_11_cf7ed8abd0aadc595f02b1ca9ec2ba13285a12cd(KeyPoint *** arrayPtrPtr_inline_c_0) {++            delete [] *arrayPtrPtr_inline_c_0;+          +}++}++extern "C" {+BFMatcher * inline_c_OpenCV_Features2d_12_3d629b7d8af2ebe2d28b0b1fe498acf0062a5280(int32_t cnormType_27_inline_c_0, bool ccrossCheck_27_inline_c_1) {+return (+      new cv::BFMatcher+          ( cnormType_27_inline_c_0+          , ccrossCheck_27_inline_c_1+          )+    );+}++}++extern "C" {+void * inline_c_OpenCV_Features2d_13_0d213c0657123ccc4d29cdc7303c0b69c02d5fda(int32_t ctree_27_inline_c_0) {+return ( new flann::KDTreeIndexParams(ctree_27_inline_c_0) );+}++}++extern "C" {+void * inline_c_OpenCV_Features2d_14_2c184908ffa3530071446466c17650df005901f2(int32_t ctableNumber_27_inline_c_0, int32_t ckeySize_27_inline_c_1, int32_t cmultiProbeLevel_27_inline_c_2) {+return ( new cv::flann::LshIndexParams(ctableNumber_27_inline_c_0, ckeySize_27_inline_c_1, cmultiProbeLevel_27_inline_c_2) );+}++}++extern "C" {+void * inline_c_OpenCV_Features2d_15_f616e207428e82c732ad58557798246008ce8ba8(int32_t cchecks_27_inline_c_0, float ceps_27_inline_c_1, bool csorted_27_inline_c_2) {+return ( new cv::flann::SearchParams(cchecks_27_inline_c_0, ceps_27_inline_c_1, csorted_27_inline_c_2) );+}++}++extern "C" {+FlannBasedMatcher * inline_c_OpenCV_Features2d_16_6b8b6e4917570b136dfcc14b4750c0f143a658dd(void * cindexParams_27_inline_c_0, void * csearchParams_27_inline_c_1) {+return (+      new cv::FlannBasedMatcher((flann::IndexParams*)(cindexParams_27_inline_c_0), (flann::SearchParams*)(csearchParams_27_inline_c_1))+    );+}++}++extern "C" {+Exception * inline_c_OpenCV_Features2d_17_9769634ffcfe6b2423aca319c5ed479323f9a54a(KeyPoint * kps1Ptr_inline_c_0, KeyPoint * kps1Ptr_inline_c_1, int32_t ckps1Length_27_inline_c_2, KeyPoint * kps2Ptr_inline_c_3, KeyPoint * kps2Ptr_inline_c_4, int32_t ckps2Length_27_inline_c_5, DMatch * mt12Ptr_inline_c_6, DMatch * mt12Ptr_inline_c_7, int32_t cmatches1to2Length_27_inline_c_8, Mat * img1Ptr_inline_c_9, Mat * img2Ptr_inline_c_10, Mat * outImgPtr_inline_c_11) {++  try+  {   +                std::vector<KeyPoint> kps1(kps1Ptr_inline_c_0, kps1Ptr_inline_c_1 + ckps1Length_27_inline_c_2);+                std::vector<KeyPoint> kps2(kps2Ptr_inline_c_3, kps2Ptr_inline_c_4 + ckps2Length_27_inline_c_5);+                std::vector<DMatch>   mt12(mt12Ptr_inline_c_6,   mt12Ptr_inline_c_7 + cmatches1to2Length_27_inline_c_8);+                drawMatches(+                    *img1Ptr_inline_c_9,+                    kps1,+                    *img2Ptr_inline_c_10,+                    kps2,+                    mt12,+                    *outImgPtr_inline_c_11);+            +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Features2d_18_6765b7d0bd3bbad57c755d54daef3014c487f076(FlannBasedMatcher * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Features2d_19_4d27bc77ab4560f842e67bc6c3296c78e8185def(BFMatcher * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Features2d_20_33d1ad332669dd8a8debec52f30c332c6ecaca71(Ptr_SimpleBlobDetector * ptr_inline_c_0) {++                  cv::Ptr<cv::SimpleBlobDetector> * simpleBlobDetector_ptr_ptr = ptr_inline_c_0;+                  simpleBlobDetector_ptr_ptr->release();+                  delete simpleBlobDetector_ptr_ptr;+                +}++}++extern "C" {+void inline_c_OpenCV_Features2d_21_ed7595b29d7e25c46f90b240e3eaf60bd8a0e85f(Ptr_ORB * ptr_inline_c_0) {++                  cv::Ptr<cv::ORB> * orb_ptr_ptr = ptr_inline_c_0;+                  orb_ptr_ptr->release();+                  delete orb_ptr_ptr;+                +}++}
+ src/OpenCV/Features2d.hsc view
@@ -0,0 +1,952 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RecordWildCards #-}++module OpenCV.Features2d+    ( -- * ORB+      Orb+    , OrbScoreType(..)+    , WTA_K(..)+    , OrbParams(..)+    , defaultOrbParams+    , mkOrb+    , orbDetectAndCompute++      -- * BLOB+    , SimpleBlobDetector+    , SimpleBlobDetectorParams(..)+    , BlobFilterByArea(..)+    , BlobFilterByCircularity(..)+    , BlobFilterByColor(..)+    , BlobFilterByConvexity(..)+    , BlobFilterByInertia(..)+    , defaultSimpleBlobDetectorParams+    , mkSimpleBlobDetector+    , blobDetect++      -- * DescriptorMatcher+    , DescriptorMatcher(..)+    , drawMatches+      -- ** BFMatcher+    , BFMatcher+    , newBFMatcher+      -- ** FlannBasedMatcher+    , FlannBasedMatcher+    , FlannIndexParams(..)+    , FlannSearchParams(..)+    , FlannBasedMatcherParams(..)+    , newFlannBasedMatcher+    ) where++import "base" Control.Exception ( mask_ )+import "base" Data.Int+import "base" Data.Word+import "base" Data.Maybe+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr, castForeignPtr )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( peekArray )+import "base" Foreign.Marshal.Utils ( fromBool )+import "base" Foreign.Ptr ( Ptr, nullPtr )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import "data-default" Data.Default+import "linear" Linear.V4+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.ArrayOps+import "this" OpenCV.Internal.Core.Types ( withArrayPtr, Scalar )+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception ( cvExcept, unsafeWrapException, handleCvException )+import "this" OpenCV.TypeLevel+import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/features2d.hpp"+C.include "orb.hpp"+C.include "simple_blob_detector.hpp"++C.using "namespace cv"+C.using "namespace cv::flann"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/features2d.hpp"++#include "namespace.hpp"+#include "orb.hpp"+#include "simple_blob_detector.hpp"++infinity :: Float+infinity = 1 / 0++--------------------------------------------------------------------------------+-- ORB - Oriented BRIEF+--------------------------------------------------------------------------------++-- Internally, an Orb is a pointer to a @cv::Ptr<cv::ORB>@, which in turn points+-- to an actual @cv::ORB@ object.+newtype Orb = Orb {unOrb :: ForeignPtr C'Ptr_ORB}++type instance C Orb = C'Ptr_ORB++instance WithPtr Orb where+    withPtr = withForeignPtr . unOrb++instance FromPtr Orb where+    fromPtr = objFromPtr Orb $ \ptr ->+                [CU.block| void {+                  cv::Ptr<cv::ORB> * orb_ptr_ptr = $(Ptr_ORB * ptr);+                  orb_ptr_ptr->release();+                  delete orb_ptr_ptr;+                }|]++--------------------------------------------------------------------------------++data WTA_K+   = WTA_K_2+   | WTA_K_3+   | WTA_K_4++marshalWTA_K :: WTA_K -> Int32+marshalWTA_K = \case+    WTA_K_2 -> 2+    WTA_K_3 -> 3+    WTA_K_4 -> 4++data OrbScoreType+   = HarrisScore+   | FastScore++#num HARRIS_SCORE+#num FAST_SCORE++marshalOrbScoreType :: OrbScoreType -> Int32+marshalOrbScoreType = \case+    HarrisScore -> c'HARRIS_SCORE+    FastScore   -> c'FAST_SCORE++data OrbParams+   = OrbParams+     { orb_nfeatures :: !Int32+       -- ^ The maximum number of features to retain.+     , orb_scaleFactor :: !Float+       -- ^ Pyramid decimation ratio, greater than 1. 'orb_scaleFactor' == 2+       -- means the classical pyramid, where each next level has 4x less pixels+       -- than the previous, but such a big scale factor will degrade feature+       -- matching scores dramatically. On the other hand, too close to 1 scale+       -- factor will mean that to cover certain scale range you will need more+       -- pyramid levels and so the speed will suffer.+     , orb_nlevels :: !Int32+       -- ^ The number of pyramid levels. The smallest level will have linear+       -- size equal to input_image_linear_size / 'orb_scaleFactor' **+       -- 'orb_nlevels'.+     , orb_edgeThreshold :: !Int32+       -- ^ This is size of the border where the features are not detected. It+       -- should roughly match the patchSize parameter.+     , orb_firstLevel :: !Int32+       -- ^ It should be 0 in the current implementation.+     , orb_WTA_K :: !WTA_K+       -- ^ The number of points that produce each element of the oriented BRIEF+       -- descriptor. The default value 'WTA_K_2' means the BRIEF where we take+       -- a random point pair and compare their brightnesses, so we get 0/1+       -- response. Other possible values are 'WTA_K_3' and 'WTA_K_4'. For+       -- example, 'WTA_K_3' means that we take 3 random points (of course,+       -- those point coordinates are random, but they are generated from the+       -- pre-defined seed, so each element of BRIEF descriptor is computed+       -- deterministically from the pixel rectangle), find point of maximum+       -- brightness and output index of the winner (0, 1 or 2). Such output+       -- will occupy 2 bits, and therefore it will need a special variant of+       -- Hamming distance, denoted as 'Norm_Hamming2' (2 bits per bin). When+       -- 'WTA_K_4', we take 4 random points to compute each bin (that will also+       -- occupy 2 bits with possible values 0, 1, 2 or 3).+     , orb_scoreType :: !OrbScoreType+       -- ^ The default 'HarrisScore' means that Harris algorithm is used to+       -- rank features (the score is written to KeyPoint::score and is used to+       -- retain best nfeatures features); 'FastScore' is alternative value of+       -- the parameter that produces slightly less stable keypoints, but it is+       -- a little faster to compute.+     , orb_patchSize :: !Int32+       -- ^ Size of the patch used by the oriented BRIEF descriptor. Of course,+       -- on smaller pyramid layers the perceived image area covered by a+       -- feature will be larger.+     , orb_fastThreshold :: !Int32+     }++defaultOrbParams :: OrbParams+defaultOrbParams =+    OrbParams+     { orb_nfeatures     = 500+     , orb_scaleFactor   = 1.2+     , orb_nlevels       = 8+     , orb_edgeThreshold = 31+     , orb_firstLevel    = 0+     , orb_WTA_K         = WTA_K_2+     , orb_scoreType     = HarrisScore+     , orb_patchSize     = 31+     , orb_fastThreshold = 20+     }++--------------------------------------------------------------------------------++newOrb :: OrbParams -> IO Orb+newOrb OrbParams{..} = fromPtr+    [CU.block|Ptr_ORB * {+      cv::Ptr<cv::ORB> orbPtr =+        cv::ORB::create+        ( $(int32_t orb_nfeatures)+        , $(float   c'scaleFactor)+        , $(int32_t orb_nlevels)+        , $(int32_t orb_edgeThreshold)+        , $(int32_t orb_firstLevel)+        , $(int32_t c'WTA_K)+        , $(int32_t c'scoreType)+        , $(int32_t orb_patchSize)+        , $(int32_t orb_fastThreshold)+        );+      return new cv::Ptr<cv::ORB>(orbPtr);+    }|]+  where+    c'scaleFactor = realToFrac orb_scaleFactor+    c'WTA_K       = marshalWTA_K        orb_WTA_K+    c'scoreType   = marshalOrbScoreType orb_scoreType++mkOrb :: OrbParams -> Orb+mkOrb = unsafePerformIO . newOrb++--------------------------------------------------------------------------------++{- | Detect keypoints and compute descriptors++Example:++@+orbDetectAndComputeImg+    :: forall (width    :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog)+    => Mat (ShapeT [height, width]) ('S channels) ('S depth)+orbDetectAndComputeImg = exceptError $ do+    (kpts, _descs) <- orbDetectAndCompute orb frog Nothing+    withMatM (Proxy :: Proxy [height, width])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      void $ matCopyToM imgM (V2 0 0) frog Nothing+      forM_ kpts $ \\kpt -> do+        let kptRec = keyPointAsRec kpt+        circle imgM (round \<$> kptPoint kptRec :: V2 Int32) 5 blue 1 LineType_AA 0+  where+    orb = mkOrb defaultOrbParams+@++<<doc/generated/examples/orbDetectAndComputeImg.png orbDetectAndComputeImg>>+-}+orbDetectAndCompute+    :: Orb+    -> Mat ('S [height, width]) channels depth -- ^ Image.+    -> Maybe (Mat ('S [height, width]) ('S 1) ('S Word8)) -- ^ Mask.+    -> CvExcept ( V.Vector KeyPoint+                , Mat 'D 'D 'D+                )+orbDetectAndCompute orb img mbMask = unsafeWrapException $ do+    descriptors <- newEmptyMat+    withPtr orb $ \orbPtr ->+      withPtr img $ \imgPtr ->+      withPtr mbMask $ \maskPtr ->+      withPtr descriptors $ \descPtr ->+      alloca $ \(numPtsPtr :: Ptr Int32) ->+      alloca $ \(arrayPtrPtr :: Ptr (Ptr (Ptr C'KeyPoint))) -> mask_ $ do+        ptrException <- [cvExcept|+          cv::ORB * orb = *$(Ptr_ORB * orbPtr);+          cv::Mat * maskPtr = $(Mat * maskPtr);++          std::vector<cv::KeyPoint> keypoints = std::vector<cv::KeyPoint>();+          orb->+            detectAndCompute+            ( *$(Mat * imgPtr)+            , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+            , keypoints+            , *$(Mat * descPtr)+            , false+            );++          *$(int32_t * numPtsPtr) = keypoints.size();++          cv::KeyPoint * * * arrayPtrPtr = $(KeyPoint * * * arrayPtrPtr);+          cv::KeyPoint * * arrayPtr = new cv::KeyPoint * [keypoints.size()];+          *arrayPtrPtr = arrayPtr;++          for (std::vector<cv::KeyPoint>::size_type ix = 0; ix != keypoints.size(); ix++)+          {+            cv::KeyPoint & org = keypoints[ix];+            cv::KeyPoint * newPt =+              new cv::KeyPoint( org.pt+                              , org.size+                              , org.angle+                              , org.response+                              , org.octave+                              , org.class_id+                              );+            arrayPtr[ix] = newPt;+          }+        |]+        if ptrException /= nullPtr+        then Left . BindingException <$> fromPtr (pure ptrException)+        else do+          numPts <- fromIntegral <$> peek numPtsPtr+          arrayPtr <- peek arrayPtrPtr+          keypoints <- mapM (fromPtr . pure) =<< peekArray numPts arrayPtr++          [CU.block| void {+            delete [] *$(KeyPoint * * * arrayPtrPtr);+          }|]++          pure $ Right (V.fromList keypoints, relaxMat descriptors)++--------------------------------------------------------------------------------+-- BLOB - Binary Large OBject+--------------------------------------------------------------------------------++-- Internally, a SimpleBlobDetector is a pointer to a @cv::Ptr<cv::SimpleBlobDetector>@, which in turn points+-- to an actual @cv::SimpleBlobDetector@ object.+newtype SimpleBlobDetector = SimpleBlobDetector {unSimpleBlobDetector :: ForeignPtr C'Ptr_SimpleBlobDetector}++type instance C SimpleBlobDetector = C'Ptr_SimpleBlobDetector++instance WithPtr SimpleBlobDetector where+    withPtr = withForeignPtr . unSimpleBlobDetector++instance FromPtr SimpleBlobDetector where+    fromPtr = objFromPtr SimpleBlobDetector $ \ptr ->+                [CU.block| void {+                  cv::Ptr<cv::SimpleBlobDetector> * simpleBlobDetector_ptr_ptr = $(Ptr_SimpleBlobDetector * ptr);+                  simpleBlobDetector_ptr_ptr->release();+                  delete simpleBlobDetector_ptr_ptr;+                }|]++data BlobFilterByArea+     = BlobFilterByArea+     { blob_minArea :: !Float+     , blob_maxArea :: !Float+     } deriving Eq++data BlobFilterByCircularity+     = BlobFilterByCircularity+     { blob_minCircularity :: !Float+     , blob_maxCircularity :: !Float+     } deriving Eq++data BlobFilterByColor+     = BlobFilterByColor+     { blob_blobColor :: !Word8+     } deriving Eq++data BlobFilterByConvexity+     = BlobFilterByConvexity+     { blob_minConvexity :: !Float+     , blob_maxConvexity :: !Float+     } deriving Eq++data BlobFilterByInertia+     = BlobFilterByInertia+     { blob_minInertiaRatio :: !Float+     , blob_maxInertiaRatio :: !Float+     } deriving Eq++data SimpleBlobDetectorParams+   = SimpleBlobDetectorParams+     { blob_minThreshold :: !Float+     , blob_maxThreshold :: !Float+     , blob_thresholdStep :: !Float+     , blob_minRepeatability :: !Int32+     , blob_minDistBetweenBlobs :: !Float+     , blob_filterByArea :: !(Maybe BlobFilterByArea)+       -- ^ Extracted blobs have an area between 'minArea' (inclusive) and+       --   'maxArea' (exclusive).+     , blob_filterByCircularity :: !(Maybe BlobFilterByCircularity)+       -- ^ Extracted blobs have circularity+       --   @(4 * pi * Area)/(perimeter * perimeter)@ between 'minCircularity'+       --   (inclusive) and 'maxCircularity' (exclusive).+     , blob_filterByColor :: !(Maybe BlobFilterByColor)+       -- ^ This filter compares the intensity of a binary image at the center of+       --   a blob to 'blobColor'. If they differ, the blob is filtered out. Use+       --   @blobColor = 0@ to extract dark blobs and @blobColor = 255@ to extract+       --   light blobs.+     , blob_filterByConvexity :: !(Maybe BlobFilterByConvexity)+       -- ^ Extracted blobs have convexity (area / area of blob convex hull) between+       --   'minConvexity' (inclusive) and 'maxConvexity' (exclusive).+     , blob_filterByInertia :: !(Maybe BlobFilterByInertia)+       -- ^ Extracted blobs have this ratio between 'minInertiaRatio' (inclusive)+       --   and 'maxInertiaRatio' (exclusive).+     }++defaultSimpleBlobDetectorParams :: SimpleBlobDetectorParams+defaultSimpleBlobDetectorParams =+    SimpleBlobDetectorParams+    { blob_minThreshold = 50+    , blob_maxThreshold = 220+    , blob_thresholdStep = 10+    , blob_minRepeatability = 2+    , blob_minDistBetweenBlobs = 10+    , blob_filterByArea = Just (BlobFilterByArea 25 5000)+    , blob_filterByCircularity = Nothing+    , blob_filterByColor = Just (BlobFilterByColor 0)+    , blob_filterByConvexity = Just (BlobFilterByConvexity 0.95 infinity)+    , blob_filterByInertia = Just (BlobFilterByInertia 0.1 infinity)+    }++--------------------------------------------------------------------------------++newSimpleBlobDetector :: SimpleBlobDetectorParams -> IO SimpleBlobDetector+newSimpleBlobDetector SimpleBlobDetectorParams{..} = fromPtr+    [CU.block|Ptr_SimpleBlobDetector * {+      cv::SimpleBlobDetector::Params params;+      params.blobColor           = $(unsigned char c'blobColor);+      params.filterByArea        = $(bool c'filterByArea);+      params.filterByCircularity = $(bool c'filterByCircularity);+      params.filterByColor       = $(bool c'filterByColor);+      params.filterByConvexity   = $(bool c'filterByConvexity);+      params.filterByInertia     = $(bool c'filterByInertia);+      params.maxArea             = $(float c'maxArea);+      params.maxCircularity      = $(float c'maxCircularity);+      params.maxConvexity        = $(float c'maxConvexity);+      params.maxInertiaRatio     = $(float c'maxInertiaRatio);+      params.maxThreshold        = $(float c'maxThreshold);+      params.minArea             = $(float c'minArea);+      params.minCircularity      = $(float c'minCircularity);+      params.minConvexity        = $(float c'minConvexity);+      params.minDistBetweenBlobs = $(float c'minDistBetweenBlobs);+      params.minInertiaRatio     = $(float c'minInertiaRatio);+      params.minRepeatability    = $(float c'minRepeatability);+      params.minThreshold        = $(float c'minThreshold);+      params.thresholdStep       = $(float c'thresholdStep);+      cv::Ptr<cv::SimpleBlobDetector> detectorPtr =+        cv::SimpleBlobDetector::create(params);+      return new cv::Ptr<cv::SimpleBlobDetector>(detectorPtr);+    }|]+  where+    c'minThreshold        = realToFrac blob_minThreshold+    c'maxThreshold        = realToFrac blob_maxThreshold+    c'thresholdStep       = realToFrac blob_thresholdStep+    c'minRepeatability    = realToFrac blob_minRepeatability+    c'minDistBetweenBlobs = realToFrac blob_minDistBetweenBlobs+    c'filterByArea        = fromBool (isJust blob_filterByArea)+    c'filterByCircularity = fromBool (isJust blob_filterByCircularity)+    c'filterByColor       = fromBool (isJust blob_filterByColor)+    c'filterByConvexity   = fromBool (isJust blob_filterByConvexity)+    c'filterByInertia     = fromBool (isJust blob_filterByInertia)+    c'minArea             = realToFrac (fromMaybe 25 (fmap blob_minArea blob_filterByArea))+    c'maxArea             = realToFrac (fromMaybe 5000 (fmap blob_maxArea blob_filterByArea))+    c'minCircularity      = realToFrac (fromMaybe 0.8 (fmap blob_minCircularity blob_filterByCircularity))+    c'maxCircularity      = realToFrac (fromMaybe infinity (fmap blob_maxCircularity blob_filterByCircularity))+    c'blobColor           = fromIntegral (fromMaybe 0 (fmap blob_blobColor blob_filterByColor))+    c'minConvexity        = realToFrac (fromMaybe 0.95 (fmap blob_minConvexity blob_filterByConvexity))+    c'maxConvexity        = realToFrac (fromMaybe infinity (fmap blob_maxConvexity blob_filterByConvexity))+    c'minInertiaRatio     = realToFrac (fromMaybe 0.1 (fmap blob_minInertiaRatio blob_filterByInertia))+    c'maxInertiaRatio     = realToFrac (fromMaybe infinity (fmap blob_maxInertiaRatio blob_filterByInertia))++mkSimpleBlobDetector :: SimpleBlobDetectorParams -> SimpleBlobDetector+mkSimpleBlobDetector = unsafePerformIO . newSimpleBlobDetector++--------------------------------------------------------------------------------++{- | Detect keypoints and compute descriptors+-}+blobDetect+    :: SimpleBlobDetector+    -> Mat ('S [height, width]) channels depth -- ^ Image.+    -> Maybe (Mat ('S [height, width]) ('S 1) ('S Word8)) -- ^ Mask.+    -> CvExcept (V.Vector KeyPoint)+blobDetect detector img mbMask = unsafeWrapException $ do+    withPtr detector $ \detectorPtr ->+      withPtr img $ \imgPtr ->+      withPtr mbMask $ \maskPtr ->+      alloca $ \(numPtsPtr :: Ptr Int32) ->+      alloca $ \(arrayPtrPtr :: Ptr (Ptr (Ptr C'KeyPoint))) -> mask_ $ do+        ptrException <- [cvExcept|+          cv::SimpleBlobDetector * detector = *$(Ptr_SimpleBlobDetector * detectorPtr);+          cv::Mat * maskPtr = $(Mat * maskPtr);++          std::vector<cv::KeyPoint> keypoints = std::vector<cv::KeyPoint>();+          detector->+            detect+            ( *$(Mat * imgPtr)+            , keypoints+            , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+            );++          *$(int32_t * numPtsPtr) = keypoints.size();++          cv::KeyPoint * * * arrayPtrPtr = $(KeyPoint * * * arrayPtrPtr);+          cv::KeyPoint * * arrayPtr = new cv::KeyPoint * [keypoints.size()];+          *arrayPtrPtr = arrayPtr;++          for (std::vector<cv::KeyPoint>::size_type ix = 0; ix != keypoints.size(); ix++)+          {+            arrayPtr[ix] = new cv::KeyPoint(keypoints[ix]);+          }+        |]+        if ptrException /= nullPtr+        then Left . BindingException <$> fromPtr (pure ptrException)+        else do+          numPts <- fromIntegral <$> peek numPtsPtr+          arrayPtr <- peek arrayPtrPtr+          keypoints <- mapM (fromPtr . pure) =<< peekArray numPts arrayPtr++          [CU.block| void {+            delete [] *$(KeyPoint * * * arrayPtrPtr);+          }|]++          pure $ Right (V.fromList keypoints)++--------------------------------------------------------------------------------+-- DescriptorMatcher+--------------------------------------------------------------------------------++class DescriptorMatcher a where+    upcast :: a -> BaseMatcher+    add :: a+        -> V.Vector (Mat 'D 'D 'D) -- ^ Train set of descriptors.+        -> IO ()+    add dm trainDescriptors =+        withPtr (upcast dm)           $ \dmPtr       ->+        withArrayPtr trainDescriptors $ \trainVecPtr ->+            [C.block| void {+                std::vector<Mat> buffer( $(Mat * trainVecPtr)+                                       , $(Mat * trainVecPtr) + $(int32_t c'trainVecLength) );+                $(DescriptorMatcher * dmPtr)->add(buffer);+            }|]+      where+        c'trainVecLength = fromIntegral $ V.length trainDescriptors+    train :: a+          -> IO ()+    train dm =+        withPtr (upcast dm) $ \dmPtr ->+            [C.block| void { $(DescriptorMatcher * dmPtr)->train(); } |]+    match+        :: a+        -> Mat 'D 'D 'D -- ^ Query set of descriptors.+        -> Mat 'D 'D 'D -- ^ Train set of descriptors.+        -> Maybe (Mat ('S [height, width]) ('S 1) ('S Word8))+           -- ^ Mask specifying permissible matches between an input query and+           -- train matrices of descriptors..+        -> IO (V.Vector DMatch)+    match dm queryDescriptors trainDescriptors mbMask =+        withPtr (upcast dm)      $ \dmPtr    ->+        withPtr queryDescriptors $ \queryPtr ->+        withPtr trainDescriptors $ \trainPtr ->+        withPtr mbMask           $ \maskPtr  ->+        alloca $ \(numMatchesPtr :: Ptr Int32) ->+        alloca $ \(arrayPtrPtr :: Ptr (Ptr (Ptr C'DMatch))) -> mask_ $ do+            [C.block| void {+                cv::Mat * maskPtr = $(Mat * maskPtr);+                std::vector<cv::DMatch> matches = std::vector<cv::DMatch>();+                $(DescriptorMatcher * dmPtr)->match+                    ( *$(Mat * queryPtr)+                    , *$(Mat * trainPtr)+                    , matches+                    , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+                    );+                *$(int32_t * numMatchesPtr) = matches.size();+                cv::DMatch * * * arrayPtrPtr = $(DMatch * * * arrayPtrPtr);+                cv::DMatch * * arrayPtr = new cv::DMatch * [matches.size()];+                *arrayPtrPtr = arrayPtr;+                for (std::vector<cv::DMatch>::size_type ix = 0; ix != matches.size(); ix++)+                {+                    cv::DMatch & org = matches[ix];+                    cv::DMatch * newMatch =+                        new cv::DMatch( org.queryIdx+                                      , org.trainIdx+                                      , org.imgIdx+                                      , org.distance+                                      );+                    arrayPtr[ix] = newMatch;+                }+            }|]+            (numMatches :: Int) <- fromIntegral <$> peek numMatchesPtr+            arrayPtr <- peek arrayPtrPtr+            matches <- mapM (fromPtr . pure) =<< peekArray numMatches arrayPtr+            [CU.block| void {+                delete [] *$(DMatch * * * arrayPtrPtr);+            }|]+            pure $ V.fromList matches+    -- | Match in pre-trained matcher+    --+    match'+        :: a+        -> Mat 'D 'D 'D -- ^ Query set of descriptors.+        -> Maybe (Mat ('S [height, width]) ('S 1) ('S Word8))+           -- ^ Mask specifying permissible matches between an input query and+           -- train matrices of descriptors..+        -> IO (V.Vector DMatch)+    match' dm queryDescriptors mbMask =+        withPtr (upcast dm)      $ \dmPtr    ->+        withPtr queryDescriptors $ \queryPtr ->+        withPtr mbMask           $ \maskPtr  ->+        alloca $ \(numMatchesPtr :: Ptr Int32) ->+        alloca $ \(arrayPtrPtr :: Ptr (Ptr (Ptr C'DMatch))) -> mask_ $ do+            [C.block| void {+                cv::Mat * maskPtr = $(Mat * maskPtr);+                std::vector<cv::DMatch> matches = std::vector<cv::DMatch>();+                $(DescriptorMatcher * dmPtr)->match+                    ( *$(Mat * queryPtr)+                    , matches+                    , maskPtr ? cv::_InputArray(*maskPtr) : cv::_InputArray(noArray())+                    );+                *$(int32_t * numMatchesPtr) = matches.size();+                cv::DMatch * * * arrayPtrPtr = $(DMatch * * * arrayPtrPtr);+                cv::DMatch * * arrayPtr = new cv::DMatch * [matches.size()];+                *arrayPtrPtr = arrayPtr;+                for (std::vector<cv::DMatch>::size_type ix = 0; ix != matches.size(); ix++)+                {+                    cv::DMatch & org = matches[ix];+                    cv::DMatch * newMatch =+                        new cv::DMatch( org.queryIdx+                                      , org.trainIdx+                                      , org.imgIdx+                                      , org.distance+                                      );+                    arrayPtr[ix] = newMatch;+                }+            }|]+            (numMatches :: Int) <- fromIntegral <$> peek numMatchesPtr+            arrayPtr <- peek arrayPtrPtr+            matches <- mapM (fromPtr . pure) =<< peekArray numMatches arrayPtr+            [CU.block| void {+                delete [] *$(DMatch * * * arrayPtrPtr);+            }|]+            pure $ V.fromList matches+++newtype BaseMatcher = BaseMatcher {unBaseMatcher :: ForeignPtr C'DescriptorMatcher}++type instance C BaseMatcher = C'DescriptorMatcher++instance WithPtr BaseMatcher where+    withPtr = withForeignPtr . unBaseMatcher+++--------------------------------------------------------------------------------+-- BFMatcher+--------------------------------------------------------------------------------++{- | Brute-force descriptor matcher++For each descriptor in the first set, this matcher finds the closest descriptor+in the second set by trying each one. This descriptor matcher supports masking+permissible matches of descriptor sets.++Example:++@+bfMatcherImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog+       , width2 ~ (*) width 2+       )+    => IO (Mat (ShapeT [height, width2]) ('S channels) ('S depth))+bfMatcherImg = do+    let (kpts1, descs1) = exceptError $ orbDetectAndCompute orb frog        Nothing+        (kpts2, descs2) = exceptError $ orbDetectAndCompute orb rotatedFrog Nothing++    bfmatcher <- newBFMatcher Norm_Hamming True+    matches <- match bfmatcher+                     descs1 -- Query descriptors+                     descs2 -- Train descriptors+                     Nothing+    exceptErrorIO $ pureExcept $+      withMatM (Proxy :: Proxy [height, width2])+               (Proxy :: Proxy channels)+               (Proxy :: Proxy depth)+               white $ \\imgM -> do+        matCopyToM imgM (V2 0     0) frog        Nothing+        matCopyToM imgM (V2 width 0) rotatedFrog Nothing++        -- Draw the matches as lines from the query image to the train image.+        forM_ matches $ \\dmatch -> do+          let matchRec = dmatchAsRec dmatch+              queryPt = kpts1 V.! fromIntegral (dmatchQueryIdx matchRec)+              trainPt = kpts2 V.! fromIntegral (dmatchTrainIdx matchRec)+              queryPtRec = keyPointAsRec queryPt+              trainPtRec = keyPointAsRec trainPt++          -- We translate the train point one width to the right in order to+          -- match the position of rotatedFrog in imgM.+          line imgM+               (round \<$> kptPoint queryPtRec :: V2 Int32)+               ((round \<$> kptPoint trainPtRec :: V2 Int32) ^+^ V2 width 0)+               blue 1 LineType_AA 0+  where+    orb = mkOrb defaultOrbParams {orb_nfeatures = 50}++    width = fromInteger $ natVal (Proxy :: Proxy width)++    rotatedFrog = exceptError $+                  warpAffine frog rotMat InterArea False False (BorderConstant black)+    rotMat = getRotationMatrix2D (V2 250 195 :: V2 CFloat) 45 0.8+@++<<doc/generated/examples/bfMatcherImg.png bfMatcherImg>>++<http://docs.opencv.org/3.0-last-rst/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html#bfmatcher OpenCV Sphinx doc>+-}+newtype BFMatcher = BFMatcher {unBFMatcher :: ForeignPtr C'BFMatcher}++type instance C BFMatcher = C'BFMatcher++instance WithPtr BFMatcher where+    withPtr = withForeignPtr . unBFMatcher++instance FromPtr BFMatcher where+    fromPtr = objFromPtr BFMatcher $ \ptr ->+                [CU.exp| void { delete $(BFMatcher * ptr) }|]+++--------------------------------------------------------------------------------++newBFMatcher+    :: NormType+       -- ^ 'Norm_L1' and 'Norm_L2' norms are preferable choices for SIFT and+       -- SURF descriptors, 'Norm_Hamming' should be used with 'Orb', BRISK and+       -- BRIEF, 'Norm_Hamming2' should be used with 'Orb' when 'WTA_K_3' or+       -- 'WTA_K_4' (see 'orb_WTA_K').+    -> Bool+       -- ^ If it is false, this is will be default 'BFMatcher' behaviour when+       -- it finds the k nearest neighbors for each query descriptor. If+       -- crossCheck == True, then the @knnMatch()@ method with @k=1@ will only+       -- return pairs @(i,j)@ such that for i-th query descriptor the j-th+       -- descriptor in the matcher's collection is the nearest and vice versa,+       -- i.e. the 'BFMatcher' will only return consistent pairs. Such technique+       -- usually produces best results with minimal number of outliers when+       -- there are enough matches. This is alternative to the ratio test, used+       -- by D. Lowe in SIFT paper.+    -> IO BFMatcher+newBFMatcher normType crossCheck = fromPtr+    [CU.exp|BFMatcher * {+      new cv::BFMatcher+          ( $(int32_t c'normType)+          , $(bool c'crossCheck)+          )+    }|]+  where+    c'normType = marshalNormType NormAbsolute normType+    c'crossCheck = fromBool crossCheck++--------------------------------------------------------------------------------++instance DescriptorMatcher BFMatcher where+    upcast (BFMatcher ptr) = BaseMatcher $ castForeignPtr ptr++++--------------------------------------------------------------------------------+-- FlannBasedMatcher+--------------------------------------------------------------------------------++{- | Flann-based descriptor matcher.++This matcher trains @flann::Index_@ on a train descriptor collection and calls it+nearest search methods to find the best matches. So, this matcher may be faster+when matching a large train collection than the brute force matcher.+@FlannBasedMatcher@ does not support masking permissible matches of descriptor+sets because flann::Index does not support this.++Example:++@+fbMatcherImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog+       , width2 ~ (*) width 2+       )+    => IO (Mat (ShapeT [height, width2]) ('S channels) ('S depth))+fbMatcherImg = do+    let (kpts1, descs1) = exceptError $ orbDetectAndCompute orb frog        Nothing+        (kpts2, descs2) = exceptError $ orbDetectAndCompute orb rotatedFrog Nothing++    fbmatcher <- newFlannBasedMatcher (def { indexParams = FlannLshIndexParams 20 10 2 })+    matches <- match fbmatcher+                     descs1 -- Query descriptors+                     descs2 -- Train descriptors+                     Nothing+    exceptErrorIO $ pureExcept $+      withMatM (Proxy :: Proxy [height, width2])+               (Proxy :: Proxy channels)+               (Proxy :: Proxy depth)+               white $ \\imgM -> do+        matCopyToM imgM (V2 0     0) frog        Nothing+        matCopyToM imgM (V2 width 0) rotatedFrog Nothing++        -- Draw the matches as lines from the query image to the train image.+        forM_ matches $ \\dmatch -> do+          let matchRec = dmatchAsRec dmatch+              queryPt = kpts1 V.! fromIntegral (dmatchQueryIdx matchRec)+              trainPt = kpts2 V.! fromIntegral (dmatchTrainIdx matchRec)+              queryPtRec = keyPointAsRec queryPt+              trainPtRec = keyPointAsRec trainPt++          -- We translate the train point one width to the right in order to+          -- match the position of rotatedFrog in imgM.+          line imgM+               (round \<$> kptPoint queryPtRec :: V2 Int32)+               ((round \<$> kptPoint trainPtRec :: V2 Int32) ^+^ V2 width 0)+               blue 1 LineType_AA 0+  where+    orb = mkOrb defaultOrbParams {orb_nfeatures = 50}++    width = fromInteger $ natVal (Proxy :: Proxy width)++    rotatedFrog = exceptError $+                  warpAffine frog rotMat InterArea False False (BorderConstant black)+    rotMat = getRotationMatrix2D (V2 250 195 :: V2 CFloat) 45 0.8+@++<<doc/generated/examples/fbMatcherImg.png fbMatcherImg>>++<http://docs.opencv.org/3.0-last-rst/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html#flannbasedmatcher OpenCV Sphinx doc>+-}+newtype FlannBasedMatcher = FlannBasedMatcher {unFlannBasedMatcher :: ForeignPtr C'FlannBasedMatcher}++type instance C FlannBasedMatcher = C'FlannBasedMatcher++instance WithPtr FlannBasedMatcher where+    withPtr = withForeignPtr . unFlannBasedMatcher++instance FromPtr FlannBasedMatcher where+    fromPtr = objFromPtr FlannBasedMatcher $ \ptr ->+                [CU.exp| void { delete $(FlannBasedMatcher * ptr) }|]+++--------------------------------------------------------------------------------+++data FlannIndexParams = FlannKDTreeIndexParams { trees :: Int }+                      | FlannLshIndexParams { tableNumber :: Int, keySize :: Int, multiProbeLevel :: Int }+++data FlannSearchParams = FlannSearchParams { checks :: Int, eps :: Float, sorted :: Bool }+++data FlannBasedMatcherParams = FlannBasedMatcherParams+    { indexParams :: FlannIndexParams+    , searchParams :: FlannSearchParams+    }+++instance Default FlannIndexParams where+    def = FlannKDTreeIndexParams { trees = 4 }+++instance Default FlannSearchParams where+    def = FlannSearchParams { checks = 32, eps = 0, sorted = True }+++instance Default FlannBasedMatcherParams where+    def = FlannBasedMatcherParams def def+++-- NB: 1) it's OK to pass these new object as raw pointers because these directly pass to Ptr() in FlannBasedMatcher+--     2) also, these objects use only in this internal module, so we don't create inlinec-wrappers for it, but pass+--        between calls as void* pointers++marshalIndexParams :: FlannIndexParams -> Ptr ()+marshalIndexParams (FlannKDTreeIndexParams tree) = unsafePerformIO $+    [CU.exp| void* { new flann::KDTreeIndexParams($(int32_t c'tree)) } |]+    where c'tree = fromIntegral tree+marshalIndexParams (FlannLshIndexParams tableNumber keySize multiProbeLevel) = unsafePerformIO $+    [CU.exp| void* { new cv::flann::LshIndexParams($(int32_t c'tableNumber), $(int32_t c'keySize), $(int32_t c'multiProbeLevel)) } |]+    where c'tableNumber     = fromIntegral tableNumber+          c'keySize         = fromIntegral keySize+          c'multiProbeLevel = fromIntegral multiProbeLevel++marshallSearchParams :: FlannSearchParams -> Ptr ()+marshallSearchParams (FlannSearchParams checks eps sorted) = unsafePerformIO $+    [CU.exp| void* { new cv::flann::SearchParams($(int32_t c'checks), $(float c'eps), $(bool c'sorted)) } |]+    where c'checks = fromIntegral checks+          c'eps    = realToFrac eps+          c'sorted = fromBool sorted+++newFlannBasedMatcher :: FlannBasedMatcherParams -> IO FlannBasedMatcher+newFlannBasedMatcher FlannBasedMatcherParams{..} = fromPtr+    [CU.exp|FlannBasedMatcher * {+      new cv::FlannBasedMatcher((flann::IndexParams*)($(void* c'indexParams)), (flann::SearchParams*)($(void* c'searchParams)))+    }|]+  where+    c'indexParams  = marshalIndexParams indexParams+    c'searchParams = marshallSearchParams searchParams++--------------------------------------------------------------------------------++instance DescriptorMatcher FlannBasedMatcher where+    upcast (FlannBasedMatcher ptr) = BaseMatcher $ castForeignPtr ptr+++--------------------------------------------------------------------------------++data DrawMatchesParams = DrawMatchesParams+    { matchColor :: Scalar+    , singlePointColor :: Scalar+    -- , matchesMask -- TODO+    , flags :: Int32+    }+++instance Default DrawMatchesParams where+    def = DrawMatchesParams+        { matchColor = toScalar $ V4 (255::Double) 255 255 125+        , singlePointColor = toScalar $ V4 (255::Double) 255 255 125+        , flags = 0+        }++drawMatches :: Mat ('S [height, width]) channels depth+            -> V.Vector KeyPoint+            -> Mat ('S [height, width]) channels depth+            -> V.Vector KeyPoint+            -> V.Vector DMatch+            -> DrawMatchesParams+            -> CvExcept (Mat ('S ['D, 'D]) channels depth)+drawMatches img1 keypoints1 img2 keypoints2 matches1to2 (DrawMatchesParams{..}) = unsafeWrapException $ do+    outImg <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat outImg) $+        withPtr img1             $ \img1Ptr ->+        withArrayPtr keypoints1  $ \kps1Ptr ->+        withPtr img2             $ \img2Ptr ->+        withArrayPtr keypoints2  $ \kps2Ptr ->+        withArrayPtr matches1to2 $ \mt12Ptr ->+        withPtr outImg           $ \outImgPtr ->+            [cvExcept|+                std::vector<KeyPoint> kps1($(KeyPoint * kps1Ptr), $(KeyPoint * kps1Ptr) + $(int32_t c'kps1Length));+                std::vector<KeyPoint> kps2($(KeyPoint * kps2Ptr), $(KeyPoint * kps2Ptr) + $(int32_t c'kps2Length));+                std::vector<DMatch>   mt12($(DMatch * mt12Ptr),   $(DMatch * mt12Ptr) + $(int32_t c'matches1to2Length));+                drawMatches(+                    *$(Mat* img1Ptr),+                    kps1,+                    *$(Mat* img2Ptr),+                    kps2,+                    mt12,+                    *$(Mat* outImgPtr));+            |]+  where+    c'kps1Length = fromIntegral $ V.length keypoints1+    c'kps2Length = fromIntegral $ V.length keypoints2+    c'matches1to2Length = fromIntegral $ V.length matches1to2
+ src/OpenCV/HighGui.cpp view
@@ -0,0 +1,67 @@++#include "opencv2/core.hpp"++#include "opencv2/highgui.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_HighGui_0_2d7609c7f0e6c42f93d15df73edc3537e124c660(char * cname_27_inline_c_0, char * ctitle_27_inline_c_1) {++        char * cname = cname_27_inline_c_0;+        cv::namedWindow(cname, cv::WINDOW_NORMAL | cv::WINDOW_KEEPRATIO);+        cv::setWindowTitle(cname, ctitle_27_inline_c_1);+      +}++}++extern "C" {+void inline_c_OpenCV_HighGui_1_c5fcdd7a84ce1bf6ff6826a91819bb2eeec8b958(char * cname_27_inline_c_0) {+ cv::destroyWindow(cname_27_inline_c_0); ;+}++}++extern "C" {+void inline_c_OpenCV_HighGui_2_6d77ebbd6b41637df8ae54e62490b84a083b5302(char * cname_27_inline_c_0, int32_t width_inline_c_1, int32_t height_inline_c_2) {+ cv::resizeWindow(cname_27_inline_c_0, width_inline_c_1, height_inline_c_2); ;+}++}++extern "C" {+int32_t inline_c_OpenCV_HighGui_3_fb37cd90c9f3b163f9aca91658c8817f9bd8cd3b(int32_t delay_inline_c_0) {+return ( cv::waitKey(delay_inline_c_0) );+}++}++extern "C" {+void inline_c_OpenCV_HighGui_4_74ffe2404cfc5216db3374d216ffaa2c36262814(char * cname_27_inline_c_0, MouseCallback callbackPtr_inline_c_1) {+ cv::setMouseCallback(cname_27_inline_c_0, callbackPtr_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_HighGui_5_fb47c18a6250110f9b081b530e8420cf3207a0c8(char * ctrackbarName_27_inline_c_0, char * cname_27_inline_c_1, int32_t * valuePtr_inline_c_2, int32_t count_inline_c_3, TrackbarCallback callbackPtr_inline_c_4) {++        (void)cv::createTrackbar+          ( ctrackbarName_27_inline_c_0+          , cname_27_inline_c_1+          , valuePtr_inline_c_2+          , count_inline_c_3+          , callbackPtr_inline_c_4+          )+      ;+}++}++extern "C" {+void inline_c_OpenCV_HighGui_6_940dcb370c787776fef1ce37b44d4eb5e8e1fd3e(char * cname_27_inline_c_0, Mat * matPtr_inline_c_1) {+ cv::imshow(cname_27_inline_c_0, *matPtr_inline_c_1); ;+}++}
+ src/OpenCV/HighGui.hsc view
@@ -0,0 +1,376 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++{- |+While OpenCV was designed for use in full-scale applications and can be used+within functionally rich UI frameworks (such as Qt*, WinForms*, or Cocoa*) or+without any UI at all, sometimes there it is required to try functionality+quickly and visualize the results. This is what the "OpenCV.HighGui" module has+been designed for.++It provides easy interface to:++ * Create and manipulate windows that can display images and “remember” their+   content (no need to handle repaint events from OS).++ * Add trackbars to the windows, handle simple mouse events as well as keyboard+   commands.+-}+module OpenCV.HighGui+    ( -- * Window management+      Window+    , makeWindow+    , destroyWindow+    , withWindow+    , resizeWindow++      -- * Event handling++      -- ** Keyboard+    , waitKey++      -- ** Mouse+    , Event(..)+    , EventFlags++    , hasLButton+    , hasRButton+    , hasMButton+    , hasCtrlKey+    , hasShiftKey+    , hasAltKey++    , EventFlagsRec(..)+    , flagsToRec++    , MouseCallback+    , setMouseCallback++      -- * Trackbars+    , TrackbarCallback+    , createTrackbar++      -- * Drawing+    , imshow+    , imshowM+    ) where++import "base" Control.Concurrent.MVar+import "base" Control.Exception ( mask_, bracket )+import "base" Data.Bits ( (.&.) )+import "base" Data.Int ( Int32 )+import "base" Data.Monoid ( (<>) )+import "base" Data.Unique ( newUnique, hashUnique )+import "base" Foreign.C.String ( CString, newCString, withCString )+import "base" Foreign.Ptr ( Ptr, FunPtr, freeHaskellFunPtr )+import "base" Foreign.Marshal.Alloc ( free )+import "base" Foreign.Marshal.Utils ( new )+import "containers" Data.Map ( Map )+import qualified "containers" Data.Map as M+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "primitive" Control.Monad.Primitive ( PrimState )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Internal.Mutable+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context (C.cppCtx <> openCvCtx)++C.include "opencv2/core.hpp"+C.include "opencv2/highgui.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/highgui.hpp"++#include "namespace.hpp"+++--------------------------------------------------------------------------------+-- Window management++data TrackbarState+   = TrackbarState+     { trackbarCallback :: !(FunPtr C'TrackbarCallback)+     , trackbarValuePtr :: !(Ptr Int32)+     }++data Window+   = Window+     { windowName          :: !CString+     , windowMouseCallback :: !(MVar (Maybe (FunPtr C'MouseCallback)))+     , windowTrackbars     :: !(MVar (Map String TrackbarState))+     }++freeTrackbar :: TrackbarState -> IO ()+freeTrackbar trackbar = do+    freeHaskellFunPtr $ trackbarCallback trackbar+    free $ trackbarValuePtr trackbar++-- #num WINDOW_NORMAL+-- #num WINDOW_AUTOSIZE+-- #num WINDOW_OPENGL+-- #num WINDOW_FREERATIO+-- #num WINDOW_KEEPRATIO++-- marshalWindowFlags :: WindowFlags -> Int32+-- marshalWindowFlags WindowFlags{..} =++-- | Create a window with the specified title.+--+-- Make sure to free the window when you're done with it using 'destroyWindow'+-- or better yet: use 'withWindow'.+makeWindow :: String -> IO Window+makeWindow title = do+    name <- show . hashUnique <$> newUnique+    c'name <- newCString name+    mouseCallback <- newMVar Nothing+    trackbars <- newMVar M.empty+    withCString title $ \c'title ->+      [C.block| void {+        char * cname = $(char * c'name);+        cv::namedWindow(cname, cv::WINDOW_NORMAL | cv::WINDOW_KEEPRATIO);+        cv::setWindowTitle(cname, $(char * c'title));+      }|]+    pure Window+         { windowName          = c'name+         , windowMouseCallback = mouseCallback+         , windowTrackbars     = trackbars+         }++-- | Close the window and free up all resources associated with the window.+destroyWindow :: Window -> IO ()+destroyWindow window = mask_ $ do+    [C.exp| void { cv::destroyWindow($(char * c'name)); }|]+    free c'name+    modifyMVar_ (windowMouseCallback window) $ \mbMouseCallback -> do+      mapM_ freeHaskellFunPtr mbMouseCallback+      pure Nothing+    modifyMVar_ (windowTrackbars window) $ \trackbars -> do+      mapM_ freeTrackbar trackbars+      pure M.empty+  where+    c'name :: CString+    c'name = windowName window++-- | @withWindow title act@ makes a window with the specified @title@ and passes+-- the resulting 'Window' to the computation @act@. The window will be destroyed+-- on exit from @withWindow@ whether by normal termination or by raising an+-- exception. Make sure not to use the @Window@ outside the @act@ computation!+withWindow :: String -> (Window -> IO a) -> IO a+withWindow title = bracket (makeWindow title) destroyWindow++-- | Resize a window to the specified size.+resizeWindow :: Window -> Int32 -> Int32 -> IO ()+resizeWindow window width height =+  [C.exp| void { cv::resizeWindow($(char * c'name), $(int32_t width), $(int32_t height)); }|]+    where+      c'name :: CString+      c'name = windowName window+++--------------------------------------------------------------------------------+-- Keyboard++waitKey :: Int32 -> IO Int32+waitKey delay = [C.exp| int32_t { cv::waitKey($(int32_t delay)) }|]+++--------------------------------------------------------------------------------+-- Mouse++data Event+   = EventMouseMove+   | EventLButtonDown+   | EventRButtonDown+   | EventMButtonDown+   | EventLButtonUp+   | EventRButtonUp+   | EventMButtonUp+   | EventLButtonDbClick+   | EventRButtonDbClick+   | EventMButtonDbClick+   | EventMouseWheel+   | EventMouseHWheel+     deriving Show++-- | Context for a mouse 'Event'+--+-- Information about which buttons and modifier keys where pressed during the+-- event.+newtype EventFlags = EventFlags Int32++matchEventFlag :: Int32 -> EventFlags -> Bool+matchEventFlag flag = \(EventFlags flags) -> flags .&. flag /= 0++hasLButton  :: EventFlags -> Bool+hasRButton  :: EventFlags -> Bool+hasMButton  :: EventFlags -> Bool+hasCtrlKey  :: EventFlags -> Bool+hasShiftKey :: EventFlags -> Bool+hasAltKey   :: EventFlags -> Bool++#num EVENT_FLAG_LBUTTON+#num EVENT_FLAG_RBUTTON+#num EVENT_FLAG_MBUTTON+#num EVENT_FLAG_CTRLKEY+#num EVENT_FLAG_SHIFTKEY+#num EVENT_FLAG_ALTKEY++hasLButton  = matchEventFlag c'EVENT_FLAG_LBUTTON+hasRButton  = matchEventFlag c'EVENT_FLAG_RBUTTON+hasMButton  = matchEventFlag c'EVENT_FLAG_MBUTTON+hasCtrlKey  = matchEventFlag c'EVENT_FLAG_CTRLKEY+hasShiftKey = matchEventFlag c'EVENT_FLAG_SHIFTKEY+hasAltKey   = matchEventFlag c'EVENT_FLAG_ALTKEY++-- | More convenient representation of 'EventFlags'+data EventFlagsRec+   = EventFlagsRec+     { flagsLButton  :: !Bool+     , flagsRButton  :: !Bool+     , flagsMButton  :: !Bool+     , flagsCtrlKey  :: !Bool+     , flagsShiftKey :: !Bool+     , flagsAltKey   :: !Bool+     } deriving Show++flagsToRec :: EventFlags -> EventFlagsRec+flagsToRec flags =+    EventFlagsRec+    { flagsLButton  = hasLButton  flags+    , flagsRButton  = hasRButton  flags+    , flagsMButton  = hasMButton  flags+    , flagsCtrlKey  = hasCtrlKey  flags+    , flagsShiftKey = hasShiftKey flags+    , flagsAltKey   = hasAltKey   flags+    }++#num EVENT_MOUSEMOVE+#num EVENT_LBUTTONDOWN+#num EVENT_RBUTTONDOWN+#num EVENT_MBUTTONDOWN+#num EVENT_LBUTTONUP+#num EVENT_RBUTTONUP+#num EVENT_MBUTTONUP+#num EVENT_LBUTTONDBLCLK+#num EVENT_RBUTTONDBLCLK+#num EVENT_MBUTTONDBLCLK+#num EVENT_MOUSEWHEEL+#num EVENT_MOUSEHWHEEL++unmarshalEvent :: Int32 -> Event+unmarshalEvent event+   | event == c'EVENT_MOUSEMOVE     = EventMouseMove+   | event == c'EVENT_LBUTTONDOWN   = EventLButtonDown+   | event == c'EVENT_RBUTTONDOWN   = EventRButtonDown+   | event == c'EVENT_MBUTTONDOWN   = EventMButtonDown+   | event == c'EVENT_LBUTTONUP     = EventLButtonUp+   | event == c'EVENT_RBUTTONUP     = EventRButtonUp+   | event == c'EVENT_MBUTTONUP     = EventMButtonUp+   | event == c'EVENT_LBUTTONDBLCLK = EventLButtonDbClick+   | event == c'EVENT_RBUTTONDBLCLK = EventRButtonDbClick+   | event == c'EVENT_MBUTTONDBLCLK = EventMButtonDbClick+   | event == c'EVENT_MOUSEWHEEL    = EventMouseWheel+   | event == c'EVENT_MOUSEHWHEEL   = EventMouseHWheel+   | otherwise = error $ "unmarshalEvent - unknown event " <> show event++-- | Callback function for mouse events+type MouseCallback+   =  Event -- ^ What happened to cause the callback to be fired.+   -> Int32 -- ^ The x-coordinate of the mouse event.+   -> Int32 -- ^ The y-coordinate of the mouse event.+   -> EventFlags+      -- ^ Context for the event, such as buttons and modifier keys pressed+      -- during the event.+   -> IO ()++setMouseCallback :: Window -> MouseCallback -> IO ()+setMouseCallback window callback =+    modifyMVar_ (windowMouseCallback window) $ \mbPrevCallback -> do+      callbackPtr <- $(C.mkFunPtr [t| C'MouseCallback |]) c'callback+      [C.exp| void { cv::setMouseCallback($(char * c'name), $(MouseCallback callbackPtr)) }|]+      mapM_ freeHaskellFunPtr mbPrevCallback+      pure $ Just callbackPtr+  where+    c'name :: CString+    c'name = windowName window++    c'callback :: C'MouseCallback+    c'callback c'event x y c'flags _c'userDataPtr = callback event x y flags+      where+        event = unmarshalEvent c'event+        flags = EventFlags $ fromIntegral c'flags++--------------------------------------------------------------------------------+-- Trackbars++-- | Callback function for trackbars+type TrackbarCallback+   =  Int32 -- ^ Current position of the specified trackbar.+   -> IO ()++createTrackbar+    :: Window+    -> String -- ^ Trackbar name+    -> Int32  -- ^ Initial value+    -> Int32  -- ^ Maximum value+    -> TrackbarCallback+    -> IO ()+createTrackbar window trackbarName value count callback =+    modifyMVar_ (windowTrackbars window) $ \trackbars ->+    withCString trackbarName $ \c'trackbarName -> mask_ $ do+      valuePtr <- new value+      callbackPtr <- $(C.mkFunPtr [t| C'TrackbarCallback |]) c'callback+      [C.exp| void {+        (void)cv::createTrackbar+          ( $(char * c'trackbarName)+          , $(char * c'name)+          , $(int32_t * valuePtr)+          , $(int32_t count)+          , $(TrackbarCallback callbackPtr)+          )+      }|]++      let (mbPrevCallback, trackbars') =+              M.updateLookupWithKey (\_k _v -> Just trackbar)+                                    trackbarName+                                    trackbars+          trackbar = TrackbarState+                     { trackbarCallback = callbackPtr+                     , trackbarValuePtr = valuePtr+                     }+      mapM_ freeTrackbar mbPrevCallback+      pure trackbars'+  where+    c'name :: CString+    c'name = windowName window++    c'callback :: C'TrackbarCallback+    c'callback pos _c'userDataPtr = callback pos+++--------------------------------------------------------------------------------+-- Drawing++imshow+    :: Window -- ^+    -> Mat ('S [height, width]) channels depth+    -> IO ()+imshow window mat =+    withPtr mat $ \matPtr ->+      [C.exp| void { cv::imshow($(char * c'name), *$(Mat * matPtr)); }|]+  where+    c'name :: CString+    c'name = windowName window++imshowM+    :: Window -- ^+    -> Mut (Mat ('S [height, width]) channels depth) (PrimState IO)+    -> IO ()+imshowM window mat = imshow window =<< unsafeFreeze mat
+ src/OpenCV/ImgCodecs.cpp view
@@ -0,0 +1,53 @@++#include <vector>++#include "opencv2/core.hpp"++#include "opencv2/imgcodecs.hpp"++using namespace cv;++extern "C" {+Mat * inline_c_OpenCV_ImgCodecs_0_36f746c8786403014d5e310cdd8e7c7dc1545ec1(char * hbuf_inline_c_0, long hbuf_inline_c_1, int32_t cimreadMode_27_inline_c_2) {++      cv::_InputArray cbuf = cv::_InputArray(hbuf_inline_c_0, hbuf_inline_c_1);+      return new cv::Mat(cv::imdecode(cbuf, cimreadMode_27_inline_c_2));+    +}++}++extern "C" {+void inline_c_OpenCV_ImgCodecs_1_d787acca1f472edcee9c045aea331d0f2c0df0b1(void * vecPtr_inline_c_0) {+ delete reinterpret_cast< std::vector<uchar> * >(vecPtr_inline_c_0) ;+}++}++extern "C" {+Exception * inline_c_OpenCV_ImgCodecs_2_7bba68846f49f21451c299ab6a8a271ad64dc223(int * params_inline_c_0, void ** vecPtrPtr_inline_c_1, long params_inline_c_2, char * extPtr_inline_c_3, Mat * matPtr_inline_c_4, int32_t * cbufSizePtr_27_inline_c_5, unsigned char ** bufPtrPtr_inline_c_6) {++  try+  {   +        const int * const paramsPtr = params_inline_c_0;+        std::vector<uchar> * vec = new std::vector<uchar>();+        *vecPtrPtr_inline_c_1 = reinterpret_cast<void *>(vec);+        std::vector<int> params(paramsPtr, paramsPtr + params_inline_c_2);+        cv::imencode( extPtr_inline_c_3+                    , *matPtr_inline_c_4+                    , *vec+                    , params+                    );+        *cbufSizePtr_27_inline_c_5 = vec->size();+        *bufPtrPtr_inline_c_6 = &((*vec)[0]);+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/ImgCodecs.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.ImgCodecs+    ( ImreadMode(..)+    , imdecode+    , imdecodeM++    , OutputFormat(..)+    , JpegParams(..), defaultJpegParams+    , PngStrategy(..)+    , PngParams(..), defaultPngParams+    , imencode+    , imencodeM+    ) where++import "base" Control.Exception ( mask_ )+import "base" Data.Int ( Int32 )+import "base" Foreign.C.String ( withCString )+import "base" Foreign.C.Types+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Ptr ( Ptr, nullPtr, castPtr )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import "bytestring" Data.ByteString ( ByteString )+import qualified "bytestring" Data.ByteString.Unsafe as BU+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState )+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.ImgCodecs+import "this" OpenCV.Internal.Mutable+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except+++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "<vector>"+C.include "opencv2/core.hpp"+C.include "opencv2/imgcodecs.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------++-- | Reads an image from a buffer in memory.+--+-- The function reads an image from the specified buffer in the+-- memory. If the buffer is too short or contains invalid data, the+-- empty matrix/image is returned.+--+-- <http://docs.opencv.org/3.0-last-rst/modules/imgcodecs/doc/reading_and_writing_images.html#imdecode OpenCV Sphinx doc>+imdecode+    :: ImreadMode+    -> ByteString+    -> Mat ('S ['D, 'D]) 'D 'D+imdecode imreadMode hbuf = unsafeCoerceMat $ unsafePerformIO $ fromPtr+    [C.block|Mat * {+      cv::_InputArray cbuf = cv::_InputArray($bs-ptr:hbuf, $bs-len:hbuf);+      return new cv::Mat(cv::imdecode(cbuf, $(int32_t c'imreadMode)));+    }|]+  where+    c'imreadMode = marshalImreadMode imreadMode++imdecodeM+    :: (PrimMonad m)+    => ImreadMode+    -> ByteString+    -> m (Mut (Mat ('S ['D, 'D]) 'D 'D) (PrimState m))+imdecodeM imreadMode hbuf = unsafeThaw $ imdecode imreadMode hbuf++--------------------------------------------------------------------------------++-- | Encodes an image into a memory buffer.+--+-- __WARNING:__ This function is not thread safe!+--+-- <http://docs.opencv.org/3.0-last-rst/modules/imgcodecs/doc/reading_and_writing_images.html#imencode OpenCV Sphinx doc>+imencode+    :: OutputFormat+    -> Mat shape channels depth+    -> CvExcept ByteString+imencode format mat = unsafeWrapException $+    withPtr mat $ \matPtr ->+    withCString ext $ \extPtr ->+    alloca $ \(bufPtrPtr :: Ptr (Ptr CUChar)) ->+    alloca $ \(vecPtrPtr :: Ptr (Ptr ())) ->+    alloca $ \(c'bufSizePtr :: Ptr Int32) -> mask_ $ do+      ptrException <- [cvExcept|+        const int * const paramsPtr = $vec-ptr:(int * params);+        std::vector<uchar> * vec = new std::vector<uchar>();+        *$(void * * vecPtrPtr) = reinterpret_cast<void *>(vec);+        std::vector<int> params(paramsPtr, paramsPtr + $vec-len:params);+        cv::imencode( $(char * extPtr)+                    , *$(Mat * matPtr)+                    , *vec+                    , params+                    );+        *$(int32_t * c'bufSizePtr) = vec->size();+        *$(unsigned char * * bufPtrPtr) = &((*vec)[0]);+      |]+      vecPtr <- peek vecPtrPtr+      if ptrException /= nullPtr+      then do+        freeVec vecPtr+        Left . BindingException <$> fromPtr (pure ptrException)+      else do+        bufSize <- peek c'bufSizePtr+        bufPtr  <- peek bufPtrPtr+        bs <- BU.unsafePackCStringFinalizer+                (castPtr bufPtr)+                (fromIntegral bufSize)+                (freeVec vecPtr)+        pure $ Right bs+  where+    (ext, params) = marshalOutputFormat format++    freeVec :: Ptr () -> IO ()+    freeVec vecPtr = [C.exp|void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecPtr)) }|]++-- | Encodes an image into a memory buffer.+--+-- See 'imencode'+imencodeM+    :: (PrimMonad m)+    => OutputFormat+    -> Mut (Mat shape channels depth) (PrimState m)+    -> CvExceptT m ByteString+imencodeM format matM =+    ExceptT . pure . runExcept =<< (imencode format <$> unsafeFreeze matM)
+ src/OpenCV/ImgProc/CascadeClassifier.cpp view
@@ -0,0 +1,108 @@++#include "opencv2/core.hpp"++#include "opencv2/objdetect.hpp"++using namespace cv;++extern "C" {+CascadeClassifier * inline_c_OpenCV_ImgProc_CascadeClassifier_0_6b80627dbb95966554673ed98b4bf9e812eac7fe(const char * cfp_27_inline_c_0) {+return ( new CascadeClassifier(cv::String(cfp_27_inline_c_0)) );+}++}++extern "C" {+bool inline_c_OpenCV_ImgProc_CascadeClassifier_1_17f93b884990af769e6f4ab16cdb7850ba9e4770(CascadeClassifier * ccPtr_inline_c_0) {+return ( ccPtr_inline_c_0->empty() );+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_CascadeClassifier_2_467f3c6b4b735f82c540b6876885dfe6994469fb(CascadeClassifier * ccPtr_inline_c_0, Mat * srcPtr_inline_c_1, double cscaleFactor_27_inline_c_2, int32_t cminNeighbours_27_inline_c_3, Size2i * minSizePtr_inline_c_4, Size2i * maxSizePtr_inline_c_5, int32_t * numRectsPtr_inline_c_6, Rect2i *** rectsPtrPtr_inline_c_7) {++        std::vector<cv::Rect> rects;+        ccPtr_inline_c_0->detectMultiScale(+          *srcPtr_inline_c_1,+          rects,+          cscaleFactor_27_inline_c_2,+          cminNeighbours_27_inline_c_3,+          0,+          *minSizePtr_inline_c_4,+          *maxSizePtr_inline_c_5);+        *numRectsPtr_inline_c_6 = rects.size();+        cv::Rect * * rectsPtr = new cv::Rect * [rects.size()];+        *rectsPtrPtr_inline_c_7 = rectsPtr;+        for (std::vector<cv::Rect>::size_type i = 0; i != rects.size(); i++) {+          rectsPtr[i] = new cv::Rect(rects[i]);+        }+      +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_CascadeClassifier_3_4e4326e12039326df2bfe9ec9769c5c8e08cabda(Rect2i *** rectsPtrPtr_inline_c_0) {+ delete [] *rectsPtrPtr_inline_c_0; +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_CascadeClassifier_4_a3df942cd43c33275e4dc0c56e3f8201fa538bbc(CascadeClassifier * ccPtr_inline_c_0, Mat * srcPtr_inline_c_1, double cscaleFactor_27_inline_c_2, int32_t cminNeighbours_27_inline_c_3, Size2i * minSizePtr_inline_c_4, Size2i * maxSizePtr_inline_c_5, int32_t * numRectsPtr_inline_c_6, Rect2i *** rectsPtrPtr_inline_c_7, int32_t ** rejectLevelsPtrPtr_inline_c_8, double ** levelWeightsPtrPtr_inline_c_9) {++        std::vector<cv::Rect> rects;+        std::vector<int> rejectLevels;+        std::vector<double> levelWeights;+        ccPtr_inline_c_0->detectMultiScale(+          *srcPtr_inline_c_1,+          rects,+          rejectLevels,+          levelWeights,+          cscaleFactor_27_inline_c_2,+          cminNeighbours_27_inline_c_3,+          0,+          *minSizePtr_inline_c_4,+          *maxSizePtr_inline_c_5,+          true);+        *numRectsPtr_inline_c_6 = rects.size();++        cv::Rect * * rectsPtr = new cv::Rect * [rects.size()];+        *rectsPtrPtr_inline_c_7 = rectsPtr;++        int32_t * rejectLevelsPtr = new int32_t [rejectLevels.size()];+        *rejectLevelsPtrPtr_inline_c_8 = rejectLevelsPtr;++        double * levelWeightsPtr = new double [levelWeights.size()];+        *levelWeightsPtrPtr_inline_c_9 = levelWeightsPtr;+++        for (std::vector<cv::Rect>::size_type i = 0; i != rects.size(); i++) {++          rectsPtr[i] = new cv::Rect(rects[i]);+          rejectLevelsPtr[i] = rejectLevels[i];+          levelWeightsPtr[i] = levelWeights[i];+        }+      +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_CascadeClassifier_5_5eecd2b84cc54564205c6b34cbf0d26aa68cf96c(Rect2i *** rectsPtrPtr_inline_c_0, int32_t ** rejectLevelsPtrPtr_inline_c_1, double ** levelWeightsPtrPtr_inline_c_2) {++      delete [] *rectsPtrPtr_inline_c_0;+      delete [] *rejectLevelsPtrPtr_inline_c_1;+      delete [] *levelWeightsPtrPtr_inline_c_2;+      +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_CascadeClassifier_6_305cd84927e8af4495fea16fc54550910af3cd0e(CascadeClassifier * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/ImgProc/CascadeClassifier.hs view
@@ -0,0 +1,218 @@+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}+{-# language MultiParamTypeClasses #-}+module OpenCV.ImgProc.CascadeClassifier+  ( CascadeClassifier+  , newCascadeClassifier+  , cascadeClassifierDetectMultiScale+  , cascadeClassifierDetectMultiScaleNC+  ) where++import "base" Data.Int+import "base" Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import "base" Foreign.C.String (withCString)+import "base" System.IO.Unsafe (unsafePerformIO)+import "base" Data.Word+import "base" Foreign.Marshal.Alloc (alloca)+import "base" Foreign.Ptr (Ptr)+import "base" Control.Exception (mask_)+import "base" Foreign.Storable (peek)+import "base" Foreign.Marshal.Array (peekArray)+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import qualified "vector" Data.Vector as V+import "linear" Linear (V2(..))+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal+import "this" OpenCV.TypeLevel++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/objdetect.hpp"+C.using "namespace cv"++newtype CascadeClassifier = CascadeClassifier {unCascadeClassifier :: ForeignPtr (C CascadeClassifier)}++type instance C CascadeClassifier = C'CascadeClassifier++instance WithPtr CascadeClassifier where+    withPtr = withForeignPtr . unCascadeClassifier++instance FromPtr CascadeClassifier where+    fromPtr = objFromPtr CascadeClassifier $ \ptr ->+                [CU.exp| void { delete $(CascadeClassifier * ptr) }|]++-- | Create a new cascade classifier. Returns 'Nothing' if the classifier+-- is empty after initialization. This usually means that the file could+-- not be loaded (e.g. it doesn't exist, is corrupt, etc.)+newCascadeClassifier :: FilePath -> IO (Maybe CascadeClassifier)+newCascadeClassifier fp = do+  cc <- withCString fp $ \c'fp -> fromPtr+    [CU.exp| CascadeClassifier * { new CascadeClassifier(cv::String($(const char * c'fp))) } |]+  -- TODO: empty() seems to return bogus numbers when the classifier is not+  -- empty, and I'm not sure why. This is also why I'm not using toBool.+  empty <- fmap (== 1) (withPtr cc (\ccPtr -> [CU.exp| bool { $(CascadeClassifier * ccPtr)->empty() } |]))+  return $ if empty+    then Nothing+    else Just cc++{- |+Example:++@+cascadeClassifierArnold+  :: forall (width    :: Nat)+            (height   :: Nat)+            (channels :: Nat)+            (depth    :: *  )+   . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Arnold_small)+  => IO (Mat (ShapeT [height, width]) ('S channels) ('S depth))+cascadeClassifierArnold = do+    -- Create two classifiers from data files.+    Just ccFrontal <- newCascadeClassifier "data/haarcascade_frontalface_default.xml"+    Just ccEyes    <- newCascadeClassifier "data/haarcascade_eye.xml"+    -- Detect some features.+    let eyes  = ccDetectMultiscale ccEyes    arnoldGray+        faces = ccDetectMultiscale ccFrontal arnoldGray+    -- Draw the result.+    pure $ exceptError $+      withMatM (Proxy :: Proxy [height, width])+               (Proxy :: Proxy channels)+               (Proxy :: Proxy depth)+               white $ \\imgM -> do+        void $ matCopyToM imgM (V2 0 0) arnold_small Nothing+        forM_ eyes  $ \\eyeRect  -> lift $ rectangle imgM eyeRect  blue  2 LineType_8 0+        forM_ faces $ \\faceRect -> lift $ rectangle imgM faceRect green 2 LineType_8 0+  where+    arnoldGray = exceptError $ cvtColor bgr gray arnold_small++    ccDetectMultiscale cc = cascadeClassifierDetectMultiScale cc Nothing Nothing minSize maxSize++    minSize = Nothing :: Maybe (V2 Int32)+    maxSize = Nothing :: Maybe (V2 Int32)+@++<<doc/generated/examples/cascadeClassifierArnold.png cascadeClassifierArnold>>+-}+cascadeClassifierDetectMultiScale+  :: (IsSize size Int32)+  => CascadeClassifier+  -> Maybe Double -- ^ Scale factor, default is 1.1+  -> Maybe Int32 -- ^ Min neighbours, default 3+  -> Maybe (size Int32) -- ^ Minimum size. Default: no minimum.+  -> Maybe (size Int32) -- ^ Maximum size. Default: no maximum.+  -> Mat ('S [w, h]) ('S 1) ('S Word8)+  -> V.Vector (Rect Int32)+cascadeClassifierDetectMultiScale cc scaleFactor minNeighbours minSize maxSize src = unsafePerformIO $+    withPtr cc $ \ccPtr ->+    withPtr src $ \srcPtr ->+    withPtr c'minSize $ \minSizePtr ->+    withPtr c'maxSize $ \maxSizePtr ->+    alloca $ \(numRectsPtr :: Ptr Int32) ->+    alloca $ \(rectsPtrPtr :: Ptr (Ptr (Ptr (C'Rect Int32)))) -> mask_ $ do+      [CU.block| void {+        std::vector<cv::Rect> rects;+        $(CascadeClassifier * ccPtr)->detectMultiScale(+          *$(Mat * srcPtr),+          rects,+          $(double c'scaleFactor),+          $(int32_t c'minNeighbours),+          0,+          *$(Size2i * minSizePtr),+          *$(Size2i * maxSizePtr));+        *$(int32_t * numRectsPtr) = rects.size();+        cv::Rect * * rectsPtr = new cv::Rect * [rects.size()];+        *$(Rect2i * * * rectsPtrPtr) = rectsPtr;+        for (std::vector<cv::Rect>::size_type i = 0; i != rects.size(); i++) {+          rectsPtr[i] = new cv::Rect(rects[i]);+        }+      } |]+      numRects <- fromIntegral <$> peek numRectsPtr+      rectsPtr <- peek rectsPtrPtr+      rects :: [Rect Int32] <- peekArray numRects rectsPtr >>= mapM (fromPtr . return)+      [CU.block| void { delete [] *$(Rect2i * * * rectsPtrPtr); }|]+      return (V.fromList rects)+  where+    c'scaleFactor = maybe 1.1 realToFrac scaleFactor+    c'minNeighbours = maybe 3 fromIntegral minNeighbours+    c'minSize = maybe (toSize (V2 0 0)) toSize minSize+    c'maxSize = maybe (toSize (V2 0 0)) toSize maxSize++{- | Special version which returns bounding rectangle, rejectLevels, and levelWeights++-}+cascadeClassifierDetectMultiScaleNC+  :: (IsSize size Int32)+  => CascadeClassifier+  -> Maybe Double -- ^ Scale factor, default is 1.1+  -> Maybe Int32 -- ^ Min neighbours, default 3+  -> Maybe (size Int32) -- ^ Minimum size. Default: no minimum.+  -> Maybe (size Int32) -- ^ Maximum size. Default: no maximum.+  -> Mat ('S [w, h]) ('S 1) ('S Word8)+  -> V.Vector (Rect Int32, Int32, Double)+cascadeClassifierDetectMultiScaleNC cc scaleFactor minNeighbours minSize maxSize src = unsafePerformIO $+    withPtr cc $ \ccPtr ->+    withPtr src $ \srcPtr ->+    withPtr c'minSize $ \minSizePtr ->+    withPtr c'maxSize $ \maxSizePtr ->+    alloca $ \(numRectsPtr :: Ptr Int32) ->+    alloca $ \(rectsPtrPtr :: Ptr (Ptr (Ptr (C'Rect Int32)))) ->+    alloca $ \(rejectLevelsPtrPtr :: Ptr (Ptr Int32)) ->+    alloca $ \(levelWeightsPtrPtr :: Ptr (Ptr C.CDouble)) -> mask_ $ do+      [CU.block| void {+        std::vector<cv::Rect> rects;+        std::vector<int> rejectLevels;+        std::vector<double> levelWeights;+        $(CascadeClassifier * ccPtr)->detectMultiScale(+          *$(Mat * srcPtr),+          rects,+          rejectLevels,+          levelWeights,+          $(double c'scaleFactor),+          $(int32_t c'minNeighbours),+          0,+          *$(Size2i * minSizePtr),+          *$(Size2i * maxSizePtr),+          true);+        *$(int32_t * numRectsPtr) = rects.size();++        cv::Rect * * rectsPtr = new cv::Rect * [rects.size()];+        *$(Rect2i * * * rectsPtrPtr) = rectsPtr;++        int32_t * rejectLevelsPtr = new int32_t [rejectLevels.size()];+        *$(int32_t * * rejectLevelsPtrPtr) = rejectLevelsPtr;++        double * levelWeightsPtr = new double [levelWeights.size()];+        *$(double * * levelWeightsPtrPtr) = levelWeightsPtr;+++        for (std::vector<cv::Rect>::size_type i = 0; i != rects.size(); i++) {++          rectsPtr[i] = new cv::Rect(rects[i]);+          rejectLevelsPtr[i] = rejectLevels[i];+          levelWeightsPtr[i] = levelWeights[i];+        }+      } |]+      numRects <- fromIntegral <$> peek numRectsPtr+      rectsPtr <- peek rectsPtrPtr+      rejectLevelsPtr <- peek rejectLevelsPtrPtr+      levelWeightsPtr <- peek levelWeightsPtrPtr+      rects :: [Rect Int32] <- peekArray numRects rectsPtr >>= mapM (fromPtr . return)+      rejectLevels :: [Int32] <- peekArray numRects rejectLevelsPtr -- >>= mapM (fromPtr . return)+      levelWeights :: [Double] <- map realToFrac <$> peekArray numRects levelWeightsPtr++      [CU.block| void {+      delete [] *$(Rect2i * * * rectsPtrPtr);+      delete [] *$(int32_t  * * rejectLevelsPtrPtr);+      delete [] *$(double * * levelWeightsPtrPtr);+      }|]+      return (V.fromList $ zip3 rects rejectLevels levelWeights)+  where+    c'scaleFactor = maybe 1.1 realToFrac scaleFactor+    c'minNeighbours = maybe 3 fromIntegral minNeighbours+    c'minSize = maybe (toSize (V2 0 0)) toSize minSize+    c'maxSize = maybe (toSize (V2 0 0)) toSize maxSize
+ src/OpenCV/ImgProc/ColorMaps.cpp view
@@ -0,0 +1,27 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ColorMaps_0_9631e9b68167076ee89b837a473e459ecefb6d62(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t ccolorMap_27_inline_c_2) {++  try+  {   +          cv::applyColorMap( *srcPtr_inline_c_0+                           , *dstPtr_inline_c_1+                           , ccolorMap_27_inline_c_2+                           );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/ImgProc/ColorMaps.hsc view
@@ -0,0 +1,161 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.ImgProc.ColorMaps+    ( ColorMap(..)+    , applyColorMap+    ) where++import "base" Data.Int+import "base" Data.Word+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++data ColorMap+   = ColorMapAutumn  -- ^ <<doc/generated/examples/colorMapAutumImg.png   colorMapAutumImg  >>+   | ColorMapBone    -- ^ <<doc/generated/examples/colorMapBoneImg.png    colorMapBoneImg   >>+   | ColorMapJet     -- ^ <<doc/generated/examples/colorMapJetImg.png     colorMapJetImg    >>+   | ColorMapWinter  -- ^ <<doc/generated/examples/colorMapWinterImg.png  colorMapWinterImg >>+   | ColorMapRainbow -- ^ <<doc/generated/examples/colorMapRainbowImg.png colorMapRainbowImg>>+   | ColorMapOcean   -- ^ <<doc/generated/examples/colorMapOceanImg.png   colorMapOceanImg  >>+   | ColorMapSummer  -- ^ <<doc/generated/examples/colorMapSummerImg.png  colorMapSummerImg >>+   | ColorMapSpring  -- ^ <<doc/generated/examples/colorMapSpringImg.png  colorMapSpringImg >>+   | ColorMapCool    -- ^ <<doc/generated/examples/colorMapCoolImg.png    colorMapCoolImg   >>+   | ColorMapHsv     -- ^ <<doc/generated/examples/colorMapHsvImg.png     colorMapHsvImg    >>+   | ColorMapPink    -- ^ <<doc/generated/examples/colorMapPinkImg.png    colorMapPinkImg   >>+   | ColorMapHot     -- ^ <<doc/generated/examples/colorMapHotImg.png     colorMapHotImg    >>+   | ColorMapParula  -- ^ <<doc/generated/examples/colorMapParulaImg.png  colorMapParulaImg >>++#num COLORMAP_AUTUMN+#num COLORMAP_BONE+#num COLORMAP_JET+#num COLORMAP_WINTER+#num COLORMAP_RAINBOW+#num COLORMAP_OCEAN+#num COLORMAP_SUMMER+#num COLORMAP_SPRING+#num COLORMAP_COOL+#num COLORMAP_HSV+#num COLORMAP_PINK+#num COLORMAP_HOT+#num COLORMAP_PARULA++marshalColorMap :: ColorMap -> Int32+marshalColorMap = \case+   ColorMapAutumn  -> c'COLORMAP_AUTUMN+   ColorMapBone    -> c'COLORMAP_BONE+   ColorMapJet     -> c'COLORMAP_JET+   ColorMapWinter  -> c'COLORMAP_WINTER+   ColorMapRainbow -> c'COLORMAP_RAINBOW+   ColorMapOcean   -> c'COLORMAP_OCEAN+   ColorMapSummer  -> c'COLORMAP_SUMMER+   ColorMapSpring  -> c'COLORMAP_SPRING+   ColorMapCool    -> c'COLORMAP_COOL+   ColorMapHsv     -> c'COLORMAP_HSV+   ColorMapPink    -> c'COLORMAP_PINK+   ColorMapHot     -> c'COLORMAP_HOT+   ColorMapParula  -> c'COLORMAP_PARULA++{- | Applies a GNU Octave/MATLAB equivalent colormap on a given image++The human perception isn’t built for observing fine changes in grayscale+images. Human eyes are more sensitive to observing changes between colors, so+you often need to recolor your grayscale images to get a clue about+them. OpenCV now comes with various colormaps to enhance the visualization in+your computer vision application.++Example:++@+grayscaleImg+    :: forall (height :: Nat) (width :: Nat) depth+     . (height ~ 30, width ~ 256, depth ~ Word8)+    => Mat (ShapeT [height, width]) ('S 1) ('S depth)+grayscaleImg = exceptError $+    matFromFunc+      (Proxy :: Proxy [height, width])+      (Proxy :: Proxy 1)+      (Proxy :: Proxy depth)+      grayscale+  where+    grayscale :: [Int] -> Int -> Word8+    grayscale [_y, x] 0 = fromIntegral x+    grayscale _pos _channel = error "impossible"++type ColorMapImg = Mat (ShapeT [30, 256]) ('S 3) ('S Word8)++mkColorMapImg :: ColorMap -> ColorMapImg+mkColorMapImg cmap = exceptError $ applyColorMap cmap grayscaleImg++colorMapAutumImg   :: ColorMapImg+colorMapBoneImg    :: ColorMapImg+colorMapJetImg     :: ColorMapImg+colorMapWinterImg  :: ColorMapImg+colorMapRainbowImg :: ColorMapImg+colorMapOceanImg   :: ColorMapImg+colorMapSummerImg  :: ColorMapImg+colorMapSpringImg  :: ColorMapImg+colorMapCoolImg    :: ColorMapImg+colorMapHsvImg     :: ColorMapImg+colorMapPinkImg    :: ColorMapImg+colorMapHotImg     :: ColorMapImg+colorMapParulaImg  :: ColorMapImg++colorMapAutumImg   = mkColorMapImg ColorMapAutumn+colorMapBoneImg    = mkColorMapImg ColorMapBone+colorMapJetImg     = mkColorMapImg ColorMapJet+colorMapWinterImg  = mkColorMapImg ColorMapWinter+colorMapRainbowImg = mkColorMapImg ColorMapRainbow+colorMapOceanImg   = mkColorMapImg ColorMapOcean+colorMapSummerImg  = mkColorMapImg ColorMapSummer+colorMapSpringImg  = mkColorMapImg ColorMapSpring+colorMapCoolImg    = mkColorMapImg ColorMapCool+colorMapHsvImg     = mkColorMapImg ColorMapHsv+colorMapPinkImg    = mkColorMapImg ColorMapPink+colorMapHotImg     = mkColorMapImg ColorMapHot+colorMapParulaImg  = mkColorMapImg ColorMapParula+@++<<doc/generated/examples/grayscaleImg.png grayscaleImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/colormaps.html#applycolormap OpenCV Sphinx doc>+-}+applyColorMap+    :: ColorMap+    -> Mat shape ('S 1) ('S Word8)+    -> CvExcept (Mat shape ('S 3) ('S Word8))+applyColorMap colorMap src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          cv::applyColorMap( *$(Mat * srcPtr)+                           , *$(Mat * dstPtr)+                           , $(int32_t c'colorMap)+                           );+        |]+  where+    c'colorMap = marshalColorMap colorMap
+ src/OpenCV/ImgProc/Drawing.cpp view
@@ -0,0 +1,214 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_0_3a0520f15da2fc2b3962c29cc5c120d9a9c18abf(Mat * matPtr_inline_c_0, Point2i * pt1Ptr_inline_c_1, Point2i * pt2Ptr_inline_c_2, Scalar * colorPtr_inline_c_3, int32_t thickness_inline_c_4, int32_t clineType_27_inline_c_5, int32_t shift_inline_c_6, double ctipLength_27_inline_c_7) {++        cv::arrowedLine( *matPtr_inline_c_0+                       , *pt1Ptr_inline_c_1+                       , *pt2Ptr_inline_c_2+                       , *colorPtr_inline_c_3+                       , thickness_inline_c_4+                       , clineType_27_inline_c_5+                       , shift_inline_c_6+                       , ctipLength_27_inline_c_7+                       )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_1_daca4286248a7ee2ccda3f206be5689da30871fe(Mat * matPtr_inline_c_0, Point2i * centerPtr_inline_c_1, int32_t radius_inline_c_2, Scalar * colorPtr_inline_c_3, int32_t thickness_inline_c_4, int32_t clineType_27_inline_c_5, int32_t shift_inline_c_6) {++        cv::circle( *matPtr_inline_c_0+                  , *centerPtr_inline_c_1+                  , radius_inline_c_2+                  , *colorPtr_inline_c_3+                  , thickness_inline_c_4+                  , clineType_27_inline_c_5+                  , shift_inline_c_6+                  )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_2_3cbae587154ddb0812861be9b3f0d9acdceae727(Mat * matPtr_inline_c_0, Point2i * centerPtr_inline_c_1, Size2i * axesPtr_inline_c_2, double cangle_27_inline_c_3, double cstartAngle_27_inline_c_4, double cendAngle_27_inline_c_5, Scalar * colorPtr_inline_c_6, int32_t thickness_inline_c_7, int32_t clineType_27_inline_c_8, int32_t shift_inline_c_9) {++        cv::ellipse( *matPtr_inline_c_0+                   , *centerPtr_inline_c_1+                   , *axesPtr_inline_c_2+                   , cangle_27_inline_c_3+                   , cstartAngle_27_inline_c_4+                   , cendAngle_27_inline_c_5+                   , *colorPtr_inline_c_6+                   , thickness_inline_c_7+                   , clineType_27_inline_c_8+                   , shift_inline_c_9+                   )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_3_031c409cd06f5215f5e4a5670cb5b25eccb4ca11(Mat * matPtr_inline_c_0, Point2i * pointsPtr_inline_c_1, int32_t cnumPoints_27_inline_c_2, Scalar * colorPtr_inline_c_3, int32_t clineType_27_inline_c_4, int32_t shift_inline_c_5) {++        cv::fillConvexPoly( *matPtr_inline_c_0+                          , pointsPtr_inline_c_1+                          , cnumPoints_27_inline_c_2+                          , *colorPtr_inline_c_3+                          , clineType_27_inline_c_4+                          , shift_inline_c_5+                          )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_4_87a75e1d46e9256c81dbe6273a64341fe7c2cfe7(Mat * matPtr_inline_c_0, const Point2i ** polygonsPtr_inline_c_1, int32_t * nptsPtr_inline_c_2, int32_t cnumPolygons_27_inline_c_3, Scalar * colorPtr_inline_c_4, int32_t clineType_27_inline_c_5, int32_t shift_inline_c_6) {++        cv::fillPoly( *matPtr_inline_c_0+                    , polygonsPtr_inline_c_1+                    , nptsPtr_inline_c_2+                    , cnumPolygons_27_inline_c_3+                    , *colorPtr_inline_c_4+                    , clineType_27_inline_c_5+                    , shift_inline_c_6+                    )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_5_94d9ed25c5bccafc37420981e18c6003529185f3(Mat * matPtr_inline_c_0, const Point2i ** curvesPtr_inline_c_1, int32_t * nptsPtr_inline_c_2, int32_t cnumCurves_27_inline_c_3, bool cisClosed_27_inline_c_4, Scalar * colorPtr_inline_c_5, int32_t thickness_inline_c_6, int32_t clineType_27_inline_c_7, int32_t shift_inline_c_8) {++        cv::polylines+        ( *matPtr_inline_c_0+        , curvesPtr_inline_c_1+        , nptsPtr_inline_c_2+        , cnumCurves_27_inline_c_3+        , cisClosed_27_inline_c_4+        , *colorPtr_inline_c_5+        , thickness_inline_c_6+        , clineType_27_inline_c_7+        , shift_inline_c_8+        );+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_6_6ffd1c2cabd6b1495a585104598e09378cca874b(Mat * matPtr_inline_c_0, Point2i * pt1Ptr_inline_c_1, Point2i * pt2Ptr_inline_c_2, Scalar * colorPtr_inline_c_3, int32_t thickness_inline_c_4, int32_t clineType_27_inline_c_5, int32_t shift_inline_c_6) {++        cv::line( *matPtr_inline_c_0+                , *pt1Ptr_inline_c_1+                , *pt2Ptr_inline_c_2+                , *colorPtr_inline_c_3+                , thickness_inline_c_4+                , clineType_27_inline_c_5+                , shift_inline_c_6+                )+      ;+}++}++extern "C" {+Size2i * inline_c_OpenCV_ImgProc_Drawing_7_68fda68cf830daae4fb5f792ee50138e035ec7bc(char * ctext_27_inline_c_0, int32_t cfontFace_27_inline_c_1, double cfontScale_27_inline_c_2, int32_t thickness_inline_c_3, int32_t * cbaseLinePtr_27_inline_c_4) {++          Size size = cv::getTextSize( ctext_27_inline_c_0+                                     , cfontFace_27_inline_c_1+                                     , cfontScale_27_inline_c_2+                                     , thickness_inline_c_3+                                     , cbaseLinePtr_27_inline_c_4+                                     );+          return new Size(size);+        +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_8_6328657f90b4ad0a72d22e3bfae3609a8ac9c164(Mat * matPtr_inline_c_0, char * ctext_27_inline_c_1, Point2i * orgPtr_inline_c_2, int32_t cfontFace_27_inline_c_3, double cfontScale_27_inline_c_4, Scalar * colorPtr_inline_c_5, int32_t thickness_inline_c_6, int32_t clineType_27_inline_c_7, bool cbottomLeftOrigin_27_inline_c_8) {++        cv::putText( *matPtr_inline_c_0+                   , ctext_27_inline_c_1+                   , *orgPtr_inline_c_2+                   , cfontFace_27_inline_c_3+                   , cfontScale_27_inline_c_4+                   , *colorPtr_inline_c_5+                   , thickness_inline_c_6+                   , clineType_27_inline_c_7+                   , cbottomLeftOrigin_27_inline_c_8+                   )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_9_29c08dfd62c9d47ba6b543619ed3098b9438d5b2(Mat * matPtr_inline_c_0, Rect2i * rectPtr_inline_c_1, Scalar * colorPtr_inline_c_2, int32_t thickness_inline_c_3, int32_t clineType_27_inline_c_4, int32_t shift_inline_c_5) {++        cv::rectangle( *matPtr_inline_c_0+                     , *rectPtr_inline_c_1+                     , *colorPtr_inline_c_2+                     , thickness_inline_c_3+                     , clineType_27_inline_c_4+                     , shift_inline_c_5+                     )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_10_498c9f67c0218fe7be40785d262dde694e17d039(int32_t * contourLengthsPtr_inline_c_0, Point2i * contoursPtrPtr_inline_c_1, int32_t numContours_inline_c_2, Mat * dstPtr_inline_c_3, Scalar * colorPtr_inline_c_4, int32_t cthickness_27_inline_c_5, int32_t clineType_27_inline_c_6) {++      int32_t *contourLengths = contourLengthsPtr_inline_c_0;+      Point2i * contoursPtr = contoursPtrPtr_inline_c_1;+      std::vector<std::vector<cv::Point>> contours;+      int32_t numContours = numContours_inline_c_2;++      int k = 0;+      for(int i = 0; i < numContours; i++) {+        std::vector<cv::Point> contour;+        for(int j = 0; j < contourLengths[i]; j++) {+          contour.push_back( contoursPtr[k] );+          k++;+        }+        contours.push_back(contour);+      }++      cv::drawContours(+        *dstPtr_inline_c_3,+        contours,+        -1,+        *colorPtr_inline_c_4,+        cthickness_27_inline_c_5,+        clineType_27_inline_c_6+      );+    ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_Drawing_11_5cbadc68dfbca79abe64e3cf58ccba5b4bb72b69(Mat * matPtr_inline_c_0, Point2i * centerPtr_inline_c_1, Scalar * colorPtr_inline_c_2) {++      cv::drawMarker( *matPtr_inline_c_0+                    , *centerPtr_inline_c_1+                    , *colorPtr_inline_c_2)+    ;+}++}
+ src/OpenCV/ImgProc/Drawing.hsc view
@@ -0,0 +1,878 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.ImgProc.Drawing+    ( LineType(..)+    , Font(..)+    , FontFace(..)+    , FontSlant(..)+    , ContourDrawMode(..)+    , arrowedLine+    , circle+    , ellipse+    , fillConvexPoly+    , fillPoly+    , polylines+    , line+    , getTextSize+    , putText+    , rectangle+    , drawContours+    , marker+    ) where++import "base" Data.Int+import qualified "vector" Data.Vector as V+import qualified "vector" Data.Vector.Storable as VS+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( withArray )+import "base" Foreign.Marshal.Utils ( fromBool )+import "base" Foreign.Ptr ( Ptr )+import "base" Foreign.Storable ( peek )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "text" Data.Text ( Text )+import qualified "text" Data.Text as T ( append )+import qualified "text" Data.Text.Foreign as T ( withCStringLen )+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.TypeLevel+import "base" System.IO.Unsafe ( unsafePerformIO )++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++data LineType+   = LineType_8+     -- ^ 8-connected line.+     --+     -- <<doc/generated/LineType_8.png 8-connected line>>+   | LineType_4+     -- ^ 4-connected line.+     --+     -- <<doc/generated/LineType_4.png 4-connected line>>+   | LineType_AA+     -- ^ Antialiased line.+     --+     -- <<doc/generated/LineType_AA.png Antialised line>>+     deriving (Show, Enum, Bounded)++#num LINE_8+#num LINE_4+#num LINE_AA++marshalLineType :: LineType -> Int32+marshalLineType = \case+  LineType_8  -> c'LINE_8+  LineType_4  -> c'LINE_4+  LineType_AA -> c'LINE_AA++data Font+   = Font+     { _fontFace  :: !FontFace+     , _fontSlant :: !FontSlant+     , _fontScale :: !Double+     } deriving (Show)++data FontFace+   = FontHersheySimplex+     -- ^ Normal size sans-serif font. Does not have a 'Slanted' variant.+     --+     -- <<doc/generated/FontHersheySimplex.png FontHersheySimplex>>+   | FontHersheyPlain+     -- ^ Small size sans-serif font.+     --+     -- <<doc/generated/FontHersheyPlain.png FontHersheyPlain>>+     --+     -- <<doc/generated/FontHersheyPlain_slanted.png FontHersheyPlain>>+   | FontHersheyDuplex+     -- ^ Normal size sans-serif font (more complex than+     -- 'FontHersheySimplex'). Does not have a 'Slanted' variant.+     --+     -- <<doc/generated/FontHersheyDuplex.png FontHersheyDuplex>>+   | FontHersheyComplex+     -- ^ Normal size serif font.+     --+     -- <<doc/generated/FontHersheyComplex.png FontHersheyComplex>>+     --+     -- <<doc/generated/FontHersheyComplex_slanted.png FontHersheyComplex>>+   | FontHersheyTriplex+     -- ^ Normal size serif font (more complex than 'FontHersheyComplex').+     --+     -- <<doc/generated/FontHersheyTriplex.png FontHersheyTriplex>>+     --+     -- <<doc/generated/FontHersheyTriplex_slanted.png FontHersheyTriplex>>+   | FontHersheyComplexSmall+     -- ^ Smaller version of 'FontHersheyComplex'.+     --+     -- <<doc/generated/FontHersheyComplexSmall.png FontHersheyComplexSmall>>+     --+     -- <<doc/generated/FontHersheyComplexSmall_slanted.png FontHersheyComplexSmall>>+   | FontHersheyScriptSimplex+     -- ^ Hand-writing style font. Does not have a 'Slanted' variant.+     --+     -- <<doc/generated/FontHersheyScriptSimplex.png FontHersheyScriptSimplex>>+   | FontHersheyScriptComplex+     -- ^ More complex variant of 'FontHersheyScriptSimplex'. Does not have a+     -- 'Slanted' variant.+     --+     -- <<doc/generated/FontHersheyScriptComplex.png FontHersheyScriptComplex>>+     deriving (Show, Enum, Bounded)++data FontSlant+   = NotSlanted+   | Slanted+     deriving (Show)++marshalFont :: Font -> (Int32, C.CDouble)+marshalFont (Font face slant scale) =+    ( marshalFontFace face + marshalFontSlant slant+    , realToFrac scale+    )++#num FONT_ITALIC++marshalFontSlant :: FontSlant -> Int32+marshalFontSlant = \case+   NotSlanted -> 0+   Slanted    -> c'FONT_ITALIC++#num FONT_HERSHEY_SIMPLEX+#num FONT_HERSHEY_PLAIN+#num FONT_HERSHEY_DUPLEX+#num FONT_HERSHEY_COMPLEX+#num FONT_HERSHEY_TRIPLEX+#num FONT_HERSHEY_COMPLEX_SMALL+#num FONT_HERSHEY_SCRIPT_SIMPLEX+#num FONT_HERSHEY_SCRIPT_COMPLEX++marshalFontFace :: FontFace -> Int32+marshalFontFace = \case+   FontHersheySimplex       -> c'FONT_HERSHEY_SIMPLEX+   FontHersheyPlain         -> c'FONT_HERSHEY_PLAIN+   FontHersheyDuplex        -> c'FONT_HERSHEY_DUPLEX+   FontHersheyComplex       -> c'FONT_HERSHEY_COMPLEX+   FontHersheyTriplex       -> c'FONT_HERSHEY_TRIPLEX+   FontHersheyComplexSmall  -> c'FONT_HERSHEY_COMPLEX_SMALL+   FontHersheyScriptSimplex -> c'FONT_HERSHEY_SCRIPT_SIMPLEX+   FontHersheyScriptComplex -> c'FONT_HERSHEY_SCRIPT_COMPLEX+++{- | Draws a arrow segment pointing from the first point to the second one++Example:++@+arrowedLineImg :: Mat (ShapeT [200, 300]) ('S 4) ('S Word8)+arrowedLineImg = exceptError $+    withMatM+      (Proxy :: Proxy [200, 300])+      (Proxy :: Proxy 4)+      (Proxy :: Proxy Word8)+      transparent $ \\imgM -> do+        arrowedLine imgM (V2  10 130 :: V2 Int32) (V2 190  40 :: V2 Int32) blue 5 LineType_AA 0 0.15+        arrowedLine imgM (V2 210  50 :: V2 Int32) (V2 250 180 :: V2 Int32) red  8 LineType_AA 0 0.4+@++<<doc/generated/examples/arrowedLineImg.png arrowedLineImg>>++<http://docs.opencv.org/3.0.0/d6/d6e/group__imgproc__draw.html#ga0a165a3ca093fd488ac709fdf10c05b2 OpenCV Doxygen doc>+<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#arrowedline OpenCV Sphinx doc>+-}+arrowedLine+    :: ( IsPoint2 fromPoint2 Int32+       , IsPoint2 toPoint2   Int32+       , ToScalar  color+       , PrimMonad m+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> fromPoint2 Int32 -- ^ The point the arrow starts from.+    -> toPoint2 Int32 -- ^ The point the arrow points to.+    -> color -- ^ Line color.+    -> Int32 -- ^ Line thickness.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the point coordinates.+    -> Double -- ^ The length of the arrow tip in relation to the arrow length.+    -> m ()+arrowedLine img pt1 pt2 color thickness lineType shift tipLength =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr (toPoint pt1) $ \pt1Ptr   ->+    withPtr (toPoint pt2) $ \pt2Ptr   ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::arrowedLine( *$(Mat * matPtr)+                       , *$(Point2i * pt1Ptr)+                       , *$(Point2i * pt2Ptr)+                       , *$(Scalar * colorPtr)+                       , $(int32_t thickness)+                       , $(int32_t c'lineType)+                       , $(int32_t shift)+                       , $(double c'tipLength)+                       )+      }|]+  where+    c'lineType  = marshalLineType lineType+    c'tipLength = realToFrac tipLength++{- | Draws a circle.++Example:++@+circleImg :: Mat (ShapeT [200, 400]) ('S 4) ('S Word8)+circleImg = exceptError $+    withMatM+      (Proxy :: Proxy [200, 400])+      (Proxy :: Proxy 4)+      (Proxy :: Proxy Word8)+      transparent $ \\imgM -> do+        lift $ circle imgM (V2 100 100 :: V2 Int32) 90 blue  5  LineType_AA 0+        lift $ circle imgM (V2 300 100 :: V2 Int32) 45 red (-1) LineType_AA 0+@++<<doc/generated/examples/circleImg.png circleImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#circle OpenCV Sphinx doc>+-}+circle+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image where the circle is drawn.+    -> point2 Int32 -- ^ Center of the circle.+    -> Int32 -- ^ Radius of the circle.+    -> color -- ^ Circle color.+    -> Int32 -- ^ Thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn.+    -> LineType -- ^ Type of the circle boundary.+    -> Int32 -- ^ Number of fractional bits in the coordinates of the center and in the radius value.+    -> m ()+circle img center radius color thickness lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr (toPoint center) $ \centerPtr ->+    withPtr (toScalar color) $ \colorPtr  ->+      [C.exp|void {+        cv::circle( *$(Mat * matPtr)+                  , *$(Point2i * centerPtr)+                  , $(int32_t radius)+                  , *$(Scalar * colorPtr)+                  , $(int32_t thickness)+                  , $(int32_t c'lineType)+                  , $(int32_t shift)+                  )+      }|]+  where+    c'lineType  = marshalLineType lineType++{- | Draws a simple or thick elliptic arc or fills an ellipse sector++Example:++@+ellipseImg :: Mat (ShapeT [200, 400]) ('S 4) ('S Word8)+ellipseImg = exceptError $+    withMatM+      (Proxy :: Proxy [200, 400])+      (Proxy :: Proxy 4)+      (Proxy :: Proxy Word8)+      transparent $ \\imgM -> do+        lift $ ellipse imgM (V2 100 100 :: V2 Int32) (V2 90 60 :: V2 Int32)  30  0 360 blue  5  LineType_AA 0+        lift $ ellipse imgM (V2 300 100 :: V2 Int32) (V2 80 40 :: V2 Int32) 160 40 290 red (-1) LineType_AA 0+@++<<doc/generated/examples/ellipseImg.png ellipseImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#ellipse OpenCV Sphinx doc>+-}+ellipse+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , IsSize   size   Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> point2 Int32 -- ^ Center of the ellipse.+    -> size   Int32  -- ^ Half of the size of the ellipse main axes.+    -> Double -- ^ Ellipse rotation angle in degrees.+    -> Double -- ^ Starting angle of the elliptic arc in degrees.+    -> Double -- ^ Ending angle of the elliptic arc in degrees.+    -> color -- ^ Ellipse color.+    -> Int32+       -- ^ Thickness of the ellipse arc outline, if+       -- positive. Otherwise, this indicates that a filled ellipse+       -- sector is to be drawn.+    -> LineType -- ^ Type of the ellipse boundary.+    -> Int32 -- ^ Number of fractional bits in the coordinates of the center and values of axes.+    -> m ()+ellipse img center axes angle startAngle endAngle color thickness lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr (toPoint  center) $ \centerPtr ->+    withPtr (toSize   axes  ) $ \axesPtr   ->+    withPtr (toScalar color ) $ \colorPtr  ->+      [C.exp|void {+        cv::ellipse( *$(Mat * matPtr)+                   , *$(Point2i * centerPtr)+                   , *$(Size2i * axesPtr)+                   , $(double c'angle)+                   , $(double c'startAngle)+                   , $(double c'endAngle)+                   , *$(Scalar * colorPtr)+                   , $(int32_t thickness)+                   , $(int32_t c'lineType)+                   , $(int32_t shift)+                   )+      }|]+  where+    c'angle      = realToFrac angle+    c'startAngle = realToFrac startAngle+    c'endAngle   = realToFrac endAngle+    c'lineType   = marshalLineType lineType++{- | Fills a convex polygon.++The function 'fillConvexPoly' draws a filled convex polygon. This+function is much faster than the function 'fillPoly' . It can fill+not only convex polygons but any monotonic polygon without+self-intersections, that is, a polygon whose contour intersects+every horizontal line (scan line) twice at the most (though, its+top-most and/or the bottom edge could be horizontal).++Example:++@+fillConvexPolyImg+    :: forall (h :: Nat) (w :: Nat)+     . (h ~ 300, w ~ 300)+    => Mat (ShapeT [h, w]) ('S 4) ('S Word8)+fillConvexPolyImg = exceptError $+    withMatM (Proxy :: Proxy [h, w])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ fillConvexPoly imgM pentagon blue LineType_AA 0+  where+    pentagon :: V.Vector (V2 Int32)+    pentagon = V.fromList+               [ V2 150   0+               , V2   7 104+               , V2  62 271+               , V2 238 271+               , V2 293 104+               ]+@++<<doc/generated/examples/fillConvexPolyImg.png fillConvexPolyImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#fillconvexpoly OpenCV Sphinx doc>+-}+fillConvexPoly+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , ToScalar  color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> V.Vector (point2 Int32) -- ^ Polygon vertices.+    -> color -- ^ Polygon color.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the vertex coordinates.+    -> m ()+fillConvexPoly img points color lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withArrayPtr (V.map toPoint points) $ \pointsPtr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::fillConvexPoly( *$(Mat * matPtr)+                          , $(Point2i * pointsPtr)+                          , $(int32_t c'numPoints)+                          , *$(Scalar * colorPtr)+                          , $(int32_t c'lineType)+                          , $(int32_t shift)+                          )+      }|]+  where+    c'numPoints = fromIntegral $ V.length points+    c'lineType  = marshalLineType lineType+++{- | Fills the area bounded by one or more polygons.++Example:++@+rookPts :: Int32 -> Int32 -> V.Vector (V.Vector (V2 Int32))+rookPts w h = V.singleton $ V.fromList+          [ V2 (    w \`div`  4) ( 7*h \`div`  8)+          , V2 (  3*w \`div`  4) ( 7*h \`div`  8)+          , V2 (  3*w \`div`  4) (13*h \`div` 16)+          , V2 ( 11*w \`div` 16) (13*h \`div` 16)+          , V2 ( 19*w \`div` 32) ( 3*h \`div`  8)+          , V2 (  3*w \`div`  4) ( 3*h \`div`  8)+          , V2 (  3*w \`div`  4) (   h \`div`  8)+          , V2 ( 26*w \`div` 40) (   h \`div`  8)+          , V2 ( 26*w \`div` 40) (   h \`div`  4)+          , V2 ( 22*w \`div` 40) (   h \`div`  4)+          , V2 ( 22*w \`div` 40) (   h \`div`  8)+          , V2 ( 18*w \`div` 40) (   h \`div`  8)+          , V2 ( 18*w \`div` 40) (   h \`div`  4)+          , V2 ( 14*w \`div` 40) (   h \`div`  4)+          , V2 ( 14*w \`div` 40) (   h \`div`  8)+          , V2 (    w \`div`  4) (   h \`div`  8)+          , V2 (    w \`div`  4) ( 3*h \`div`  8)+          , V2 ( 13*w \`div` 32) ( 3*h \`div`  8)+          , V2 (  5*w \`div` 16) (13*h \`div` 16)+          , V2 (    w \`div`  4) (13*h \`div` 16)+          ]++fillPolyImg+    :: forall (h :: Nat) (w :: Nat)+     . (h ~ 300, w ~ 300)+    => Mat (ShapeT [h, w]) ('S 4) ('S Word8)+fillPolyImg = exceptError $+    withMatM (Proxy :: Proxy [h, w])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ fillPoly imgM (rookPts w h) blue LineType_AA 0+  where+    h = fromInteger $ natVal (Proxy :: Proxy h)+    w = fromInteger $ natVal (Proxy :: Proxy w)+@++<<doc/generated/examples/fillPolyImg.png fillPolyImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#fillpoly OpenCV Sphinx doc>+-}+fillPoly+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> V.Vector (V.Vector (point2 Int32)) -- ^ Polygons.+    -> color -- ^ Polygon color.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the vertex coordinates.+    -> m ()+fillPoly img polygons color lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPolygons polygons $ \polygonsPtr ->+    VS.unsafeWith npts $ \nptsPtr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::fillPoly( *$(Mat * matPtr)+                    , $(const Point2i * * polygonsPtr)+                    , $(int32_t * nptsPtr)+                    , $(int32_t c'numPolygons)+                    , *$(Scalar * colorPtr)+                    , $(int32_t c'lineType)+                    , $(int32_t shift)+                    )+      }|]+  where+    c'numPolygons = fromIntegral $ V.length polygons+    c'lineType    = marshalLineType lineType++    npts :: VS.Vector Int32+    npts = VS.convert $ V.map (fromIntegral . V.length) polygons++{- | Draws several polygonal curves++Example:++@+polylinesImg+    :: forall (h :: Nat) (w :: Nat)+     . (h ~ 300, w ~ 300)+    => Mat (ShapeT [h, w]) ('S 4) ('S Word8)+polylinesImg = exceptError $+    withMatM (Proxy :: Proxy [h, w])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ polylines imgM (rookPts w h) True blue 2 LineType_AA 0+  where+    h = fromInteger $ natVal (Proxy :: Proxy h)+    w = fromInteger $ natVal (Proxy :: Proxy w)+@++<<doc/generated/examples/polylinesImg.png polylinesImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#polylines OpenCV Sphinx doc>+-}+polylines+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> V.Vector (V.Vector (point2 Int32)) -- ^ Vertices.+    -> Bool+       -- ^ Flag indicating whether the drawn polylines are closed or not. If+       -- they are closed, the function draws a line from the last vertex of+       -- each curve to its first vertex.+    -> color+    -> Int32 -- ^ Thickness of the polyline edges.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the vertex coordinates.+    -> m ()+polylines img curves isClosed color thickness lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPolygons curves $ \curvesPtr ->+    VS.unsafeWith npts $ \nptsPtr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::polylines+        ( *$(Mat * matPtr)+        , $(const Point2i * * curvesPtr)+        , $(int32_t * nptsPtr)+        , $(int32_t c'numCurves)+        , $(bool c'isClosed)+        , *$(Scalar * colorPtr)+        , $(int32_t thickness)+        , $(int32_t c'lineType)+        , $(int32_t shift)+        );+      }|]+  where+    c'numCurves = fromIntegral $ V.length curves+    c'isClosed  = fromBool isClosed+    c'lineType  = marshalLineType lineType++    npts :: VS.Vector Int32+    npts = VS.convert $ V.map (fromIntegral . V.length) curves++{- | Draws a line segment connecting two points.++Example:++@+lineImg :: Mat (ShapeT [200, 300]) ('S 4) ('S Word8)+lineImg = exceptError $+    withMatM (Proxy :: Proxy [200, 300])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ line imgM (V2  10 130 :: V2 Int32) (V2 190  40 :: V2 Int32) blue 5 LineType_AA 0+      lift $ line imgM (V2 210  50 :: V2 Int32) (V2 250 180 :: V2 Int32) red  8 LineType_AA 0+@++<<doc/generated/examples/lineImg.png lineImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#line OpenCV Sphinx doc>+-}+line+    :: ( PrimMonad m+       , IsPoint2 fromPoint2 Int32+       , IsPoint2 toPoint2   Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> fromPoint2 Int32 -- ^ First point of the line segment.+    -> toPoint2   Int32 -- ^ Scond point of the line segment.+    -> color -- ^ Line color.+    -> Int32 -- ^ Line thickness.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the point coordinates.+    -> m ()+line img pt1 pt2 color thickness lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr (toPoint pt1) $ \pt1Ptr ->+    withPtr (toPoint pt2) $ \pt2Ptr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::line( *$(Mat * matPtr)+                , *$(Point2i * pt1Ptr)+                , *$(Point2i * pt2Ptr)+                , *$(Scalar * colorPtr)+                , $(int32_t thickness)+                , $(int32_t c'lineType)+                , $(int32_t shift)+                )+      }|]+  where+    c'lineType = marshalLineType lineType++{- | Calculates the size of a box that contains the specified text++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#gettextsize OpenCV Sphinx doc>+-}+getTextSize+    :: Text+    -> Font+    -> Int32 -- ^ Thickness of lines used to render the text.+    -> (Size2i, Int32)+       -- ^ (size, baseLine) =+       -- (The size of a box that contains the specified text.+       -- , y-coordinate of the baseline relative to the bottom-most text point)+getTextSize text font thickness = unsafePerformIO $+    T.withCStringLen (T.append text "\0") $ \(c'text, _textLength) ->+    alloca $ \(c'baseLinePtr :: Ptr Int32) -> do+      size <- fromPtr $+        [C.block|Size2i * {+          Size size = cv::getTextSize( $(char * c'text)+                                     , $(int32_t c'fontFace)+                                     , $(double c'fontScale)+                                     , $(int32_t thickness)+                                     , $(int32_t * c'baseLinePtr)+                                     );+          return new Size(size);+        }|]+      baseLine <- peek c'baseLinePtr+      pure (size, baseLine)+  where+    (c'fontFace, c'fontScale) = marshalFont font++{- | Draws a text string.++The function putText renders the specified text string in the+image. Symbols that cannot be rendered using the specified font are+replaced by question marks.++Example:++@+putTextImg :: Mat ('S ['D, 'S 400]) ('S 4) ('S Word8)+putTextImg = exceptError $+    withMatM (height ::: (Proxy :: Proxy 400) ::: Z)+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      forM_ (zip [0..] [minBound .. maxBound]) $ \\(n, fontFace) ->+        lift $ putText imgM+                       (T.pack $ show fontFace)+                       (V2 10 (35 + n * 30) :: V2 Int32)+                       (Font fontFace NotSlanted 1.0)+                       black+                       1+                       LineType_AA+                       False+  where+    height :: Int32+    height = 50 + fromIntegral (30 * fromEnum (maxBound :: FontFace))+@++<<doc/generated/examples/putTextImg.png putTextImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#puttext OpenCV Sphinx doc>+-}+putText+    :: ( PrimMonad m+       , IsPoint2 point2 Int32+       , ToScalar color+       )+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> Text -- ^ Text string to be drawn.+    -> point2 Int32 -- ^ Bottom-left corner of the text string in the image.+    -> Font+    -> color -- ^ Text color.+    -> Int32 -- ^ Thickness of the lines used to draw a text.+    -> LineType+    -> Bool -- ^ When 'True', the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.+    -> m ()+putText img text org font color thickness lineType bottomLeftOrigin =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    T.withCStringLen (T.append text "\0") $ \(c'text, _textLength) ->+    withPtr (toPoint org) $ \orgPtr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::putText( *$(Mat * matPtr)+                   , $(char * c'text)+                   , *$(Point2i * orgPtr)+                   , $(int32_t c'fontFace)+                   , $(double c'fontScale)+                   , *$(Scalar * colorPtr)+                   , $(int32_t thickness)+                   , $(int32_t c'lineType)+                   , $(bool c'bottomLeftOrigin)+                   )+      }|]+  where+    (c'fontFace, c'fontScale) = marshalFont font+    c'lineType = marshalLineType lineType+    c'bottomLeftOrigin = fromBool bottomLeftOrigin++{- | Draws a simple, thick, or filled up-right rectangle++Example:++@+rectangleImg :: Mat (ShapeT [200, 400]) ('S 4) ('S Word8)+rectangleImg = exceptError $+    withMatM (Proxy :: Proxy [200, 400])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ rectangle imgM (toRect $ HRect (V2  10 10) (V2 180 180)) blue  5  LineType_8 0+      lift $ rectangle imgM (toRect $ HRect (V2 260 30) (V2  80 140)) red (-1) LineType_8 0+@++<<doc/generated/examples/rectangleImg.png rectangleImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/drawing_functions.html#rectangle OpenCV Sphinx doc>+-}+rectangle+    :: (PrimMonad m, ToScalar color, IsRect rect Int32)+    => Mut (Mat ('S [height, width]) channels depth) (PrimState m) -- ^ Image.+    -> rect Int32+    -> color -- ^ Rectangle color or brightness (grayscale image).+    -> Int32 -- ^ Line thickness.+    -> LineType+    -> Int32 -- ^ Number of fractional bits in the point coordinates.+    -> m ()+rectangle img rect color thickness lineType shift =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr (toRect rect) $ \rectPtr ->+    withPtr (toScalar color) $ \colorPtr ->+      [C.exp|void {+        cv::rectangle( *$(Mat * matPtr)+                     , *$(Rect2i * rectPtr)+                     , *$(Scalar * colorPtr)+                     , $(int32_t thickness)+                     , $(int32_t c'lineType)+                     , $(int32_t shift)+                     )+      }|]+  where+    c'lineType = marshalLineType lineType+++data ContourDrawMode+  = OutlineContour LineType+                   Int32 -- ^ Thickness of lines the contours are drawn with.+  | FillContours -- ^ Draw the contour, filling in the area.++marshalContourDrawMode+  :: ContourDrawMode -> (Int32, Int32)+marshalContourDrawMode = \case+  OutlineContour lineType thickness -> (marshalLineType lineType, thickness)+  FillContours -> (marshalLineType LineType_4, -1)++{-|++Draw contours onto a black image.++Example:++@+flowerContours :: Mat ('S ['S 512, 'S 768]) ('S 3) ('S Word8)+flowerContours = exceptError $+  withMatM (Proxy :: Proxy [512,768])+           (Proxy :: Proxy 3)+           (Proxy :: Proxy Word8)+           black $ \\imgM -> do+    edges <- thaw $ exceptError $+             cvtColor bgr gray flower_768x512 >>=+             canny 30 20 Nothing CannyNormL1+    contours <- findContours ContourRetrievalList+                             ContourApproximationSimple edges+    lift $ drawContours (V.map contourPoints contours)+                        red+                        (OutlineContour LineType_AA 1)+                        imgM+@++<<doc/generated/examples/flowerContours.png flowerContours>>++-}+drawContours :: (ToScalar color, PrimMonad m)+             => V.Vector (V.Vector Point2i)+             -> color -- ^ Color of the contours.+             -> ContourDrawMode+             -> Mut (Mat ('S [h, w]) channels depth) (PrimState m) -- ^ Image.+             -> m ()+drawContours contours color drawMode img = unsafePrimToPrim $+  withArrayPtr (V.concat (V.toList contours)) $ \contoursPtrPtr ->+  withArray (V.toList (V.map (fromIntegral . V.length) contours)) $ \(contourLengthsPtr :: Ptr Int32) ->+  withPtr (toScalar color) $ \colorPtr ->+  withPtr img $ \dstPtr ->+    [C.exp|void {+      int32_t *contourLengths = $(int32_t * contourLengthsPtr);+      Point2i * contoursPtr = $(Point2i * contoursPtrPtr);+      std::vector<std::vector<cv::Point>> contours;+      int32_t numContours = $(int32_t numContours);++      int k = 0;+      for(int i = 0; i < numContours; i++) {+        std::vector<cv::Point> contour;+        for(int j = 0; j < contourLengths[i]; j++) {+          contour.push_back( contoursPtr[k] );+          k++;+        }+        contours.push_back(contour);+      }++      cv::drawContours(+        *$(Mat * dstPtr),+        contours,+        -1,+        *$(Scalar * colorPtr),+        $(int32_t c'thickness),+        $(int32_t c'lineType)+      );+    }|]+  where+    numContours = fromIntegral (V.length contours)+    (c'lineType, c'thickness) = marshalContourDrawMode drawMode++{-| Draws a marker on a predefined position in an image.++The marker will be drawn as as a 20-pixel cross.++Example:++@+markerImg :: Mat (ShapeT [100, 100]) ('S 4) ('S Word8)+markerImg = exceptError $+    withMatM (Proxy :: Proxy [100, 100])+             (Proxy :: Proxy 4)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      lift $ marker imgM (50 :: V2 Int32) blue+@++<<doc/generated/examples/markerImg.png markerImg>>+-}+marker+  :: (PrimMonad m, IsPoint2 point2 Int32, ToScalar color)+  => Mut (Mat ('S '[ height, width]) channels depth) (PrimState m)+    -- ^ The image to draw the marker on.+  -> point2 Int32+    -- ^ The point where the crosshair is positioned.+  -> color+    -- ^ Line color.+  -> m ()+marker img center color =+  unsafePrimToPrim $+  withPtr img $ \matPtr ->+  withPtr (toPoint center) $ \centerPtr ->+  withPtr (toScalar color) $ \colorPtr  ->+    [C.exp|void {+      cv::drawMarker( *$(Mat * matPtr)+                    , *$(Point2i * centerPtr)+                    , *$(Scalar * colorPtr))+    }|]
+ src/OpenCV/ImgProc/FeatureDetection.cpp view
@@ -0,0 +1,157 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_FeatureDetection_0_5f88cbbf14721ff0e52026e5bf93249a196cdb8c(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, double cthreshold1_27_inline_c_2, double cthreshold2_27_inline_c_3, int32_t capertureSize_27_inline_c_4, bool cl2Gradient_27_inline_c_5) {++  try+  {   +          cv::Canny+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , cthreshold1_27_inline_c_2+          , cthreshold2_27_inline_c_3+          , capertureSize_27_inline_c_4+          , cl2Gradient_27_inline_c_5+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_FeatureDetection_1_d3ad35ecbcac628897a1552ca7c9008021f820e4(Mat * mskPtr_inline_c_0, Mat * srcPtr_inline_c_1, int32_t maxCorners_inline_c_2, double cqualityLevel_27_inline_c_3, double cminDistance_27_inline_c_4, int32_t cblockSize_27_inline_c_5, bool cuseHarrisDetector_27_inline_c_6, double charrisK_27_inline_c_7, Point2f *** cornersPtrPtr_inline_c_8, int32_t * cornersLengthsPtr_inline_c_9) {++      std::vector<cv::Point2f> corners;+      Mat * mskPtr = mskPtr_inline_c_0;+      cv::goodFeaturesToTrack+      ( *srcPtr_inline_c_1+      , corners+      , maxCorners_inline_c_2+      , cqualityLevel_27_inline_c_3+      , cminDistance_27_inline_c_4+      , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+      , cblockSize_27_inline_c_5+      , cuseHarrisDetector_27_inline_c_6+      , charrisK_27_inline_c_7+      );++      cv::Point2f * * * cornersPtrPtr = cornersPtrPtr_inline_c_8;+      cv::Point2f * * cornersPtr = new cv::Point2f * [corners.size()];+      *cornersPtrPtr = cornersPtr;++      *cornersLengthsPtr_inline_c_9 = corners.size();++      for (std::vector<cv::Point2f>::size_type i = 0; i != corners.size(); i++) {+        cornersPtr[i] = new cv::Point2f( corners[i] );+      }+    +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_FeatureDetection_2_c9d92b710b149101347a9c45ed5938492191af5c(Point2f *** cornersPtrPtr_inline_c_0) {++      delete [] *cornersPtrPtr_inline_c_0;+    +}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_FeatureDetection_3_a4f81dd096a5abe34749e20b9be735232e6748b4(Mat * srcPtr_inline_c_0, double cdp_27_inline_c_1, double cminDist_27_inline_c_2, double cparam1_27_inline_c_3, double cparam2_27_inline_c_4, int32_t cminRadius_27_inline_c_5, int32_t cmaxRadius_27_inline_c_6, Vec3f *** circlesPtrPtr_inline_c_7, int32_t * circleLengthsPtr_inline_c_8) {++  try+  {   +      std::vector<cv::Vec3f> circles;+      cv::HoughCircles(+        *srcPtr_inline_c_0,+        circles,+        CV_HOUGH_GRADIENT,+        cdp_27_inline_c_1,+        cminDist_27_inline_c_2,+        cparam1_27_inline_c_3,+        cparam2_27_inline_c_4,+        cminRadius_27_inline_c_5,+        cmaxRadius_27_inline_c_6+      );++      cv::Vec3f * * * circlesPtrPtr = circlesPtrPtr_inline_c_7;+      cv::Vec3f * * circlesPtr = new cv::Vec3f * [circles.size()];+      *circlesPtrPtr = circlesPtr;++      *circleLengthsPtr_inline_c_8 = circles.size();++      for (std::vector<cv::Vec3f>::size_type i = 0; i != circles.size(); i++) {+        circlesPtr[i] = new cv::Vec3f( circles[i] );+      }+    +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_FeatureDetection_4_c6446509d1918e78bf046dd1d2f1c932e3ccf9f6(Vec3f *** circlesPtrPtr_inline_c_0) {+ delete [] *circlesPtrPtr_inline_c_0; +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_FeatureDetection_5_e55ed1c705d2d80d10931b28319c21af80a9d7e0(Mat * srcPtr_inline_c_0, double crho_27_inline_c_1, double ctheta_27_inline_c_2, int32_t threshold_inline_c_3, double cminLineLength_27_inline_c_4, double cmaxLineGap_27_inline_c_5, int32_t * numLinesPtr_inline_c_6, Vec4i *** linesPtrPtr_inline_c_7) {++        std::vector<cv::Vec4i> lines = std::vector<cv::Vec4i>();+        cv::HoughLinesP+          ( *srcPtr_inline_c_0+          , lines+          , crho_27_inline_c_1+          , ctheta_27_inline_c_2+          , threshold_inline_c_3+          , cminLineLength_27_inline_c_4+          , cmaxLineGap_27_inline_c_5+          );++        *numLinesPtr_inline_c_6 = lines.size();++        cv::Vec4i * * * linesPtrPtr = linesPtrPtr_inline_c_7;+        cv::Vec4i * * linesPtr = new cv::Vec4i * [lines.size()];+        *linesPtrPtr = linesPtr;++        for (std::vector<cv::Vec4i>::size_type ix = 0; ix != lines.size(); ix++)+        {+          cv::Vec4i & org = lines[ix];+          cv::Vec4i * newLine = new cv::Vec4i(org[0], org[1], org[2], org[3]);+          linesPtr[ix] = newLine;+        }+      +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_FeatureDetection_6_38d283b332ccfda6ddffce48d6828cd1a8dde2d9(Vec4i *** linesPtrPtr_inline_c_0) {++        delete [] *linesPtrPtr_inline_c_0;+      +}++}
+ src/OpenCV/ImgProc/FeatureDetection.hs view
@@ -0,0 +1,469 @@+{-# language CPP #-}+{-# language DeriveFunctor #-}+{-# language DeriveTraversable #-}+{-# language MultiParamTypeClasses #-}+{-# language NoImplicitPrelude #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}+{-# language UndecidableInstances #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.ImgProc.FeatureDetection+    ( canny+    , goodFeaturesToTrack+    , houghCircles+    , houghLinesP+    , GoodFeaturesToTrackDetectionMethod(..)+    , CannyNorm(..)+    , Circle(..)+    , LineSegment(..)+    ) where++import "base" Control.Exception ( mask_ )+import "base" Data.Int+import "base" Data.Maybe+import qualified "vector" Data.Vector as V+import "base" Data.Word+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( peekArray )+import "base" Foreign.Marshal.Utils ( fromBool )+import "base" Foreign.Ptr ( Ptr )+import "base" Foreign.Storable ( peek )+import "base" Prelude hiding ( lines )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear ( V2(..), V3(..), V4(..) )+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel+#if MIN_VERSION_base(4,9,0)+import "base" Data.Foldable ( Foldable )+import "base" Data.Traversable ( Traversable )+#endif++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------+-- Feature Detection+--------------------------------------------------------------------------------++{- |++Finds edges in an image using the+<http://docs.opencv.org/2.4/modules/imgproc/doc/feature_detection.html#canny86 Canny86>+algorithm.++Example:++@+cannyImg+    :: forall shape channels depth+     . (Mat shape channels depth ~ Lambda)+    => Mat shape ('S 1) depth+cannyImg = exceptError $+  canny 30 200 Nothing CannyNormL1 lambda+@++<<doc/generated/examples/cannyImg.png cannyImg>>++-}+canny+    :: Double+       -- ^ First threshold for the hysteresis procedure.+    -> Double+       -- ^ Second threshold for the hysteresis procedure.+    -> Maybe Int32+       -- ^ Aperture size for the @Sobel()@ operator. If not specified defaults+       -- to @3@. Must be 3, 5 or 7.+    -> CannyNorm+       -- ^ A flag, indicating whether to use the more accurate L2 norm or the default L1 norm.+    -> Mat ('S [h, w]) channels ('S Word8)+       -- ^ 8-bit input image.+    -> CvExcept (Mat ('S [h, w]) ('S 1) ('S Word8))+canny threshold1 threshold2 apertureSize norm src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          cv::Canny+          ( *$(Mat * srcPtr)+          , *$(Mat * dstPtr)+          , $(double c'threshold1)+          , $(double c'threshold2)+          , $(int32_t c'apertureSize)+          , $(bool c'l2Gradient)+          );+        |]+  where+    c'threshold1 = realToFrac threshold1+    c'threshold2 = realToFrac threshold2+    c'apertureSize = fromMaybe 3 apertureSize+    c'l2Gradient =+      fromBool $+        case norm of+          CannyNormL1 -> False+          CannyNormL2 -> True++-- | A flag, indicating whether to use the more accurate L2 norm or the default L1 norm.+data CannyNorm+   = CannyNormL1+   | CannyNormL2+   deriving (Show, Eq)++data Circle+   = Circle+     { circleCenter :: V2 Float+     , circleRadius :: Float+     } deriving (Show)++{- |++Determines strong corners on an image.++The function finds the most prominent corners in the image or in the specified image region.++* Function calculates the corner quality measure at every source image pixel using the cornerMinEigenVal or cornerHarris.+* Function performs a non-maximum suppression (the local maximums in 3 x 3 neighborhood are retained).+* The corners with the minimal eigenvalue less than @𝚚𝚞𝚊𝚕𝚒𝚝𝚢𝙻𝚎𝚟𝚎𝚕 * max(x,y) qualityMeasureMap(x,y)@ are rejected.+* The remaining corners are sorted by the quality measure in the descending order.+* Function throws away each corner for which there is a stronger corner at a distance less than maxDistance.++Example:++@+goodFeaturesToTrackTraces+    :: forall (width    :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog)+    => Mat (ShapeT [height, width]) ('S channels) ('S depth)+goodFeaturesToTrackTraces = exceptError $ do+  imgG <- cvtColor bgr gray frog+  let features = goodFeaturesToTrack imgG 20 0.01 0.5 Nothing Nothing CornerMinEigenVal+  withMatM (Proxy :: Proxy [height, width])+           (Proxy :: Proxy channels)+           (Proxy :: Proxy depth)+           white $ \\imgM -> do+    void $ matCopyToM imgM (V2 0 0) frog Nothing+    forM_ features $ \\f -> do+      circle imgM (round \<$> f :: V2 Int32) 2 blue 5 LineType_AA 0+@++<<doc/generated/examples/goodFeaturesToTrackTraces.png goodFeaturesToTrackTraces>>+-}+goodFeaturesToTrack+  :: (depth `In` ['S Word8, 'S Float, 'D])+  => Mat ('S [h, w]) ('S 1) depth+  -- ^ Input 8-bit or floating-point 32-bit, single-channel image.+  -> Int32+  -- ^ Maximum number of corners to return. If there are more corners than are+  -- found, the strongest of them is returned.+  -> Double+  -- ^ Parameter characterizing the minimal accepted quality of image corners.+  -- The parameter value is multiplied by the best corner quality measure,+  -- which is the minimal eigenvalue (see cornerMinEigenVal ) or the Harris+  -- function response (see cornerHarris ). The corners with the quality measure+  -- less than the product are rejected. For example, if the best corner has the+  -- quality measure = 1500, and the qualityLevel=0.01 , then all the corners with+  -- the quality measure less than 15 are rejected.+  -> Double+  -- ^ Minimum possible Euclidean distance between the returned corners.+  -> Maybe (Mat ('S [h, w]) ('S 1) ('S Word8))+  -- ^ Optional region of interest. If the image is not empty (it needs to have+  -- the type CV_8UC1 and the same size as image ), it specifies the region in which+  -- the corners are detected.+  -> Maybe Int32+  -- ^ Size of an average block for computing a derivative covariation matrix+  -- over each pixel neighborhood. See cornerEigenValsAndVecs.+  -> GoodFeaturesToTrackDetectionMethod+  -- ^ Parameter indicating whether to use a Harris detector (see cornerHarris)+  -- or cornerMinEigenVal.+  -> V.Vector (V2 Float)+goodFeaturesToTrack src maxCorners qualityLevel minDistance mbMask blockSize detector = unsafePerformIO $ do+  withPtr src  $ \srcPtr ->+    withPtr mbMask $ \mskPtr ->+    alloca $ \(cornersLengthsPtr :: Ptr Int32) ->+    alloca $ \(cornersPtrPtr :: Ptr (Ptr (Ptr C'Point2f))) -> mask_ $ do+    [C.block| void {+      std::vector<cv::Point2f> corners;+      Mat * mskPtr = $(Mat * mskPtr);+      cv::goodFeaturesToTrack+      ( *$(Mat * srcPtr)+      , corners+      , $(int32_t maxCorners)+      , $(double c'qualityLevel)+      , $(double c'minDistance)+      , mskPtr ? _InputArray(*mskPtr) : _InputArray(cv::noArray())+      , $(int32_t c'blockSize)+      , $(bool c'useHarrisDetector)+      , $(double c'harrisK)+      );++      cv::Point2f * * * cornersPtrPtr = $(Point2f * * * cornersPtrPtr);+      cv::Point2f * * cornersPtr = new cv::Point2f * [corners.size()];+      *cornersPtrPtr = cornersPtr;++      *$(int32_t * cornersLengthsPtr) = corners.size();++      for (std::vector<cv::Point2f>::size_type i = 0; i != corners.size(); i++) {+        cornersPtr[i] = new cv::Point2f( corners[i] );+      }+    }|]+    numCorners <- fromIntegral <$> peek cornersLengthsPtr+    cornersPtr <- peek cornersPtrPtr+    (corners :: [V2 Float]) <-+        peekArray numCorners cornersPtr >>=+        mapM (fmap (fmap fromCFloat . fromPoint) . fromPtr . pure)+    [CU.block| void {+      delete [] *$(Point2f * * * cornersPtrPtr);+    }|]+    pure (V.fromList  corners)+  where+    c'qualityLevel = realToFrac qualityLevel+    c'minDistance  = realToFrac minDistance+    c'blockSize    = fromMaybe 3 blockSize+    c'useHarrisDetector =+      fromBool $+        case detector of+          HarrisDetector _kValue -> True+          CornerMinEigenVal -> False+    c'harrisK =+      realToFrac $+        case detector of+          HarrisDetector kValue -> kValue+          CornerMinEigenVal -> 0.04++data GoodFeaturesToTrackDetectionMethod+   = HarrisDetector Double -- ^ Harris detector and it free k parameter+   | CornerMinEigenVal+   deriving (Show, Eq)++{- |++Finds circles in a grayscale image using a modification of the Hough+transformation.++Example:++@+houghCircleTraces+    :: forall (width    :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Circles_1000x625)+    => Mat (ShapeT [height, width]) ('S channels) ('S depth)+houghCircleTraces = exceptError $ do+  imgG <- cvtColor bgr gray circles_1000x625+  let circles = houghCircles 1 10 Nothing Nothing Nothing Nothing imgG+  withMatM (Proxy :: Proxy [height, width])+           (Proxy :: Proxy channels)+           (Proxy :: Proxy depth)+           white $ \\imgM -> do+    void $ matCopyToM imgM (V2 0 0) circles_1000x625 Nothing+    forM_ circles $ \\c -> do+      circle imgM (round \<$> circleCenter c :: V2 Int32) (round (circleRadius c)) blue 1 LineType_AA 0+@++<<doc/generated/examples/houghCircleTraces.png houghCircleTraces>>+-}+houghCircles+  :: Double+     -- ^ Inverse ratio of the accumulator resolution to the image resolution.+     -- For example, if @dp=1@, the accumulator has the same resolution as the+     -- input image. If @dp=2@, the accumulator has half as big width and height.+  -> Double+     -- ^ Minimum distance between the centers of the detected circles. If the+     -- parameter is too small, multiple neighbor circles may be falsely+     -- detected in addition to a true one. If it is too large, some circles may+     -- be missed.+  -> Maybe Double+     -- ^ The higher threshold of the two passed to the 'canny' edge detector+     -- (the lower one is twice smaller). Default is 100.+  -> Maybe Double+     -- ^ The accumulator threshold for the circle centers at the detection+     -- stage. The smaller it is, the more false circles may be detected.+     -- Circles, corresponding to the larger accumulator values, will be returned+     -- first. Default is 100.+  -> Maybe Int32+     -- ^ Minimum circle radius.+  -> Maybe Int32+     -- ^ Maximum circle radius.+  -> Mat ('S [h, w]) ('S 1) ('S Word8)+  -> V.Vector Circle+houghCircles dp minDist param1 param2 minRadius maxRadius src = unsafePerformIO $+  withPtr src $ \srcPtr ->+  alloca $ \(circleLengthsPtr :: Ptr Int32) ->+  alloca $ \(circlesPtrPtr :: Ptr (Ptr (Ptr C'Vec3f))) -> mask_ $ do+    _ <- [cvExcept|+      std::vector<cv::Vec3f> circles;+      cv::HoughCircles(+        *$(Mat * srcPtr),+        circles,+        CV_HOUGH_GRADIENT,+        $(double c'dp),+        $(double c'minDist),+        $(double c'param1),+        $(double c'param2),+        $(int32_t c'minRadius),+        $(int32_t c'maxRadius)+      );++      cv::Vec3f * * * circlesPtrPtr = $(Vec3f * * * circlesPtrPtr);+      cv::Vec3f * * circlesPtr = new cv::Vec3f * [circles.size()];+      *circlesPtrPtr = circlesPtr;++      *$(int32_t * circleLengthsPtr) = circles.size();++      for (std::vector<cv::Vec3f>::size_type i = 0; i != circles.size(); i++) {+        circlesPtr[i] = new cv::Vec3f( circles[i] );+      }+    |]+    numCircles <- fromIntegral <$> peek circleLengthsPtr+    circlesPtr <- peek circlesPtrPtr+    (circles :: [V3 Float]) <-+        peekArray numCircles circlesPtr >>=+        mapM (fmap (fmap fromCFloat . fromVec) . fromPtr . pure)+    [CU.block| void { delete [] *$(Vec3f * * * circlesPtrPtr); }|]+    pure (V.fromList (map (\(V3 x y r) -> Circle (V2 x y) r) circles))+  where c'dp = realToFrac dp+        c'minDist = realToFrac minDist+        c'param1 = realToFrac (fromMaybe 100 param1)+        c'param2 = realToFrac (fromMaybe 100 param2)+        c'minRadius = fromIntegral (fromMaybe 0 minRadius)+        c'maxRadius = fromIntegral (fromMaybe 0 maxRadius)++data LineSegment depth+   = LineSegment+     { lineSegmentStart :: !(V2 depth)+     , lineSegmentStop  :: !(V2 depth)+     } deriving (Foldable, Functor, Traversable, Show)++type instance VecDim LineSegment = 4++instance (IsVec V4 depth) => IsVec LineSegment depth where+    toVec (LineSegment (V2 x1 y1) (V2 x2 y2)) =+        toVec (V4 x1 y1 x2 y2)++    fromVec vec =+        LineSegment+        { lineSegmentStart = V2 x1 y1+        , lineSegmentStop  = V2 x2 y2+        }+      where+        V4 x1 y1 x2 y2 = fromVec vec++{- |+Example:++@+houghLinesPTraces+  :: forall (width    :: Nat)+            (height   :: Nat)+            (channels :: Nat)+            (depth    :: *  )+   . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Building_868x600)+  => Mat (ShapeT [height, width]) ('S channels) ('S depth)+houghLinesPTraces = exceptError $ do+    edgeImg <- canny 50 200 Nothing CannyNormL1 building_868x600+    edgeImgBgr <- cvtColor gray bgr edgeImg+    withMatM (Proxy :: Proxy [height, width])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      edgeImgM <- thaw edgeImg+      lineSegments <- houghLinesP 1 (pi / 180) 80 (Just 30) (Just 10) edgeImgM+      void $ matCopyToM imgM (V2 0 0) edgeImgBgr Nothing+      forM_ lineSegments $ \\lineSegment -> do+        line imgM+             (lineSegmentStart lineSegment)+             (lineSegmentStop  lineSegment)+             red 2 LineType_8 0+@++<<doc/generated/examples/houghLinesPTraces.png houghLinesPTraces>>+-}+houghLinesP+  :: (PrimMonad m)+  => Double+     -- ^ Distance resolution of the accumulator in pixels.+  -> Double+     -- ^ Angle resolution of the accumulator in radians.+  -> Int32+     -- ^ Accumulator threshold parameter. Only those lines are returned that+     -- get enough votes (> threshold).+  -> Maybe Double+     -- ^ Minimum line length. Line segments shorter than that are rejected.+  -> Maybe Double+     -- ^ Maximum allowed gap between points on the same line to link them.+  -> Mut (Mat ('S [h, w]) ('S 1) ('S Word8)) (PrimState m)+     -- ^ Source image. May be modified by the function.+  -> m (V.Vector (LineSegment Int32))+houghLinesP rho theta threshold minLineLength maxLineGap src = unsafePrimToPrim $+    withPtr src $ \srcPtr ->+    -- Pointer to number of lines.+    alloca $ \(numLinesPtr :: Ptr Int32) ->+    -- Pointer to array of Vec4i pointers. The array is allocated in+    -- C++. Each element of the array points to a Vec4i that is also+    -- allocated in C++.+    alloca $ \(linesPtrPtr :: Ptr (Ptr (Ptr C'Vec4i))) -> mask_ $ do+      [C.block| void {+        std::vector<cv::Vec4i> lines = std::vector<cv::Vec4i>();+        cv::HoughLinesP+          ( *$(Mat * srcPtr)+          , lines+          , $(double  c'rho)+          , $(double  c'theta)+          , $(int32_t threshold)+          , $(double  c'minLineLength)+          , $(double  c'maxLineGap)+          );++        *$(int32_t * numLinesPtr) = lines.size();++        cv::Vec4i * * * linesPtrPtr = $(Vec4i * * * linesPtrPtr);+        cv::Vec4i * * linesPtr = new cv::Vec4i * [lines.size()];+        *linesPtrPtr = linesPtr;++        for (std::vector<cv::Vec4i>::size_type ix = 0; ix != lines.size(); ix++)+        {+          cv::Vec4i & org = lines[ix];+          cv::Vec4i * newLine = new cv::Vec4i(org[0], org[1], org[2], org[3]);+          linesPtr[ix] = newLine;+        }+      }|]++      numLines <- fromIntegral <$> peek numLinesPtr+      linesPtr <- peek linesPtrPtr+      lineSegments  <- mapM (fmap fromVec . fromPtr . pure) =<< peekArray numLines linesPtr++      -- Free the array of Vec4i pointers. This does not free the+      -- Vec4i's pointed to by the elements of the array. That is the+      -- responsibility of Haskell's Vec4i finalizer.+      [CU.block| void {+        delete [] *$(Vec4i * * * linesPtrPtr);+      }|]++      pure $ V.fromList lineSegments+  where+    c'rho           = realToFrac rho+    c'theta         = realToFrac theta+    c'minLineLength = maybe 0 realToFrac minLineLength+    c'maxLineGap    = maybe 0 realToFrac maxLineGap
+ src/OpenCV/ImgProc/GeometricImgTransform.cpp view
@@ -0,0 +1,167 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_GeometricImgTransform_0_c2b99805a51c969cd8f0197f3312633538eae840(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Size2i * dsizePtr_inline_c_2, double fx_inline_c_3, double fy_inline_c_4, int32_t cinterpolation_27_inline_c_5) {++  try+  {   +          cv::resize+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , *dsizePtr_inline_c_2+          , fx_inline_c_3+          , fy_inline_c_4+          , cinterpolation_27_inline_c_5+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_GeometricImgTransform_1_3de91dcfbe482398170a011285287da39aab63a0(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * transformPtr_inline_c_2, int32_t cinterpolationMethod_27_inline_c_3, int32_t cinverse_27_inline_c_4, int32_t cfillOutliers_27_inline_c_5, int32_t cborderMode_27_inline_c_6, Scalar * borderValuePtr_inline_c_7) {++  try+  {   +            Mat * src = srcPtr_inline_c_0;+            cv::warpAffine+              ( *src+              , *dstPtr_inline_c_1+              , *transformPtr_inline_c_2+              , src->size()+              , cinterpolationMethod_27_inline_c_3 | cinverse_27_inline_c_4 | cfillOutliers_27_inline_c_5+              , cborderMode_27_inline_c_6+              , *borderValuePtr_inline_c_7+              );+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_GeometricImgTransform_2_4e6ddd0199bf9ac49390a7b6ec8672f793256425(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * transformPtr_inline_c_2, int32_t cinterpolationMethod_27_inline_c_3, int32_t cinverse_27_inline_c_4, int32_t cfillOutliers_27_inline_c_5, int32_t cborderMode_27_inline_c_6, Scalar * borderValuePtr_inline_c_7) {++  try+  {   +            Mat * src = srcPtr_inline_c_0;+            cv::warpPerspective+              ( *src+              , *dstPtr_inline_c_1+              , *transformPtr_inline_c_2+              , src->size()+              , cinterpolationMethod_27_inline_c_3 | cinverse_27_inline_c_4 | cfillOutliers_27_inline_c_5+              , cborderMode_27_inline_c_6+              , *borderValuePtr_inline_c_7+              );+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_GeometricImgTransform_3_db4c7b21fb82ac16f38778e04e1a21d3c2a15efb(Mat * matInPtr_inline_c_0, Mat * matOutPtr_inline_c_1) {++  try+  {   +           cv::invertAffineTransform(*matInPtr_inline_c_0, *matOutPtr_inline_c_1);+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Mat * inline_c_OpenCV_ImgProc_GeometricImgTransform_4_5705994512e2d75b375ec9799d768645b380269b(Point2f * srcPtsPtr_inline_c_0, Point2f * dstPtsPtr_inline_c_1) {++            return new cv::Mat+            ( cv::getPerspectiveTransform(srcPtsPtr_inline_c_0, dstPtsPtr_inline_c_1)+            );+        +}++}++extern "C" {+Mat * inline_c_OpenCV_ImgProc_GeometricImgTransform_5_0ccf603b281c6c9ea50e37bde67fdad2ca9d8fb7(Point2f * centerPtr_inline_c_0, double cangle_27_inline_c_1, double cscale_27_inline_c_2) {++        return new cv::Mat+        ( cv::getRotationMatrix2D+          ( *centerPtr_inline_c_0+          , cangle_27_inline_c_1+          , cscale_27_inline_c_2+          )+        );+      +}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_GeometricImgTransform_6_90a3b43830af9c51592b5cfb3eeb2224044835b4(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * mappingPtr_inline_c_2, int32_t cinterpolation_27_inline_c_3, int32_t cborderMode_27_inline_c_4, Scalar * borderValuePtr_inline_c_5) {++  try+  {   +          cv::remap+            ( *srcPtr_inline_c_0+            , *dstPtr_inline_c_1+            , *mappingPtr_inline_c_2+            , {}+            , cinterpolation_27_inline_c_3+            , cborderMode_27_inline_c_4+            , *borderValuePtr_inline_c_5+            );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_GeometricImgTransform_7_b911b00f072c7df7d438e470e94acbbfd6dfa9ef(Mat * imgPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * cameraPtr_inline_c_2, Mat * distCoeffsPtr_inline_c_3) {++          undistort(*imgPtr_inline_c_0,+                    *dstPtr_inline_c_1,+                    *cameraPtr_inline_c_2,+                    *distCoeffsPtr_inline_c_3);+        +}++}
+ src/OpenCV/ImgProc/GeometricImgTransform.hsc view
@@ -0,0 +1,473 @@+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++{- |++The functions in this section perform various geometrical transformations of 2D+images. They do not change the image content but deform the pixel grid and map+this deformed grid to the destination image. In fact, to avoid sampling+artifacts, the mapping is done in the reverse order, from destination to the+source. That is, for each pixel @(x,y)@ of the destination image, the functions+compute coordinates of the corresponding "donor" pixel in the source image and+copy the pixel value:++@dst(x,y) = src(fx(x,y), fy(x,y))@++In case when you specify the forward mapping @\<gx,gy> : src -> dst@, the OpenCV+functions first compute the corresponding inverse mapping @\<fx,fy>:dst->src@+and then use the above formula.++The actual implementations of the geometrical transformations, from the most+generic remap and to the simplest and the fastest resize, need to solve two main+problems with the above formula:++* Extrapolation of non-existing pixels.+Similarly to the filtering functions described in the previous section, for some+@(x,y)@, either one of @fx(x,y)@, or @fy(x,y)@, or both of them may fall outside+of the image. In this case, an extrapolation method needs to be used. OpenCV+provides the same selection of extrapolation methods as in the filtering+functions. In addition, it provides the method 'BorderTransparent'. This means+that the corresponding pixels in the destination image will not be modified at+all.++* Interpolation of pixel values.+Usually @fx(x,y)@ and @fy(x,y)@ are floating-point numbers. This means that+@\<fx,fy>@ can be either an affine or perspective transformation, or radial lens+distortion correction, and so on. So, a pixel value at fractional coordinates+needs to be retrieved. In the simplest case, the coordinates can be just rounded+to the nearest integer coordinates and the corresponding pixel can be used. This+is called a nearest-neighbor interpolation. However, a better result can be+achieved by using more sophisticated interpolation methods , where a polynomial+function is fit into some neighborhood of the computed pixel+@(fx(x,y),fy(x,y))@, and then the value of the polynomial at @(fx(x,y),fy(x,y))@+is taken as the interpolated pixel value. In OpenCV, you can choose between+several interpolation methods. See resize for details.+-}+module OpenCV.ImgProc.GeometricImgTransform+    ( ResizeAbsRel(..)+    , resize+    , warpAffine+    , warpPerspective+    , invertAffineTransform+    , getPerspectiveTransform+    , getRotationMatrix2D+    , remap+    , undistort+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types ( CFloat, CDouble )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified Data.Vector as V+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.Vector ( zero )+import "this" OpenCV.Core.Types+import "this" OpenCV.ImgProc.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.ImgProc.Types+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++data ResizeAbsRel+   = ResizeAbs Size2i -- ^ Resize to an absolute size.+   | ResizeRel (V2 Double)+     -- ^ Resize with relative factors for both the width and the height.+     deriving Show++marshalResizeAbsRel+    :: ResizeAbsRel+    -> (Size2i, CDouble, CDouble)+marshalResizeAbsRel (ResizeAbs s) = (s, 0   , 0   )+marshalResizeAbsRel (ResizeRel f) = (s, c'fx, c'fy)+  where+    s :: Size2i+    s = toSize (zero :: V2 Int32)++    (V2 c'fx c'fy) = realToFrac <$> f++{- | Resizes an image++To shrink an image, it will generally look best with 'InterArea' interpolation,+whereas to enlarge an image, it will generally look best with 'InterCubic'+(slow) or 'InterLinear' (faster but still looks OK).++Example:++@+resizeInterAreaImg :: Mat ('S ['D, 'D]) ('S 3) ('S Word8)+resizeInterAreaImg = exceptError $+    withMatM (h ::: w + (w \`div` 2) ::: Z)+             (Proxy :: Proxy 3)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      birds_resized <-+        pureExcept $ resize (ResizeRel $ pure 0.5) InterArea birds_768x512+      matCopyToM imgM (V2 0 0) birds_768x512 Nothing+      matCopyToM imgM (V2 w 0) birds_resized Nothing+      lift $ arrowedLine imgM (V2 startX y) (V2 pointX y) red 4 LineType_8 0 0.15+  where+    [h, w] = miShape $ matInfo birds_768x512+    startX = round $ fromIntegral w * (0.95 :: Double)+    pointX = round $ fromIntegral w * (1.05 :: Double)+    y = h \`div` 4+@++<<doc/generated/examples/resizeInterAreaImg.png resizeInterAreaImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#resize OpenCV Sphinx doc>+-}+resize+    :: ResizeAbsRel+    -> InterpolationMethod+    -> Mat ('S [height, width]) channels depth+    -> CvExcept (Mat ('S ['D, 'D]) channels depth)+resize factor interpolationMethod src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src   $ \srcPtr   ->+      withPtr dst   $ \dstPtr   ->+      withPtr dsize $ \dsizePtr ->+        [cvExcept|+          cv::resize+          ( *$(Mat * srcPtr)+          , *$(Mat * dstPtr)+          , *$(Size2i * dsizePtr)+          , $(double fx)+          , $(double fy)+          , $(int32_t c'interpolation)+          );+        |]+  where+    (dsize, fx, fy) = marshalResizeAbsRel factor+    c'interpolation = marshalInterpolationMethod interpolationMethod++#num WARP_FILL_OUTLIERS+#num WARP_INVERSE_MAP++{- | Applies an affine transformation to an image++Example:++@+rotateBirds :: Mat (ShapeT [2, 3]) ('S 1) ('S Double)+rotateBirds = getRotationMatrix2D (V2 256 170 :: V2 CFloat) 45 0.75++warpAffineImg :: Birds_512x341+warpAffineImg = exceptError $+    warpAffine birds_512x341 rotateBirds InterArea False False (BorderConstant black)++warpAffineInvImg :: Birds_512x341+warpAffineInvImg = exceptError $+    warpAffine warpAffineImg rotateBirds InterCubic True False (BorderConstant black)+@++<<doc/generated/birds_512x341.png             original        >>+<<doc/generated/examples/warpAffineImg.png    warpAffineImg   >>+<<doc/generated/examples/warpAffineInvImg.png warpAffineInvImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#warpaffine OpenCV Sphinx doc>+-}+warpAffine+    :: Mat ('S [height, width]) channels depth -- ^ Source image.+    -> Mat (ShapeT [2, 3]) ('S 1) ('S Double) -- ^ Affine transformation matrix.+    -> InterpolationMethod+    -> Bool -- ^ Perform the inverse transformation.+    -> Bool -- ^ Fill outliers.+    -> BorderMode -- ^ Pixel extrapolation method.+    -> CvExcept (Mat ('S [height, width]) channels depth) -- ^ Transformed source image.+warpAffine src transform interpolationMethod inverse fillOutliers borderMode =+    unsafeWrapException $ do+      dst <- newEmptyMat+      handleCvException (pure $ unsafeCoerceMat dst) $+        withPtr src $ \srcPtr ->+        withPtr dst $ \dstPtr ->+        withPtr transform   $ \transformPtr ->+        withPtr    borderValue $ \borderValuePtr ->+          [cvExcept|+            Mat * src = $(Mat * srcPtr);+            cv::warpAffine+              ( *src+              , *$(Mat * dstPtr)+              , *$(Mat * transformPtr)+              , src->size()+              , $(int32_t c'interpolationMethod) | $(int32_t c'inverse) | $(int32_t c'fillOutliers)+              , $(int32_t c'borderMode)+              , *$(Scalar * borderValuePtr)+              );+          |]+  where+    c'interpolationMethod = marshalInterpolationMethod interpolationMethod+    c'inverse      = if inverse      then c'WARP_INVERSE_MAP   else 0+    c'fillOutliers = if fillOutliers then c'WARP_FILL_OUTLIERS else 0+    (c'borderMode, borderValue) = marshalBorderMode borderMode++-- | Applies a perspective transformation to an image+--+-- <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#warpperspective OpenCV Sphinx doc>+warpPerspective+    :: Mat ('S [height, width]) channels depth -- ^ Source image.+    -> Mat (ShapeT [3, 3]) ('S 1) ('S Double) -- ^ Perspective transformation matrix.+    -> InterpolationMethod+    -> Bool -- ^ Perform the inverse transformation.+    -> Bool -- ^ Fill outliers.+    -> BorderMode -- ^ Pixel extrapolation method.+    -> CvExcept (Mat ('S [height, width]) channels depth) -- ^ Transformed source image.+warpPerspective src transform interpolationMethod inverse fillOutliers borderMode =+    unsafeWrapException $ do+      dst <- newEmptyMat+      handleCvException (pure $ unsafeCoerceMat dst) $+        withPtr src $ \srcPtr ->+        withPtr dst $ \dstPtr ->+        withPtr transform   $ \transformPtr   ->+        withPtr    borderValue $ \borderValuePtr ->+          [cvExcept|+            Mat * src = $(Mat * srcPtr);+            cv::warpPerspective+              ( *src+              , *$(Mat * dstPtr)+              , *$(Mat * transformPtr)+              , src->size()+              , $(int32_t c'interpolationMethod) | $(int32_t c'inverse) | $(int32_t c'fillOutliers)+              , $(int32_t c'borderMode)+              , *$(Scalar * borderValuePtr)+              );+          |]+  where+    c'interpolationMethod = marshalInterpolationMethod interpolationMethod+    c'inverse      = if inverse      then c'WARP_INVERSE_MAP   else 0+    c'fillOutliers = if fillOutliers then c'WARP_FILL_OUTLIERS else 0+    (c'borderMode, borderValue) = marshalBorderMode borderMode++-- | Inverts an affine transformation+--+-- <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#invertaffinetransform OpenCV Sphinx doc>+invertAffineTransform+    :: Mat (ShapeT [2, 3]) ('S 1) depth -- ^+    -> CvExcept (Mat (ShapeT [2, 3]) ('S 1) depth)+invertAffineTransform matIn = unsafeWrapException $ do+    matOut <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat matOut) $+      withPtr matIn  $ \matInPtr ->+      withPtr matOut $ \matOutPtr ->+        [cvExcept|+           cv::invertAffineTransform(*$(Mat * matInPtr), *$(Mat * matOutPtr));+        |]++{- | Calculates a perspective transformation matrix for 2D perspective transform++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#getperspectivetransform OpenCV Sphinx doc>+-}+getPerspectiveTransform+    :: (IsPoint2 point2 CFloat)+    => V.Vector (point2 CFloat) -- ^ Array of 4 floating-point Points representing 4 vertices in source image+    -> V.Vector (point2 CFloat) -- ^ Array of 4 floating-point Points representing 4 vertices in destination image+    -> Mat (ShapeT [3,3]) ('S 1) ('S Double) -- ^ The output perspective transformation, 3x3 floating-point-matrix.+getPerspectiveTransform srcPts dstPts = unsafeCoerceMat $ unsafePerformIO $+    withArrayPtr (V.map toPoint srcPts) $ \srcPtsPtr ->+        withArrayPtr (V.map toPoint dstPts) $ \dstPtsPtr ->+        fromPtr+        [CU.block| Mat * {+            return new cv::Mat+            ( cv::getPerspectiveTransform($(Point2f * srcPtsPtr), $(Point2f * dstPtsPtr))+            );+        }|]++{- | Calculates an affine matrix of 2D rotation++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#getrotationmatrix2d OpenCV Sphinx doc>+-}+getRotationMatrix2D+    :: (IsPoint2 point2 CFloat)+    => point2 CFloat -- ^ Center of the rotation in the source image.+    -> Double+       -- ^ Rotation angle in degrees. Positive values mean counter-clockwise+       -- rotation (the coordinate origin is assumed to be the top-left corner).+    -> Double -- ^ Isotropic scale factor.+    -> Mat (ShapeT [2, 3]) ('S 1) ('S Double) -- ^ The output affine transformation, 2x3 floating-point matrix.+getRotationMatrix2D center angle scale = unsafeCoerceMat $ unsafePerformIO $+    withPtr (toPoint center) $ \centerPtr ->+      fromPtr+      [CU.block| Mat * {+        return new cv::Mat+        ( cv::getRotationMatrix2D+          ( *$(Point2f * centerPtr)+          , $(double c'angle)+          , $(double c'scale)+          )+        );+      }|]+  where+    c'angle = realToFrac angle+    c'scale = realToFrac scale++{- | Applies a generic geometrical transformation to an image.++The function remap transforms the source image using the specified map:++@dst(x,y) = src(map(x,y))@++Example:++@+remapImg+  :: forall (width    :: Nat)+            (height   :: Nat)+            (channels :: Nat)+            (depth    :: *  )+   . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Birds_512x341)+  => Mat ('S ['S height, 'S width]) ('S channels) ('S depth)+remapImg = exceptError $ remap birds_512x341 transform InterLinear (BorderConstant black)+  where+    transform = exceptError $+                matFromFunc (Proxy :: Proxy [height, width])+                            (Proxy :: Proxy 2)+                            (Proxy :: Proxy Float)+                            exampleFunc++    exampleFunc [_y,  x] 0 = wobble x w+    exampleFunc [ y, _x] 1 = wobble y h+    exampleFunc _pos _channel = error "impossible"++    wobble :: Int -> Float -> Float+    wobble v s = let v' = fromIntegral v+                     n = v' / s+                 in v' + (s * 0.05 * sin (n * 2 * pi * 5))++    w = fromInteger $ natVal (Proxy :: Proxy width)+    h = fromInteger $ natVal (Proxy :: Proxy height)+@++<<doc/generated/birds_512x341.png original>>+<<doc/generated/examples/remapImg.png remapImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/geometric_transformations.html#remap OpenCV documentation>+-}+remap+    :: Mat ('S [inputHeight, inputWidth]) inputChannels inputDepth+       -- ^ Source image.+    -> Mat ('S [outputHeight, outputWidth]) ('S 2) ('S Float)+       -- ^ A map of @(x, y)@ points.+    -> InterpolationMethod+       -- ^ Interpolation method to use. Note that 'InterArea' is not+       -- supported by this function.+    -> BorderMode+    -> CvExcept (Mat ('S [outputHeight, outputWidth]) inputChannels inputDepth)+remap src mapping interpolationMethod borderMode = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+      withPtr mapping $ \mappingPtr ->+      withPtr borderValue $ \borderValuePtr ->+        [cvExcept|+          cv::remap+            ( *$(Mat * srcPtr)+            , *$(Mat * dstPtr)+            , *$(Mat * mappingPtr)+            , {}+            , $(int32_t c'interpolation)+            , $(int32_t c'borderMode)+            , *$(Scalar * borderValuePtr)+            );+        |]+  where+    c'interpolation = marshalInterpolationMethod interpolationMethod+    (c'borderMode, borderValue) = marshalBorderMode borderMode+++{-|++The function transforms an image to compensate radial and tangential lens+distortion.++Those pixels in the destination image, for which there is no correspondent+pixels in the source image, are filled with zeros (black color).++The camera matrix and the distortion parameters can be determined using+@calibrateCamera@ . If the resolution of images is different from the resolution+used at the calibration stage, f_x, f_y, c_x and c_y need to be scaled accordingly,+while the distortion coefficients remain the same.++Example:++@+undistortImg+  :: forall (width    :: Nat)+            (height   :: Nat)+            (channels :: Nat)+            (depth    :: *  )+   . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Birds_512x341)+  => Mat ('S ['S height, 'S width]) ('S channels) ('S depth)+undistortImg = undistort birds_512x341 intrinsics coefficients+  where intrinsics :: M33 Float+        intrinsics =+          V3 (V3 15840.8      0      2049)+             (V3     0    15830.3    1097)+             (V3     0        0         1)++        coefficients :: Matx51d+        coefficients = unsafePerformIO $+          newMatx51d+            (-2.239145913492247)+             13.674526561736648+              3.650187848850095e-2+            (-2.0042015752853796e-2)+            (-0.44790921357620456)+@++<<doc/generated/birds_512x341.png original>>+<<doc/generated/examples/undistortImg.png undistortImg>>++-}+undistort+  :: ( ToMat m33d, MatShape m33d ~ 'S '[ 'S 3, 'S 3 ]+     , ToMat distCoeffs, MatShape distCoeffs `In` '[ 'S '[ 'S  4, 'S 1 ]+                                                   , 'S '[ 'S  5, 'S 1 ]+                                                   , 'S '[ 'S  8, 'S 1 ]+                                                   , 'S '[ 'S 12, 'S 1 ]+                                                   , 'S '[ 'S 14, 'S 1 ]+                                                   ]+     )+  => Mat ('S '[ h, w]) c d+    -- ^ The source image to undistort.+  -> m33d+  -- ^ The 3x3 matrix of intrinsic parameters.+  -> distCoeffs+  -- ^ The distortion coefficients+  --   (k1,k2,p1,p2[,k3[,k4,k5,k6[,s1,s2,s3,s4[,τx,τy]]]]) of 4, 5, 8, 12 or 14 elements.+  -> Mat ('S '[ h, w]) c d+undistort img camera distCoeffs = unsafePerformIO $ do+    dst <- newEmptyMat+    withPtr img $ \imgPtr ->+      withPtr dst $ \dstPtr ->+      withPtr (toMat camera) $ \cameraPtr ->+      withPtr (toMat distCoeffs) $ \distCoeffsPtr ->+        [C.block| void {+          undistort(*$(Mat * imgPtr),+                    *$(Mat * dstPtr),+                    *$(Mat * cameraPtr),+                    *$(Mat * distCoeffsPtr));+        }|]+    return (unsafeCoerceMat dst)
+ src/OpenCV/ImgProc/ImgFiltering.cpp view
@@ -0,0 +1,222 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_0_e376504d66a67a81166f6a7de96ff685ab99ae52(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t cddepth_27_inline_c_2, int32_t cksize_27_inline_c_3, double cscale_27_inline_c_4, double cdelta_27_inline_c_5, int32_t cborderType_27_inline_c_6) {++  try+  {   +        cv::Laplacian+        ( *srcPtr_inline_c_0+        , *dstPtr_inline_c_1+        ,  cddepth_27_inline_c_2+        ,  cksize_27_inline_c_3+        ,  cscale_27_inline_c_4+        ,  cdelta_27_inline_c_5+        ,  cborderType_27_inline_c_6+        );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_1_345ace375d204c2a7dff8b68ca0269df67bc7938(Mat * matInPtr_inline_c_0, Mat * matOutPtr_inline_c_1, int32_t ksize_inline_c_2) {++  try+  {    cv::medianBlur(*matInPtr_inline_c_0, *matOutPtr_inline_c_1, ksize_inline_c_2); +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_2_d33ce1e3332ac2ac4dd5246990112c449c582d4c(Mat * matInPtr_inline_c_0, Mat * matOutPtr_inline_c_1, Size2i * ksizePtr_inline_c_2) {++  try+  {   +           cv::blur+           ( *matInPtr_inline_c_0+           , *matOutPtr_inline_c_1+           , *ksizePtr_inline_c_2+           );+       +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_3_907ecf95556ac76c10894cb3ae59a4e2b7e7ca9b(Mat * matInPtr_inline_c_0, Mat * matOutPtr_inline_c_1, Size2i * ksizePtr_inline_c_2, double csigmaX_27_inline_c_3, double csigmaY_27_inline_c_4) {++  try+  {   +           cv::GaussianBlur+           ( *matInPtr_inline_c_0+           , *matOutPtr_inline_c_1+           , *ksizePtr_inline_c_2+           , csigmaX_27_inline_c_3+           , csigmaY_27_inline_c_4+           );+       +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_4_82421a3cb5054e4b649407f8926c057bfed86a45(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * kernelPtr_inline_c_2, Point2i * anchorPtr_inline_c_3, int32_t citerations_27_inline_c_4, int32_t cborderType_27_inline_c_5, Scalar * borderValuePtr_inline_c_6) {++  try+  {   +          cv::erode+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , *kernelPtr_inline_c_2+          , *anchorPtr_inline_c_3+          ,  citerations_27_inline_c_4+          ,  cborderType_27_inline_c_5+          , *borderValuePtr_inline_c_6+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_5_686cd566b987aa9d5ec27846da2b925a79b1c365(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * kernelPtr_inline_c_2, Point2i * anchorPtr_inline_c_3, double cdelta_27_inline_c_4, int32_t cborderType_27_inline_c_5) {++  try+  {   +          cv::filter2D+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , -1+          , *kernelPtr_inline_c_2+          , *anchorPtr_inline_c_3+          ,  cdelta_27_inline_c_4+          ,  cborderType_27_inline_c_5+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_6_93c9df76baf0966fe0e3e5136e89b57d1aea3586(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, Mat * kernelPtr_inline_c_2, Point2i * anchorPtr_inline_c_3, int32_t citerations_27_inline_c_4, int32_t cborderType_27_inline_c_5, Scalar * borderValuePtr_inline_c_6) {++  try+  {   +          cv::dilate+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          , *kernelPtr_inline_c_2+          , *anchorPtr_inline_c_3+          ,  citerations_27_inline_c_4+          ,  cborderType_27_inline_c_5+          , *borderValuePtr_inline_c_6+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_7_fe64cf1ef54e417d07f7d0a61e6c49313898058d(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t cop_27_inline_c_2, Mat * kernelPtr_inline_c_3, Point2i * anchorPtr_inline_c_4, int32_t citerations_27_inline_c_5, int32_t cborderType_27_inline_c_6, Scalar * borderValuePtr_inline_c_7) {++  try+  {   +          cv::morphologyEx+          ( *srcPtr_inline_c_0+          , *dstPtr_inline_c_1+          ,  cop_27_inline_c_2+          , *kernelPtr_inline_c_3+          , *anchorPtr_inline_c_4+          ,  citerations_27_inline_c_5+          ,  cborderType_27_inline_c_6+          , *borderValuePtr_inline_c_7+          );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ImgFiltering_8_7ea2729a8a8a953773da566c07815d3fa635d8e9(Mat * elementPtr_inline_c_0, int32_t cmorphShape_27_inline_c_1, Size2i * ksizePtr_inline_c_2, Point2i * anchorPtr_inline_c_3) {++  try+  {   +         *elementPtr_inline_c_0 =+           cv::getStructuringElement+           ( cmorphShape_27_inline_c_1+           , *ksizePtr_inline_c_2+           , *anchorPtr_inline_c_3+           );+       +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/ImgProc/ImgFiltering.hsc view
@@ -0,0 +1,667 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++{- |++Functions and classes described in this section are used to perform various+linear or non-linear filtering operations on 2D images (represented as+@'Mat'@\'s). It means that for each pixel location @(x,y)@ in the source image+(normally, rectangular), its neighborhood is considered and used to compute the+response. In case of a linear filter, it is a weighted sum of pixel values. In+case of morphological operations, it is the minimum or maximum values, and so+on. The computed response is stored in the destination image at the same+location @(x,y)@. It means that the output image will be of the same size as the+input image. Normally, the functions support multi-channel arrays, in which case+every channel is processed independently. Therefore, the output image will also+have the same number of channels as the input one.++Another common feature of the functions and classes described in this section is+that, unlike simple arithmetic functions, they need to extrapolate values of+some non-existing pixels. For example, if you want to smooth an image using a+Gaussian @3x3@ filter, then, when processing the left-most pixels in each+row, you need pixels to the left of them, that is, outside of the image. You can+let these pixels be the same as the left-most image pixels ("replicated border"+extrapolation method), or assume that all the non-existing pixels are zeros+("constant border" extrapolation method), and so on. OpenCV enables you to+specify the extrapolation method.+-}+module OpenCV.ImgProc.ImgFiltering+    ( MorphShape(..)+    , MorphOperation(..)++    , laplacian+    , medianBlur+    , erode+    , dilate+    , filter2D+    , morphologyEx+    , getStructuringElement+    , blur+    , gaussianBlur+    ) where++import "base" Data.Int+import "base" Data.Maybe+import "base" Data.Proxy+import "base" Data.Word+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V2 ( V2(..) )+import "this" OpenCV.Core.Types+import "this" OpenCV.ImgProc.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.ImgProc.Types ( marshalBorderMode )+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"+#include "hsc_macros.hpp"+++--------------------------------------------------------------------------------+-- Constants+--------------------------------------------------------------------------------++defaultAnchor :: Point2i+defaultAnchor = toPoint (pure (-1) :: V2 Int32)+++--------------------------------------------------------------------------------+-- Types+--------------------------------------------------------------------------------++data MorphShape+   = MorphRect -- ^ A rectangular structuring element.+   | MorphEllipse+     -- ^ An elliptic structuring element, that is, a filled ellipse inscribed+     -- into the rectangle Rect(0, 0, esize.width, 0.esize.height).+   | MorphCross !Point2i -- ^ A cross-shaped structuring element.++#num MORPH_RECT+#num MORPH_ELLIPSE+#num MORPH_CROSS++marshalMorphShape :: MorphShape -> (Int32, Point2i)+marshalMorphShape = \case+    MorphRect         -> (c'MORPH_RECT   , defaultAnchor)+    MorphEllipse      -> (c'MORPH_ELLIPSE, defaultAnchor)+    MorphCross anchor -> (c'MORPH_CROSS  , anchor)++data MorphOperation+   = MorphOpen     -- ^ An opening operation: dilate . erode+   | MorphClose    -- ^ A closing operation: erode . dilate+   | MorphGradient -- ^ A morphological gradient: dilate - erode+   | MorphTopHat   -- ^ "top hat": src - open+   | MorphBlackHat -- ^ "black hat": close - src++#num MORPH_OPEN+#num MORPH_CLOSE+#num MORPH_GRADIENT+#num MORPH_TOPHAT+#num MORPH_BLACKHAT++marshalMorphOperation :: MorphOperation -> Int32+marshalMorphOperation = \case+    MorphOpen     -> c'MORPH_OPEN+    MorphClose    -> c'MORPH_CLOSE+    MorphGradient -> c'MORPH_GRADIENT+    MorphTopHat   -> c'MORPH_TOPHAT+    MorphBlackHat -> c'MORPH_BLACKHAT+++--------------------------------------------------------------------------------+-- Image Filtering+--------------------------------------------------------------------------------++{- | Calculates the Laplacian of an image++The function calculates the Laplacian of the source image by adding up+the second x and y derivatives calculated using the Sobel operator.++Example:++@+laplacianImg+    :: forall shape channels depth+     . (Mat shape channels depth ~ Birds_512x341)+    => Mat shape ('S 1) ('S Double)+laplacianImg = exceptError $ do+    imgG <- cvtColor bgr gray birds_512x341+    laplacian Nothing Nothing Nothing Nothing imgG+@++<<doc/generated/examples/laplacianImg.png laplacianImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#laplacian OpenCV Sphinx doc>+-}+laplacian+    :: forall shape channels srcDepth dstDepth+     . (ToDepth (Proxy dstDepth))+    => Maybe Int32+       -- ^ Aperture size used to compute the second-derivative filters. The+       -- size must be positive and odd. Default value is 1.+    -> Maybe Double+       -- ^ Optional scale factor for the computed Laplacian values. Default+       -- value is 1.+    -> Maybe Double+       -- ^ Optional delta value that is added to the results. Default value is+       -- 0.+    -> Maybe BorderMode+       -- ^ Pixel extrapolation method.+    -> Mat shape channels srcDepth+    -> CvExcept (Mat shape channels ('S dstDepth))+laplacian ksize scale delta borderType src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+      [cvExcept|+        cv::Laplacian+        ( *$(Mat *   srcPtr      )+        , *$(Mat *   dstPtr      )+        ,  $(int32_t c'ddepth    )+        ,  $(int32_t c'ksize     )+        ,  $(double  c'scale     )+        ,  $(double  c'delta     )+        ,  $(int32_t c'borderType)+        );+      |]+  where+    c'ksize = fromMaybe 1 ksize+    c'scale = maybe 1 realToFrac scale+    c'delta = maybe 0 realToFrac delta+    c'ddepth = marshalDepth $ toDepth (Proxy :: Proxy dstDepth)+    c'borderType = fst $ marshalBorderMode $ fromMaybe BorderReflect101 borderType++{- | Blurs an image using the median filter++Example:++@+medianBlurImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Birds_512x341+       , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+medianBlurImg = exceptError $+    withMatM (Proxy :: Proxy [height, width2])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      birdsBlurred <- pureExcept $ medianBlur birds_512x341 13+      matCopyToM imgM (V2 0 0) birds_512x341 Nothing+      matCopyToM imgM (V2 w 0) birdsBlurred  Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy width)+@++<<doc/generated/examples/medianBlurImg.png medianBlurImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#medianblur OpenCV Sphinx doc>+-}+-- TODO (Rvd): make ksize a type level argument+-- if ksize in [3, 5] then depth in [Word8, Int16, Float) else depth ~ Word8+medianBlur+    :: ( depth    `In` '[Word8, Word16, Float]+       , channels `In` '[1, 3, 4]+       -- , Length shape <= 2+       )+    => Mat shape ('S channels) ('S depth)+       -- ^ Input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image+       -- depth should be 'Word8', 'Word16', or 'Float', for+       -- larger aperture sizes, it can only be 'Word8'.+    -> Int32+       -- ^ Aperture linear size; it must be odd and greater than 1, for+       -- example: 3, 5, 7...+    -> CvExcept (Mat shape ('S channels) ('S depth))+medianBlur matIn ksize = unsafeWrapException $ do+    matOut <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat matOut) $+      withPtr matOut $ \matOutPtr ->+      withPtr matIn $ \matInPtr ->+        [cvExcept| cv::medianBlur(*$(Mat * matInPtr), *$(Mat * matOutPtr), $(int32_t ksize)); |]++{- | Blurs an image using a box filter.++Example:++@+boxBlurImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Birds_512x341+       , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+boxBlurImg = exceptError $+    withMatM (Proxy :: Proxy [height, width2])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      birdsBlurred <- pureExcept $ blur (V2 13 13 :: V2 Int32) birds_512x341+      matCopyToM imgM (V2 0 0) birds_512x341 Nothing+      matCopyToM imgM (V2 w 0) birdsBlurred  Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy width)+@++<<doc/generated/examples/boxBlurImg.png boxBlurImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#blur OpenCV Sphinx doc>+-}+blur+  :: ( depth `In` '[Word8, Word16, Int16, Float, Double]+     , IsSize  size  Int32+     )+  => size  Int32 -- ^ Blurring kernel size.+  -> Mat shape ('S channels) ('S depth)+  -> CvExcept (Mat shape ('S channels) ('S depth))+blur size matIn =+  unsafeWrapException $+  do matOut <- newEmptyMat+     handleCvException (pure $ unsafeCoerceMat matOut) $+       withPtr ksize $ \ksizePtr ->+       withPtr matIn $ \matInPtr ->+       withPtr matOut $ \matOutPtr ->+       [cvExcept|+           cv::blur+           ( *$(Mat * matInPtr)+           , *$(Mat * matOutPtr)+           , *$(Size2i * ksizePtr)+           );+       |]+  where ksize :: Size2i+        ksize = toSize size++gaussianBlur+  :: ( depth `In` '[Word8, Word16, Float, Double]+     , IsSize size Int32+     )+  => size Int32 -- ^ Blurring kernel size.+  -> Double -- ^ sigmaX+  -> Double -- ^ sigmaY+  -> Mat shape ('S channels) ('S depth)+  -> CvExcept (Mat shape ('S channels) ('S depth))+gaussianBlur size sigmaX sigmaY matIn =+  unsafeWrapException $+  do matOut <- newEmptyMat+     handleCvException (pure $ unsafeCoerceMat matOut) $+       withPtr ksize $ \ksizePtr ->+       withPtr matIn $ \matInPtr ->+       withPtr matOut $ \matOutPtr ->+       [cvExcept|+           cv::GaussianBlur+           ( *$(Mat * matInPtr)+           , *$(Mat * matOutPtr)+           , *$(Size2i * ksizePtr)+           , $(double c'sigmaX)+           , $(double c'sigmaY)+           );+       |]+  where+    ksize :: Size2i+    ksize = toSize size++    c'sigmaX = realToFrac sigmaX+    c'sigmaY = realToFrac sigmaY++{- | Erodes an image by using a specific structuring element++Example:++@+erodeImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Lambda+       , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+erodeImg = exceptError $+    withMatM (Proxy :: Proxy [height, width2])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      erodedLambda <-+        pureExcept $ erode lambda Nothing (Nothing :: Maybe Point2i) 5 BorderReplicate+      matCopyToM imgM (V2 0 0) lambda Nothing+      matCopyToM imgM (V2 w 0) erodedLambda Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy width)+@++<<doc/generated/examples/erodeImg.png erodeImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#erode OpenCV Sphinx doc>+-}+erode+    :: ( IsPoint2 point2 Int32+       , depth `In` [Word8, Word16, Int16, Float, Double]+       )+    => Mat shape channels ('S depth) -- ^ Input image.+    -> Maybe (Mat ('S [sh, sw]) ('S 1) ('S Word8))+       -- ^ Structuring element used for erosion. If `emptyMat` is+       -- used a @3x3@ rectangular structuring element is used. Kernel+       -- can be created using `getStructuringElement`.+    -> Maybe (point2 Int32) -- ^ anchor+    -> Int -- ^ iterations+    -> BorderMode+    -> CvExcept (Mat shape channels ('S depth))+erode src mbKernel mbAnchor iterations borderMode = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr    ->+      withPtr dst    $ \dstPtr    ->+      withPtr kernel $ \kernelPtr ->+      withPtr anchor $ \anchorPtr ->+      withPtr borderValue $ \borderValuePtr ->+        [cvExcept|+          cv::erode+          ( *$(Mat     * srcPtr        )+          , *$(Mat     * dstPtr        )+          , *$(Mat     * kernelPtr     )+          , *$(Point2i * anchorPtr     )+          ,  $(int32_t   c'iterations  )+          ,  $(int32_t   c'borderType  )+          , *$(Scalar  * borderValuePtr)+          );+        |]+  where+    kernel :: Mat 'D 'D 'D+    kernel = maybe (relaxMat emptyMat) unsafeCoerceMat mbKernel++    anchor :: Point2i+    anchor = maybe defaultAnchor toPoint mbAnchor++    c'iterations = fromIntegral iterations+    (c'borderType, borderValue) = marshalBorderMode borderMode++{- | Convolves an image with the kernel.++Example:++@+filter2DImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Birds_512x341+       , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+filter2DImg = exceptError $+    withMatM (Proxy :: Proxy [height, width2])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      filteredBird <-+        pureExcept $ filter2D birds_512x341 kernel (Nothing :: Maybe Point2i) 0 BorderReplicate+      matCopyToM imgM (V2 0 0) birds_512x341 Nothing+      matCopyToM imgM (V2 w 0) filteredBird Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy width)+    kernel =+      exceptError $+      withMatM (Proxy :: Proxy [3, 3])+               (Proxy :: Proxy 1)+               (Proxy :: Proxy Double)+               black $ \\imgM -> do+        lift $ line imgM (V2 0 0 :: V2 Int32) (V2 0 0 :: V2 Int32) (V4 (-2) (-2) (-2) 1 :: V4 Double) 0 LineType_8 0+        lift $ line imgM (V2 1 0 :: V2 Int32) (V2 0 1 :: V2 Int32) (V4 (-1) (-1) (-1) 1 :: V4 Double) 0 LineType_8 0+        lift $ line imgM (V2 1 1 :: V2 Int32) (V2 1 1 :: V2 Int32) (V4   1    1    1  1 :: V4 Double) 0 LineType_8 0+        lift $ line imgM (V2 1 2 :: V2 Int32) (V2 2 1 :: V2 Int32) (V4   1    1    1  1 :: V4 Double) 0 LineType_8 0+        lift $ line imgM (V2 2 2 :: V2 Int32) (V2 2 2 :: V2 Int32) (V4   2    2    2  1 :: V4 Double) 0 LineType_8 0+@++<<doc/generated/examples/filter2DImg.png filter2DImg>>+++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#filter2d OpenCV Sphinx doc>+-}+filter2D+    :: ( IsPoint2 point2 Int32+       , depth `In` [Word8, Word16, Int16, Float, Double]+       )+    => Mat shape channels ('S depth) -- ^ Input image.+    -> Mat ('S [sh, sw]) ('S 1) ('S Double)+       -- ^ convolution kernel (or rather a correlation kernel),+       -- a single-channel floating point matrix; if you want to+       -- apply different kernels to different channels, split the+       -- image into separate color planes using split and process+       -- them individually.+    -> Maybe (point2 Int32) -- ^ anchor+    -> Double -- ^ delta+    -> BorderMode+    -> CvExcept (Mat shape channels ('S depth))+filter2D src kernel mbAnchor delta borderMode = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr    ->+      withPtr dst    $ \dstPtr    ->+      withPtr kernel $ \kernelPtr ->+      withPtr anchor $ \anchorPtr ->+        [cvExcept|+          cv::filter2D+          ( *$(Mat     * srcPtr        )+          , *$(Mat     * dstPtr        )+          , -1+          , *$(Mat     * kernelPtr     )+          , *$(Point2i * anchorPtr     )+          ,  $(double    c'delta       )+          ,  $(int32_t   c'borderType  )+          );+        |]+  where+    anchor :: Point2i+    anchor = maybe defaultAnchor toPoint mbAnchor++    c'delta = realToFrac delta+    (c'borderType, _) = marshalBorderMode borderMode++{- | Dilates an image by using a specific structuring element++Example:++@+dilateImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Lambda+       , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+dilateImg = exceptError $+    withMatM (Proxy :: Proxy [height, width2])+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      dilatedLambda <-+        pureExcept $ dilate lambda Nothing (Nothing :: Maybe Point2i) 3 BorderReplicate+      matCopyToM imgM (V2 0 0) lambda Nothing+      matCopyToM imgM (V2 w 0) dilatedLambda Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy width)+@++<<doc/generated/examples/dilateImg.png dilateImg>>+++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#dilate OpenCV Sphinx doc>+-}+dilate+    :: ( IsPoint2 point2 Int32+       , depth `In` [Word8, Word16, Int16, Float, Double]+       )+    => Mat shape channels ('S depth) -- ^ Input image.+    -> Maybe (Mat ('S [sh, sw]) ('S 1) ('S Word8))+       -- ^ Structuring element used for dilation. If `emptyMat` is+       -- used a @3x3@ rectangular structuring element is used. Kernel+       -- can be created using `getStructuringElement`.+    -> Maybe (point2 Int32) -- ^ anchor+    -> Int -- ^ iterations+    -> BorderMode+    -> CvExcept (Mat shape channels ('S depth))+dilate src mbKernel mbAnchor iterations borderMode = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr    ->+      withPtr dst    $ \dstPtr    ->+      withPtr kernel $ \kernelPtr ->+      withPtr anchor $ \anchorPtr ->+      withPtr borderValue $ \borderValuePtr ->+        [cvExcept|+          cv::dilate+          ( *$(Mat     * srcPtr        )+          , *$(Mat     * dstPtr        )+          , *$(Mat     * kernelPtr     )+          , *$(Point2i * anchorPtr     )+          ,  $(int32_t   c'iterations  )+          ,  $(int32_t   c'borderType  )+          , *$(Scalar  * borderValuePtr)+          );+        |]+  where+    kernel :: Mat 'D 'D 'D+    kernel = maybe (relaxMat emptyMat) unsafeCoerceMat mbKernel++    anchor :: Point2i+    anchor = maybe defaultAnchor toPoint mbAnchor++    c'iterations = fromIntegral iterations+    (c'borderType, borderValue) = marshalBorderMode borderMode++{- | Performs advanced morphological transformations++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#morphologyex OpenCV Sphinx doc>+-}+morphologyEx+    :: ( IsPoint2 point2 Int32+       , depth `In` [Word8, Word16, Int16, Float, Double]+       )+     => Mat shape channels ('S depth) -- ^ Source image.+    -> MorphOperation -- ^ Type of a morphological operation.+    -> Mat 'D 'D 'D -- ^ Structuring element.+    -> Maybe (point2 Int32) -- ^ Anchor position with the kernel.+    -> Int -- ^ Number of times erosion and dilation are applied.+    -> BorderMode+    -> CvExcept (Mat shape channels ('S depth))+morphologyEx src op kernel mbAnchor iterations borderMode = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src    $ \srcPtr    ->+      withPtr dst    $ \dstPtr    ->+      withPtr kernel $ \kernelPtr ->+      withPtr anchor $ \anchorPtr ->+      withPtr borderValue $ \borderValuePtr ->+        [cvExcept|+          cv::morphologyEx+          ( *$(Mat     * srcPtr        )+          , *$(Mat     * dstPtr        )+          ,  $(int32_t   c'op          )+          , *$(Mat     * kernelPtr     )+          , *$(Point2i * anchorPtr     )+          ,  $(int32_t   c'iterations  )+          ,  $(int32_t   c'borderType  )+          , *$(Scalar  * borderValuePtr)+          );+        |]++  where+    c'op = marshalMorphOperation op++    anchor :: Point2i+    anchor = maybe defaultAnchor toPoint mbAnchor++    c'iterations = fromIntegral iterations+    (c'borderType, borderValue) = marshalBorderMode borderMode+++{- | Returns a structuring element of the specified size and shape for+morphological operations++Example:++@+type StructureImg = Mat (ShapeT [128, 128]) ('S 1) ('S Word8)++structureImg :: MorphShape -> StructureImg+structureImg shape = exceptError $ do+    mat <- getStructuringElement shape (Proxy :: Proxy 128) (Proxy :: Proxy 128)+    img <- matConvertTo (Just 255) Nothing mat+    bitwiseNot img++morphRectImg :: StructureImg+morphRectImg = structureImg MorphRect++morphEllipseImg :: StructureImg+morphEllipseImg = structureImg MorphEllipse++morphCrossImg :: StructureImg+morphCrossImg = structureImg $ MorphCross $ toPoint (pure (-1) :: V2 Int32)+@++<<doc/generated/examples/morphRectImg.png morphRectImg>>+<<doc/generated/examples/morphEllipseImg.png morphEllipseImg>>+<<doc/generated/examples/morphCrossImg.png morphCrossImg>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html#getstructuringelement OpenCV Sphinx doc>+-}+getStructuringElement+    :: (ToInt32 height, ToInt32 width)+    => MorphShape -- ^+    -> height+    -> width+    -> CvExcept (Mat (ShapeT (height ::: width ::: Z)) ('S 1) ('S Word8))+getStructuringElement morphShape height width = unsafeWrapException $ do+    element <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat element) $+      withPtr ksize   $ \ksizePtr   ->+      withPtr anchor  $ \anchorPtr  ->+      withPtr element $ \elementPtr ->+       [cvExcept|+         *$(Mat * elementPtr) =+           cv::getStructuringElement+           ( $(int32_t c'morphShape)+           , *$(Size2i * ksizePtr)+           , *$(Point2i * anchorPtr)+           );+       |]+  where+    ksize :: Size2i+    ksize = toSize $ V2 (toInt32 width) (toInt32 height)+    (c'morphShape, anchor) = marshalMorphShape morphShape
+ src/OpenCV/ImgProc/MiscImgTransform.cpp view
@@ -0,0 +1,115 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_MiscImgTransform_0_d2be594f4f12563672774c8c4e1f40e11ca04a85(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, int32_t ccode_27_inline_c_2) {++  try+  {   +          cv::cvtColor( *srcPtr_inline_c_0+                      , *dstPtr_inline_c_1+                      , ccode_27_inline_c_2+                      , 0+                      );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_MiscImgTransform_1_7f03ad69fa7f1dd24496f6fd913ec5b08e914c63(Mat * maskPtr_inline_c_0, Mat * matPtr_inline_c_1, Point2i * seedPointPtr_inline_c_2, Scalar * colorPtr_inline_c_3, Rect2i * rectPtr_inline_c_4, Scalar * loDiffPtr_inline_c_5, Scalar * upDiffPtr_inline_c_6, int32_t copFlags_27_inline_c_7) {++        cv::Mat * maskPtr = maskPtr_inline_c_0;+        cv::floodFill( *matPtr_inline_c_1+                     , maskPtr ? cv::_InputOutputArray(*maskPtr) : cv::_InputOutputArray(noArray())+                     , *seedPointPtr_inline_c_2+                     , *colorPtr_inline_c_3+                     , rectPtr_inline_c_4+                     , *loDiffPtr_inline_c_5+                     , *upDiffPtr_inline_c_6+                     , copFlags_27_inline_c_7+                     );+      +}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_MiscImgTransform_2_b818811bceb7d3047a2b7526a53fde01319f83df(double * calcThreshPtr_inline_c_0, Mat * srcPtr_inline_c_1, Mat * dstPtr_inline_c_2, double cthreshVal_27_inline_c_3, double cmaxVal_27_inline_c_4, int32_t ctype_27_inline_c_5) {++  try+  {   +          *calcThreshPtr_inline_c_0 =+            cv::threshold( *srcPtr_inline_c_1+                         , *dstPtr_inline_c_2+                         , cthreshVal_27_inline_c_3+                         , cmaxVal_27_inline_c_4+                         , ctype_27_inline_c_5+                         );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_MiscImgTransform_3_4f0f8c34c71fc074383b1de89868150524d9d984(Mat * imgPtr_inline_c_0, Mat * markersPtr_inline_c_1) {++        cv::watershed( *imgPtr_inline_c_0+                     , *markersPtr_inline_c_1+                     )+      ;+}++}++extern "C" {+void inline_c_OpenCV_ImgProc_MiscImgTransform_4_5f6806c8350b79ac1a2202371cf50a4940707dc2(Mat * imgPtr_inline_c_0, Mat * maskPtr_inline_c_1, Rect2i * rectPtr_inline_c_2, Mat * bgdModelPtr_inline_c_3, Mat * fgdModelPtr_inline_c_4, int32_t iterCount_inline_c_5, int32_t cmodeFlags_27_inline_c_6) {++        cv::grabCut( *imgPtr_inline_c_0+                   , *maskPtr_inline_c_1+                   , *rectPtr_inline_c_2+                   , *bgdModelPtr_inline_c_3+                   , *fgdModelPtr_inline_c_4+                   , iterCount_inline_c_5+                   , cmodeFlags_27_inline_c_6+                   );+      +}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_MiscImgTransform_5_0c1197093bd6dc0e0cbd6cb325fabba737cf7d53(Mat * srcPtr_inline_c_0, Scalar * loPtr_inline_c_1, Scalar * hiPtr_inline_c_2, Mat * dstPtr_inline_c_3) {++  try+  {   +        cv::inRange(*srcPtr_inline_c_0, *loPtr_inline_c_1, *hiPtr_inline_c_2, *dstPtr_inline_c_3);+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/ImgProc/MiscImgTransform.hs view
@@ -0,0 +1,523 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.ImgProc.MiscImgTransform+    ( -- * Color conversion+      cvtColor+    , module OpenCV.ImgProc.MiscImgTransform.ColorCodes++      -- * Flood filling+    , floodFill+    , FloodFillOperationFlags(..)+    , defaultFloodFillOperationFlags++      -- * Thresholding+    , ThreshType(..)+    , ThreshValue(..)+    , threshold++      -- * Watershed+    , watershed++      -- * GrabCut+    , GrabCutOperationMode(..)+    , grabCut++      -- * In range+    , inRange+    ) where++import "base" Data.Bits+import "base" Data.Int+import "base" Data.Proxy ( Proxy(..) )+import "base" Data.Word+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Storable ( peek )+import "base" GHC.TypeLits+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V4 ( V4 )+import "this" OpenCV.Core.Types+import "this" OpenCV.ImgProc.MiscImgTransform.ColorCodes+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.ImgProc.MiscImgTransform+import "this" OpenCV.Internal.ImgProc.MiscImgTransform.TypeLevel+import "this" OpenCV.Internal.ImgProc.MiscImgTransform.ColorCodes ( colorConversionCode )+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------++-- ignore next Haddock code block, because of the hash sign in the link at the end of the comment.+{- | Converts an image from one color space to another++The function converts an input image from one color space to+another. In case of a transformation to-from RGB color space, the+order of the channels should be specified explicitly (RGB or+BGR). Note that the default color format in OpenCV is often+referred to as RGB but it is actually BGR (the bytes are+reversed). So the first byte in a standard (24-bit) color image+will be an 8-bit Blue component, the second byte will be Green, and+the third byte will be Red. The fourth, fifth, and sixth bytes+would then be the second pixel (Blue, then Green, then Red), and so+on.++The conventional ranges for R, G, and B channel values are:++  * 0 to 255 for 'Word8' images++  * 0 to 65535 for 'Word16' images++  * 0 to 1 for 'Float' images++In case of linear transformations, the range does not matter. But+in case of a non-linear transformation, an input RGB image should+be normalized to the proper value range to get the correct results,+for example, for RGB to L*u*v* transformation. For example, if you+have a 32-bit floating-point image directly converted from an 8-bit+image without any scaling, then it will have the 0..255 value range+instead of 0..1 assumed by the function. So, before calling+'cvtColor', you need first to scale the image down:++>  cvtColor (img * 1/255) 'ColorConvBGR2Luv'++If you use 'cvtColor' with 8-bit images, the conversion will have+some information lost. For many applications, this will not be+noticeable but it is recommended to use 32-bit images in+applications that need the full range of colors or that convert an+image before an operation and then convert back.++If conversion adds the alpha channel, its value will set to the+maximum of corresponding channel range: 255 for 'Word8', 65535 for+'Word16', 1 for 'Float'.++Example:++@+cvtColorImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Birds_512x341+       , width2 ~ (width + width)+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+cvtColorImg = exceptError $+    withMatM ((Proxy :: Proxy height) ::: (Proxy :: Proxy width2) ::: Z)+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      birds_gray <- pureExcept $   cvtColor gray bgr+                               =<< cvtColor bgr gray birds_512x341+      matCopyToM imgM (V2 0 0) birds_512x341 Nothing+      matCopyToM imgM (V2 w 0) birds_gray    Nothing+      lift $ arrowedLine imgM (V2 startX midY) (V2 pointX midY) red 4 LineType_8 0 0.15+  where+    h, w :: Int32+    h = fromInteger $ natVal (Proxy :: Proxy height)+    w = fromInteger $ natVal (Proxy :: Proxy width)++    startX, pointX :: Int32+    startX = round $ fromIntegral w * (0.95 :: Double)+    pointX = round $ fromIntegral w * (1.05 :: Double)+    midY = h \`div\` 2+@++<<doc/generated/examples/cvtColorImg.png cvtColorImg>>++<http://goo.gl/3rfrhu OpenCV Sphinx Doc>+-}++-- the link avove is minified because it includes a hash, which the CPP tries to parse and fails++-- TODO (RvD): Allow value level color codes+-- Allow statically unknown color codes: fromColor :: DS ColorCode+cvtColor :: forall (fromColor   :: ColorCode)+                   (toColor     :: ColorCode)+                   (shape       :: DS [DS Nat])+                   (srcChannels :: DS Nat)+                   (dstChannels :: DS Nat)+                   (srcDepth    :: DS *)+                   (dstDepth    :: DS *)+          . ( ColorConversion fromColor toColor+            , ColorCodeMatchesChannels fromColor srcChannels+            , dstChannels ~ 'S (ColorCodeChannels toColor)+            , srcDepth `In` ['D, 'S Word8, 'S Word16, 'S Float]+            , dstDepth ~ ColorCodeDepth fromColor toColor srcDepth+            )+         => Proxy fromColor -- ^ Convert from 'ColorCode'. Make sure the source image has this 'ColorCode'+         -> Proxy toColor   -- ^ Convert to 'ColorCode'.+         -> Mat shape srcChannels srcDepth -- ^ Source image+         -> CvExcept (Mat shape dstChannels dstDepth)+cvtColor fromColor toColor src = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          cv::cvtColor( *$(Mat * srcPtr)+                      , *$(Mat * dstPtr)+                      , $(int32_t c'code)+                      , 0+                      );+        |]+  where+    c'code = colorConversionCode fromColor toColor++{- | The function 'floodFill' fills a connected component starting from the seed point with the specified color.++The connectivity is determined by the color/brightness closeness of the neighbor pixels. See the OpenCV+documentation for details on the algorithm.++Example:++@+floodFillImg+    :: forall (width    :: Nat)+              (width2   :: Nat)+              (height   :: Nat)+              (channels :: Nat)+              (depth    :: *)+     . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Sailboat_768x512+       , width2 ~ (width + width)+       )+    => Mat (ShapeT [height, width2]) ('S channels) ('S depth)+floodFillImg = exceptError $+    withMatM ((Proxy :: Proxy height) ::: (Proxy :: Proxy width2) ::: Z)+             (Proxy :: Proxy channels)+             (Proxy :: Proxy depth)+             white $ \\imgM -> do+      sailboatEvening_768x512 <- thaw sailboat_768x512+      mask <- mkMatM (Proxy :: Proxy [height + 2, width + 2])+                     (Proxy :: Proxy 1)+                     (Proxy :: Proxy Word8)+                     black+      circle mask (V2 450 120 :: V2 Int32) 45 white (-1) LineType_AA 0+      rect <- floodFill sailboatEvening_768x512 (Just mask) seedPoint eveningRed (Just tolerance) (Just tolerance) defaultFloodFillOperationFlags+      rectangle sailboatEvening_768x512 rect blue 2 LineType_8 0+      frozenSailboatEvening_768x512 <- freeze sailboatEvening_768x512+      matCopyToM imgM (V2 0 0) sailboat_768x512 Nothing+      matCopyToM imgM (V2 w 0) frozenSailboatEvening_768x512 Nothing+      lift $ arrowedLine imgM (V2 startX midY) (V2 pointX midY) red 4 LineType_8 0 0.15+  where+    h, w :: Int32+    h = fromInteger $ natVal (Proxy :: Proxy height)+    w = fromInteger $ natVal (Proxy :: Proxy width)++    startX, pointX :: Int32+    startX = round $ fromIntegral w * (0.95 :: Double)+    pointX = round $ fromIntegral w * (1.05 :: Double)++    midY = h \`div\` 2++    seedPoint :: V2 Int32+    seedPoint = V2 100 50++    eveningRed :: V4 Double+    eveningRed = V4 0 100 200 255++    tolerance :: V4 Double+    tolerance = pure 7+@++<<doc/generated/examples/floodFillImg.png floodFillImg>>++<http://goo.gl/9XIIne OpenCV Sphinx Doc>+-}+floodFill+    :: ( PrimMonad m+       , channels `In` '[ 'S 1, 'S 3 ]+       , depth `In` '[ 'D, 'S Word8, 'S Float, 'S Double ]+       , IsPoint2 point2 Int32+       , ToScalar color+       )+    => Mut (Mat shape channels depth) (PrimState m)+        -- ^ Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the function unless the FLOODFILL_MASK_ONLY flag is set.+    -> Maybe (Mut (Mat (WidthAndHeightPlusTwo shape) ('S 1) ('S Word8)) (PrimState m))+        -- ^ Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller than image. Since this is both an input and output parameter, you must take responsibility of initializing it. Flood-filling cannot go across non-zero pixels in the input mask. For example, an edge detector output can be used as a mask to stop filling at edges. On output, pixels in the mask corresponding to filled pixels in the image are set to 1 or to the a value specified in flags as described below. It is therefore possible to use the same mask in multiple calls to the function to make sure the filled areas do not overlap.+        -- Note: Since the mask is larger than the filled image, a pixel  (x, y) in image corresponds to the pixel  (x+1, y+1) in the mask.+    -> point2 Int32+        -- ^ Starting point.+    -> color+        -- ^ New value of the repainted domain pixels.+    -> Maybe color+        -- ^ Maximal lower brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. Zero by default.+    -> Maybe color+        -- ^ Maximal upper brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. Zero by default.+    -> FloodFillOperationFlags+    -> m Rect2i+floodFill img mbMask seedPoint color mLoDiff mUpDiff opFlags =+    unsafePrimToPrim $+    withPtr img $ \matPtr ->+    withPtr mbMask $ \maskPtr ->+    withPtr (toPoint seedPoint) $ \seedPointPtr ->+    withPtr (toScalar color) $ \colorPtr ->+    withPtr loDiff $ \loDiffPtr ->+    withPtr upDiff $ \upDiffPtr ->+    withPtr rect $ \rectPtr -> do+      [C.block|void {+        cv::Mat * maskPtr = $(Mat * maskPtr);+        cv::floodFill( *$(Mat * matPtr)+                     , maskPtr ? cv::_InputOutputArray(*maskPtr) : cv::_InputOutputArray(noArray())+                     , *$(Point2i * seedPointPtr)+                     , *$(Scalar * colorPtr)+                     , $(Rect2i * rectPtr)+                     , *$(Scalar * loDiffPtr)+                     , *$(Scalar * upDiffPtr)+                     , $(int32_t c'opFlags)+                     );+      }|]+      pure rect+  where+    rect :: Rect2i+    rect = toRect HRect{ hRectTopLeft = pure 0+                       , hRectSize    = pure 0+                       }+    c'opFlags = marshalFloodFillOperationFlags opFlags+    zeroScalar = toScalar (pure 0 :: V4 Double)+    loDiff = maybe zeroScalar toScalar mLoDiff+    upDiff = maybe zeroScalar toScalar mUpDiff++data FloodFillOperationFlags+   = FloodFillOperationFlags+   { floodFillConnectivity :: Word8+      -- ^ Connectivity value. The default value of 4 means that only the four nearest neighbor pixels (those that share+      -- an edge) are considered. A connectivity value of 8 means that the eight nearest neighbor pixels (those that share+      -- a corner) will be considered.+   , floodFillMaskFillColor :: Word8+      -- ^ Value between 1 and 255 with which to fill the mask (the default value is 1).+   , floodFillFixedRange :: Bool+      -- ^ If set, the difference between the current pixel and seed pixel is considered. Otherwise, the difference+      -- between neighbor pixels is considered (that is, the range is floating).+   , floodFillMaskOnly :: Bool+      -- ^ If set, the function does not change the image ( newVal is ignored), and only fills the mask with the+      -- value specified in bits 8-16 of flags as described above. This option only make sense in function variants+      -- that have the mask parameter.+   }++defaultFloodFillOperationFlags :: FloodFillOperationFlags+defaultFloodFillOperationFlags =+    FloodFillOperationFlags+    { floodFillConnectivity = 4+    , floodFillMaskFillColor = 1+    , floodFillFixedRange = False+    , floodFillMaskOnly = False+    }++marshalFloodFillOperationFlags :: FloodFillOperationFlags -> Int32+marshalFloodFillOperationFlags opFlags =+    let connectivityBits = fromIntegral (floodFillConnectivity opFlags)+        maskFillColorBits = fromIntegral (floodFillMaskFillColor opFlags) `shiftL` 8+        fixedRangeBits = if floodFillFixedRange opFlags then c'FLOODFILL_FIXED_RANGE else 0+        fillMaskOnlyBits = if floodFillMaskOnly opFlags then c'FLOODFILL_MASK_ONLY else 0+    in connectivityBits .|. maskFillColorBits .|. fixedRangeBits .|. fillMaskOnlyBits++-- TODO (RvD): Otsu and triangle are only implemented for 8 bit images.++{- | Applies a fixed-level threshold to each array element++The function applies fixed-level thresholding to a single-channel array. The+function is typically used to get a bi-level (binary) image out of a+grayscale image or for removing a noise, that is, filtering out pixels with+too small or too large values. There are several types of thresholding+supported by the function.++Example:++@+grayBirds :: Mat (ShapeT [341, 512]) ('S 1) ('S Word8)+grayBirds = exceptError $ cvtColor bgr gray birds_512x341++threshBinaryBirds :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+threshBinaryBirds =+    exceptError $ cvtColor gray bgr $ fst $ exceptError $+    threshold (ThreshVal_Abs 100) (Thresh_Binary 150) grayBirds++threshBinaryInvBirds :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+threshBinaryInvBirds =+    exceptError $ cvtColor gray bgr $ fst $ exceptError $+    threshold (ThreshVal_Abs 100) (Thresh_BinaryInv 150) grayBirds++threshTruncateBirds :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+threshTruncateBirds =+    exceptError $ cvtColor gray bgr $ fst $ exceptError $+    threshold (ThreshVal_Abs 100) Thresh_Truncate grayBirds++threshToZeroBirds :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+threshToZeroBirds =+    exceptError $ cvtColor gray bgr $ fst $ exceptError $+    threshold (ThreshVal_Abs 100) Thresh_ToZero grayBirds++threshToZeroInvBirds :: Mat (ShapeT [341, 512]) ('S 3) ('S Word8)+threshToZeroInvBirds =+    exceptError $ cvtColor gray bgr $ fst $ exceptError $+    threshold (ThreshVal_Abs 100) Thresh_ToZeroInv grayBirds+@++<<doc/generated/examples/threshBinaryBirds.png threshBinaryBirds>>+<<doc/generated/examples/threshBinaryInvBirds.png threshBinaryInvBirds>>+<<doc/generated/examples/threshTruncateBirds.png threshTruncateBirds>>+<<doc/generated/examples/threshToZeroBirds.png threshToZeroBirds>>+<<doc/generated/examples/threshToZeroInvBirds.png threshToZeroInvBirds>>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/miscellaneous_transformations.html#threshold OpenCV Sphinx doc>+-}+threshold+    :: (depth `In` [Word8, Float])+    => ThreshValue -- ^+    -> ThreshType+    -> (Mat shape ('S 1) ('S depth))+    -> CvExcept (Mat shape ('S 1) ('S depth), Double)+threshold threshVal threshType src = unsafeWrapException $ do+    dst <- newEmptyMat+    alloca $ \calcThreshPtr ->+      handleCvException ((unsafeCoerceMat dst, ) . realToFrac <$> peek calcThreshPtr) $+      withPtr src $ \srcPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          *$(double * calcThreshPtr) =+            cv::threshold( *$(Mat * srcPtr)+                         , *$(Mat * dstPtr)+                         , $(double c'threshVal)+                         , $(double c'maxVal)+                         , $(int32_t c'type)+                         );+        |]+  where+    c'type = c'threshType .|. c'threshValMode+    (c'threshType, c'maxVal) = marshalThreshType threshType+    (c'threshValMode, c'threshVal) = marshalThreshValue threshVal+++{- | Performs a marker-based image segmentation using the watershed algorithm.++The function implements one of the variants of watershed, non-parametric marker-based segmentation algorithm, described in [Meyer, F. Color Image Segmentation, ICIP92, 1992].++Before passing the image to the function, you have to roughly outline the desired regions in the image markers with positive (>0) indices. So, every region is represented as one or more connected components with the pixel values 1, 2, 3, and so on. Such markers can be retrieved from a binary mask using 'findContours' and 'drawContours'. The markers are “seeds” of the future image regions. All the other pixels in markers , whose relation to the outlined regions is not known and should be defined by the algorithm, should be set to 0’s. In the function output, each pixel in markers is set to a value of the “seed” components or to -1 at boundaries between the regions.++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/miscellaneous_transformations.html#watershed OpenCV Sphinx doc>+-}+watershed+  :: (PrimMonad m)+  => Mat ('S [h, w]) ('S 3) ('S Word8) -- ^ Input 8-bit 3-channel image+  -> Mut (Mat ('S [h, w]) ('S 1) ('S Int32)) (PrimState m) -- ^ Input/output 32-bit single-channel image (map) of markers+  -> CvExceptT m ()+watershed img markers =+    unsafePrimToPrim $+    withPtr img $ \imgPtr ->+    withPtr markers $ \markersPtr ->+      [C.exp|void {+        cv::watershed( *$(Mat * imgPtr)+                     , *$(Mat * markersPtr)+                     )+      }|]++{- | Runs the <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/miscellaneous_transformations.html#grabcut GrabCut> algorithm.++Example:++@+grabCutBird :: Birds_512x341+grabCutBird = exceptError $ do+    mask <- withMatM (Proxy :: Proxy [341, 512])+                     (Proxy :: Proxy 1)+                     (Proxy :: Proxy Word8)+                     black $ \\mask -> do+      fgTmp <- mkMatM (Proxy :: Proxy [1, 65]) (Proxy :: Proxy 1) (Proxy :: Proxy Double) black+      bgTmp <- mkMatM (Proxy :: Proxy [1, 65]) (Proxy :: Proxy 1) (Proxy :: Proxy Double) black+      grabCut birds_512x341 mask fgTmp bgTmp 5 (GrabCut_InitWithRect rect)+    mask' <- matScalarCompare mask 3 Cmp_Ge+    withMatM (Proxy :: Proxy [341, 512])+             (Proxy :: Proxy 3)+             (Proxy :: Proxy Word8)+             transparent $ \\imgM -> do+      matCopyToM imgM (V2 0 0) birds_512x341 (Just mask')+  where+    rect :: Rect Int32+    rect = toRect $ HRect { hRectTopLeft = V2 264 60, hRectSize = V2 248 281 }+@++<<doc/generated/examples/grabCutBird.png grabCutBird>>++-}+grabCut+    :: ( PrimMonad m+       , depth `In` '[ 'D, 'S Word8 ]+       )+    => Mat shape ('S 3) depth+        -- ^ Input 8-bit 3-channel image.+    -> Mut (Mat shape ('S 1) ('S Word8)) (PrimState m)+        -- ^ Input/output 8-bit single-channel mask. The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. Its elements may have one of following values:+        --+        --     * GC_BGD defines an obvious background pixels.+        --+        --     * GC_FGD defines an obvious foreground (object) pixel.+        --+        --     * GC_PR_BGD defines a possible background pixel.+        --+        --     * GC_PR_FGD defines a possible foreground pixel.+    -> Mut (Mat ('S ['S 1, 'S 65]) ('S 1) ('S Double)) (PrimState m)+        -- ^ Temporary array for the background model. Do not modify it while you are processing the same image.+    -> Mut (Mat ('S ['S 1, 'S 65]) ('S 1) ('S Double)) (PrimState m)+        -- ^ Temporary arrays for the foreground model. Do not modify it while you are processing the same image.+    -> Int32+        -- ^ Number of iterations the algorithm should make before returning the result. Note that the result can be refined with further calls with mode==GC_INIT_WITH_MASK or mode==GC_EVAL.+    -> GrabCutOperationMode+        -- ^ Operation mode+    -> CvExceptT m ()+grabCut img mask bgdModel fgdModel iterCount mode =+    unsafePrimToPrim $+    withPtr img $ \imgPtr ->+    withPtr mask $ \maskPtr ->+    withPtr rect $ \rectPtr ->+    withPtr bgdModel $ \bgdModelPtr ->+    withPtr fgdModel $ \fgdModelPtr ->+      [C.block|void {+        cv::grabCut( *$(Mat * imgPtr)+                   , *$(Mat * maskPtr)+                   , *$(Rect2i * rectPtr)+                   , *$(Mat * bgdModelPtr)+                   , *$(Mat * fgdModelPtr)+                   , $(int32_t iterCount)+                   , $(int32_t c'modeFlags)+                   );+      }|]+  where+    rect = marshalGrabCutOperationModeRect mode+    c'modeFlags = marshalGrabCutOperationMode mode++{- | Returns 0 if the pixels are not in the range, 255 otherwise. -}+inRange ::+     (ToScalar scalar)+  => Mat ('S [w, h]) channels depth+  -> scalar -- ^ Lower bound+  -> scalar -- ^ Upper bound+  -> CvExcept (Mat ('S [w, h]) ('S 1) ('S Word8))+inRange src lo hi = unsafeWrapException $ do+  dst <- newEmptyMat+  withPtr src $ \srcPtr ->+    handleCvException (return (unsafeCoerceMat dst)) $+    withPtr (toScalar lo) $ \loPtr ->+    withPtr (toScalar hi) $ \hiPtr ->+    withPtr dst $ \dstPtr ->+      [cvExcept|+        cv::inRange(*$(Mat * srcPtr), *$(Scalar * loPtr), *$(Scalar * hiPtr), *$(Mat * dstPtr));+      |]
+ src/OpenCV/ImgProc/MiscImgTransform/ColorCodes.hs view
@@ -0,0 +1,106 @@+module OpenCV.ImgProc.MiscImgTransform.ColorCodes+    ( ColorConversion+    , ColorCode(..)+    , ColorCodeChannels+    , ColorCodeDepth+    , ColorCodeMatchesChannels++      -- ** Color code proxies+    , bayerBG+    , bayerGB+    , bayerGR+    , bayerRG+    , bgr+    , bgr555+    , bgr565+    , bgra+    , bgra_I420+    , bgra_IYUV+    , bgra_NV12+    , bgra_NV21+    , bgra_UYNV+    , bgra_UYVY+    , bgra_Y422+    , bgra_YUNV+    , bgra_YUY2+    , bgra_YUYV+    , bgra_YV12+    , bgra_YVYU+    , bgr_EA+    , bgr_FULL+    , bgr_I420+    , bgr_IYUV+    , bgr_NV12+    , bgr_NV21+    , bgr_UYNV+    , bgr_UYVY+    , bgr_VNG+    , bgr_Y422+    , bgr_YUNV+    , bgr_YUY2+    , bgr_YUYV+    , bgr_YV12+    , bgr_YVYU+    , gray+    , gray_420+    , gray_I420+    , gray_IYUV+    , gray_NV12+    , gray_NV21+    , gray_UYNV+    , gray_UYVY+    , gray_Y422+    , gray_YUNV+    , gray_YUY2+    , gray_YUYV+    , gray_YV12+    , gray_YVYU+    , hls+    , hls_FULL+    , hsv+    , hsv_FULL+    , lab+    , lbgr+    , lrgb+    , luv+    , mrgba+    , rgb+    , rgba+    , rgba_I420+    , rgba_IYUV+    , rgba_NV12+    , rgba_NV21+    , rgba_UYNV+    , rgba_UYVY+    , rgba_Y422+    , rgba_YUNV+    , rgba_YUY2+    , rgba_YUYV+    , rgba_YV12+    , rgba_YVYU+    , rgb_EA+    , rgb_FULL+    , rgb_I420+    , rgb_IYUV+    , rgb_NV12+    , rgb_NV21+    , rgb_UYNV+    , rgb_UYVY+    , rgb_VNG+    , rgb_Y422+    , rgb_YUNV+    , rgb_YUY2+    , rgb_YUYV+    , rgb_YV12+    , rgb_YVYU+    , xyz+    , yCrCb+    , yuv+    , yuv420p+    , yuv420sp+    , yuv_I420+    , yuv_IYUV+    , yuv_YV12+    ) where++import "this" OpenCV.Internal.ImgProc.MiscImgTransform.ColorCodes
+ src/OpenCV/ImgProc/ObjectDetection.cpp view
@@ -0,0 +1,30 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++#include "opencv2/objdetect.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_ObjectDetection_0_bea3a019a4b2867a729135479f483faecee14380(Mat * imagePtr_inline_c_0, Mat * templPtr_inline_c_1, Mat * resultPtr_inline_c_2, int32_t cmethod_27_inline_c_3) {++  try+  {   +          cv::matchTemplate( *imagePtr_inline_c_0+                           , *templPtr_inline_c_1+                           , *resultPtr_inline_c_2+                           , cmethod_27_inline_c_3+                           );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/ImgProc/ObjectDetection.hsc view
@@ -0,0 +1,135 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.ImgProc.ObjectDetection+    ( MatchTemplateMethod(..)+    , MatchTemplateNormalisation(..)+    , matchTemplate+    ) where++import "base" Data.Int+import "base" Data.Word+import "base" GHC.TypeLits+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.include "opencv2/objdetect.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"+#include "hsc_macros.hpp"++--------------------------------------------------------------------------------++-- | <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/object_detection.html#matchtemplate OpenCV Sphinx doc>+data MatchTemplateMethod+   = MatchTemplateSqDiff+       -- ^ * not normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/f096a706cb9499736423f10d901c7fe13a1e6926.png>>+       --   * normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/6d6a720237b3a4c1365c8e86a9cfcf0895d5e265.png>>+   | MatchTemplateCCorr+       -- ^ * not normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/93f1747a86a3c5095a0e6a187442c6e2a0ae0968.png>>+       --   * normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/6a72ad9ae17c4dad88e33ed16308fc1cfba549b8.png>>+   | MatchTemplateCCoeff+       -- ^ * not normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/c9b62df96d0692d90cc1d8a5912a68a44461910c.png>>+       --   * where <<http://docs.opencv.org/3.0-last-rst/_images/math/ffb6954b6020b02e13b73c79bd852c1627cfb79c.png>>+       --   * normed: <<http://docs.opencv.org/3.0-last-rst/_images/math/235e42ec68d2d773899efcf0a4a9d35a7afedb64.png>>+     deriving Show++-- | Whether to use normalisation. See 'MatchTemplateMethod'.+data MatchTemplateNormalisation+   = MatchTemplateNotNormed+   | MatchTemplateNormed+   deriving (Show, Eq)++#num CV_TM_SQDIFF+#num CV_TM_SQDIFF_NORMED+#num CV_TM_CCORR+#num CV_TM_CCORR_NORMED+#num CV_TM_CCOEFF+#num CV_TM_CCOEFF_NORMED++marshalMatchTemplateMethod :: MatchTemplateMethod -> Bool -> Int32+marshalMatchTemplateMethod m n =+    case (m, n) of+      (MatchTemplateSqDiff, False) -> c'CV_TM_SQDIFF+      (MatchTemplateSqDiff, True ) -> c'CV_TM_SQDIFF_NORMED+      (MatchTemplateCCorr , False) -> c'CV_TM_CCORR+      (MatchTemplateCCorr , True ) -> c'CV_TM_CCORR_NORMED+      (MatchTemplateCCoeff, False) -> c'CV_TM_CCOEFF+      (MatchTemplateCCoeff, True ) -> c'CV_TM_CCOEFF_NORMED++-- | <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/object_detection.html#matchtemplate OpenCV Sphinx doc>+--+-- Compares a template against overlapped image regions.+--+-- The function slides through image, compares the overlapped patches+-- of size+-- <<http://docs.opencv.org/3.0-last-rst/_images/math/d47153257f0243694e5632bb23b85009eb9e5599.png w \times h>>+-- against templ using the specified method and stores the comparison+-- results in result . Here are the formulae for the available+-- comparison methods+-- (<<http://docs.opencv.org/3.0-last-rst/_images/math/06f9f0fcaa8d96a6a23b0f7d1566fe5efaa789ad.png I>> denotes image,+-- <<http://docs.opencv.org/3.0-last-rst/_images/math/87804527283a4539e1e17c5861df8cb92a97fd6d.png T>> template,+-- <<http://docs.opencv.org/3.0-last-rst/_images/math/8fa391da5431a5d6eaba1325c3e7cb3da22812b5.png R>> result).+-- The summation is done over template and/or the image patch:+-- <<http://docs.opencv.org/3.0-last-rst/_images/math/ff90cafd4a71d85875237787b54815ee8ac77bff.png x' = 0...w-1, y' = 0...h-1>>+matchTemplate+    :: ( depth `In` [Word8, Float]+       , Length searchShape <= 2+       )+    => Mat ('S searchShape) ('S 1) ('S depth)+       -- ^ Image where the search is running. It must be 8-bit or 32-bit floating-point.+    -> Mat ('S [th, tw]) ('S 1) ('S depth)+       -- ^ Searched template. It must be not greater than the source image and have the same data type.+    -> MatchTemplateMethod+       -- ^ Parameter specifying the comparison method.+    -> MatchTemplateNormalisation+       -- ^ Normalise+    -> CvExcept (Mat ('S [rh, rw]) ('S 1) ('S Float))+       -- ^ Map of comparison results. It must be single-channel 32-bit floating-point.+       -- If image is+       -- <<http://docs.opencv.org/3.0-last-rst/_images/math/e4926c3d97c3f7434c6317ba24b8b9294a0aba64.png>>+       -- and templ is+       -- <<http://docs.opencv.org/3.0-last-rst/_images/math/d47153257f0243694e5632bb23b85009eb9e5599.png>>+       -- , then result is+       -- <<http://docs.opencv.org/3.0-last-rst/_images/math/e318d7237b57e08135e689fd9136b9ac8e4a4102.png>>.+matchTemplate image templ method normalisation = unsafeWrapException $ do+    result <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat result) $+      withPtr result $ \resultPtr ->+      withPtr image $ \imagePtr ->+      withPtr templ $ \templPtr ->+        [cvExcept|+          cv::matchTemplate( *$(Mat * imagePtr)+                           , *$(Mat * templPtr)+                           , *$(Mat * resultPtr)+                           , $(int32_t c'method)+                           );+        |]+  where+    normed =+      case normalisation of+        MatchTemplateNotNormed -> False+        MatchTemplateNormed -> True+    c'method = marshalMatchTemplateMethod method normed
+ src/OpenCV/ImgProc/StructuralAnalysis.cpp view
@@ -0,0 +1,192 @@++#include "opencv2/core.hpp"++#include "opencv2/imgproc.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_ImgProc_StructuralAnalysis_0_7935fba0a7f8ba80a4bbee32ab76a2a8748ac730(Point2f * contourPtr_inline_c_0, int32_t cnumPoints_27_inline_c_1, double * carea_27_inline_c_2, bool coriented_27_inline_c_3) {++  try+  {   +        cv::_InputArray contour =+          cv::_InputArray( contourPtr_inline_c_0+                         , cnumPoints_27_inline_c_1+                         );+        *carea_27_inline_c_2 = cv::contourArea(contour, coriented_27_inline_c_3);+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_StructuralAnalysis_1_4b2ac3789eb26d10e61f390b3818a71f30a3a509(Point2f * contourPtr_inline_c_0, int32_t cnumPoints_27_inline_c_1, double * cresultPtr_27_inline_c_2, Point2f * ptPtr_inline_c_3, bool cmeasureDist_27_inline_c_4) {++  try+  {   +        cv::_InputArray contour =+          cv::_InputArray( contourPtr_inline_c_0+                         , cnumPoints_27_inline_c_1+                         );+        *cresultPtr_27_inline_c_2 =+          cv::pointPolygonTest( contour+                              , *ptPtr_inline_c_3+                              , cmeasureDist_27_inline_c_4+                              );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_ImgProc_StructuralAnalysis_2_614023623c1bbdf57403aa0cb1c576902533a9fe(Mat * srcPtr_inline_c_0, int32_t cmode_27_inline_c_1, int32_t cmethod_27_inline_c_2, int32_t * numContoursPtr_inline_c_3, Point2i **** contoursPtrPtr_inline_c_4, Vec4i *** hierarchyPtrPtr_inline_c_5, int32_t ** contourLengthsPtrPtr_inline_c_6) {++      std::vector<std::vector<cv::Point>> contours;+      std::vector<cv::Vec4i> hierarchy;+      cv::findContours(+        *srcPtr_inline_c_0,+        contours,+        hierarchy,+        cmode_27_inline_c_1,+        cmethod_27_inline_c_2+      );++      *numContoursPtr_inline_c_3 = contours.size();++      cv::Point * * * * contoursPtrPtr = contoursPtrPtr_inline_c_4;+      cv::Point * * * contoursPtr = new cv::Point * * [contours.size()];+      *contoursPtrPtr = contoursPtr;++      cv::Vec4i * * * hierarchyPtrPtr = hierarchyPtrPtr_inline_c_5;+      cv::Vec4i * * hierarchyPtr = new cv::Vec4i * [contours.size()];+      *hierarchyPtrPtr = hierarchyPtr;++      int32_t * * contourLengthsPtrPtr = contourLengthsPtrPtr_inline_c_6;+      int32_t * contourLengthsPtr = new int32_t [contours.size()];+      *contourLengthsPtrPtr = contourLengthsPtr;++      for (std::vector<std::vector<cv::Point>>::size_type i = 0; i < contours.size(); i++) {+        std::vector<cv::Point> & contourPoints = contours[i];+        cv::Vec4i hierarchyInfo = hierarchy[i];++        contourLengthsPtr[i] = contourPoints.size();++        cv::Point * * newContourPoints = new cv::Point * [contourPoints.size()];+        for (std::vector<cv::Point>::size_type j = 0; j < contourPoints.size(); j++) {+          cv::Point & orig = contourPoints[j];+          cv::Point * newPt = new cv::Point(orig.x, orig.y);+          newContourPoints[j] = newPt;+        }+        contoursPtr[i] = newContourPoints;++        hierarchyPtr[i] = new cv::Vec4i(+          hierarchyInfo[0],+          hierarchyInfo[1],+          hierarchyInfo[2],+          hierarchyInfo[3]+        );+      }+    +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_StructuralAnalysis_3_ff5ea92778e465a6335a4692b484c0bf9d4d34d0(Point2i **** contoursPtrPtr_inline_c_0, Vec4i *** hierarchyPtrPtr_inline_c_1, int32_t ** contourLengthsPtrPtr_inline_c_2) {++      delete [] *contoursPtrPtr_inline_c_0;+      delete [] *hierarchyPtrPtr_inline_c_1;+      delete [] *contourLengthsPtrPtr_inline_c_2;+    +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_StructuralAnalysis_4_b1965061fd4c69b7637c516ababa8f2fae19bdde(Point2i * curvePtr_inline_c_0, int32_t cnumPoints_27_inline_c_1, double cepsilon_27_inline_c_2, bool cisClosed_27_inline_c_3, int32_t * numPointsResPtr_inline_c_4, Point2i *** pointsResPtrPtr_inline_c_5) {++        std::vector<cv::Point> points_res;+        cv::_InputArray curve = cv::_InputArray (curvePtr_inline_c_0, cnumPoints_27_inline_c_1);+        cv::approxPolyDP+        (  curve+        ,  points_res+        ,  cepsilon_27_inline_c_2+        ,  cisClosed_27_inline_c_3+        );++        *numPointsResPtr_inline_c_4 = points_res.size();++        cv::Point * * * pointsResPtrPtr = pointsResPtrPtr_inline_c_5;+        cv::Point * * pointsResPtr = new cv::Point * [points_res.size()];+        *pointsResPtrPtr = pointsResPtr;++        for (std::vector<cv::Point>::size_type i = 0; i < points_res.size(); i++) {+            cv::Point & ptAddress = points_res[i];+            cv::Point * newPt = new cv::Point(ptAddress.x, ptAddress.y);+            pointsResPtr[i] = newPt;+        }+      +}++}++extern "C" {+void inline_c_OpenCV_ImgProc_StructuralAnalysis_5_c6aa8b9807565075fddddcc34edf8efb263f7d67(Point2i *** pointsResPtrPtr_inline_c_0) {++        delete [] *pointsResPtrPtr_inline_c_0;+      +}++}++extern "C" {+Exception * inline_c_OpenCV_ImgProc_StructuralAnalysis_6_1fed7fd1e0382f9c24232067deba04c89c597064(Point2i * curvePtr_inline_c_0, int32_t cnumPoints_27_inline_c_1, double * cresultPtr_27_inline_c_2, bool cisClosed_27_inline_c_3) {++  try+  {   +            cv::_InputArray curve =+              cv::_InputArray ( curvePtr_inline_c_0+                              , cnumPoints_27_inline_c_1+                              );+            *cresultPtr_27_inline_c_2 =+               cv::arcLength( curve+                              , cisClosed_27_inline_c_3+                            );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+RotatedRect * inline_c_OpenCV_ImgProc_StructuralAnalysis_7_a83635d7b79cb79d9a94886051098775b48130e1(Point2i * pointsPtr_inline_c_0, int32_t cnumPoints_27_inline_c_1) {+return (+          new RotatedRect(+            cv::minAreaRect(+                cv::_InputArray( pointsPtr_inline_c_0+                               , cnumPoints_27_inline_c_1)))+        );+}++}
+ src/OpenCV/ImgProc/StructuralAnalysis.hsc view
@@ -0,0 +1,401 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.ImgProc.StructuralAnalysis+    ( contourArea+    , pointPolygonTest+    , findContours+    , Contour(..)+    , ContourAreaOriented(..)+    , ContourRetrievalMode(..)+    , ContourApproximationMethod(..)+    , approxPolyDP+    , arcLength+    , minAreaRect+    ) where++import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "base" Control.Exception ( mask_ )+import "base" Control.Monad (guard)+import "base" Data.Functor (($>))+import "base" Data.Int+import "base" Data.Maybe (mapMaybe)+import "base" Data.Traversable (for)+import qualified "vector" Data.Vector as V+import "base" Data.Word+import "base" Foreign.C.Types+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( peekArray )+import "base" Foreign.Marshal.Utils ( fromBool )+import "base" Foreign.Ptr ( Ptr )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "linear" Linear.V4 ( V4(..) )+import "this" OpenCV.Core.Types ( Mut )+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Core.Types.Vec ( fromVec )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/imgproc.hpp"++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/imgproc.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------+-- Structural Analysis and Shape Descriptors+--------------------------------------------------------------------------------++{- | Calculates a contour area.++The function computes a contour area. Similarly to `moments`, the area is+computed using the <https://en.wikipedia.org/wiki/Green%27s_theorem Green formula>.+Thus, the returned area and the number of non-zero pixels, if you draw the+contour using `drawContours` or `fillPoly`, can be different. Also, the function+will most certainly give a wrong results for contours with self-intersections.++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contourarea#cv2.contourArea OpenCV Sphinx doc>+-}+contourArea+    :: (IsPoint2 point2 CFloat)+    => V.Vector (point2 CFloat)+       -- ^ Input vector of 2D points (contour vertices).+    -> ContourAreaOriented+       -- ^ Signed or unsigned area+    -> CvExcept Double+contourArea contour areaOriented = unsafeWrapException $+    withArrayPtr (V.map toPoint contour) $ \contourPtr ->+    alloca $ \c'area ->+    handleCvException (realToFrac <$> peek c'area) $+      [cvExcept|+        cv::_InputArray contour =+          cv::_InputArray( $(Point2f * contourPtr)+                         , $(int32_t c'numPoints)+                         );+        *$(double * c'area) = cv::contourArea(contour, $(bool c'oriented));+      |]+  where+    oriented =+      case areaOriented of+        ContourAreaOriented -> True+        ContourAreaAbsoluteValue -> False+    c'numPoints = fromIntegral $ V.length contour+    c'oriented = fromBool oriented++-- | Performs a point-in-contour test.+--+-- The function determines whether the point is inside a contour, outside, or+-- lies on an edge (or coincides with a vertex). It returns positive (inside),+-- negative (outside), or zero (on an edge) value, correspondingly. When+-- measureDist=false , the return value is +1, -1, and 0,+-- respectively. Otherwise, the return value is a signed distance between the+-- point and the nearest contour edge.+--+-- <http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#pointpolygontest OpenCV Sphinx doc>+pointPolygonTest+    :: ( IsPoint2 contourPoint2 CFloat+       , IsPoint2 testPoint2    CFloat+       )+    => V.Vector (contourPoint2 CFloat) -- ^ Contour.+    -> testPoint2 CFloat -- ^ Point tested against the contour.+    -> Bool+       -- ^ If true, the function estimates the signed distance from the point+       -- to the nearest contour edge. Otherwise, the function only checks if+       -- the point is inside a contour or not.+    -> CvExcept Double+pointPolygonTest contour pt measureDist = unsafeWrapException $+    withArrayPtr (V.map toPoint contour) $ \contourPtr ->+    withPtr (toPoint pt) $ \ptPtr ->+    alloca $ \c'resultPtr ->+    handleCvException (realToFrac <$> peek c'resultPtr) $+      [cvExcept|+        cv::_InputArray contour =+          cv::_InputArray( $(Point2f * contourPtr)+                         , $(int32_t c'numPoints)+                         );+        *$(double * c'resultPtr) =+          cv::pointPolygonTest( contour+                              , *$(Point2f * ptPtr)+                              , $(bool c'measureDist)+                              );+      |]+  where+    c'numPoints = fromIntegral $ V.length contour+    c'measureDist = fromBool measureDist++-- | Oriented area flag.+data ContourAreaOriented+  = ContourAreaOriented+    -- ^ Return a signed area value, depending on the contour orientation (clockwise or+    -- counter-clockwise). Using this feature you can determine orientation+    -- of a contour by taking the sign of an area.+  | ContourAreaAbsoluteValue+    -- ^ Return the area as an absolute value.++data ContourRetrievalMode+  = ContourRetrievalExternal+    -- ^ Retrieves only the extreme outer contours.+  | ContourRetrievalList+    -- ^ Retrieves all of the contours without establishing any hierarchical relationships.+  | ContourRetrievalCComp+    -- ^ Retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.+  | ContourRetrievalTree+    -- ^ Retrieves all of the contours and reconstructs a full hierarchy of nested contours.++data ContourApproximationMethod+  = ContourApproximationNone+    -- ^ Stores absolutely all the contour points. That is, any 2 subsequent points @(x1,y1)@ and @(x2,y2)@ of the contour will be either horizontal, vertical or diagonal neighbors, that is, @max(abs(x1-x2),abs(y2-y1)) == 1@.+  | ContourApproximationSimple+    -- ^ Compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.+  | ContourApproximationTC89L1+  | ContourApproximationTC89KCOS++#num CV_RETR_EXTERNAL+#num CV_RETR_LIST+#num CV_RETR_CCOMP+#num CV_RETR_TREE+#num CV_CHAIN_APPROX_NONE+#num CV_CHAIN_APPROX_SIMPLE+#num CV_CHAIN_APPROX_TC89_L1+#num CV_CHAIN_APPROX_TC89_KCOS++marshalContourRetrievalMode+  :: ContourRetrievalMode -> Int32+marshalContourRetrievalMode = \case+  ContourRetrievalExternal -> c'CV_RETR_EXTERNAL+  ContourRetrievalList     -> c'CV_RETR_LIST+  ContourRetrievalCComp    -> c'CV_RETR_CCOMP+  ContourRetrievalTree     -> c'CV_RETR_TREE++marshalContourApproximationMethod+  :: ContourApproximationMethod -> Int32+marshalContourApproximationMethod = \case+  ContourApproximationNone     -> c'CV_CHAIN_APPROX_NONE+  ContourApproximationSimple   -> c'CV_CHAIN_APPROX_SIMPLE+  ContourApproximationTC89L1   -> c'CV_CHAIN_APPROX_TC89_L1+  ContourApproximationTC89KCOS -> c'CV_CHAIN_APPROX_TC89_KCOS++data Contour =+     Contour+     { contourPoints   :: !(V.Vector Point2i)+     , contourChildren :: !(V.Vector Contour)+     } deriving Show++findContours+  :: (PrimMonad m)+  => ContourRetrievalMode+  -> ContourApproximationMethod+  -> Mut (Mat ('S [h, w]) ('S 1) ('S Word8)) (PrimState m)+  -> m (V.Vector Contour)+findContours mode method src = unsafePrimToPrim $+  withPtr src $ \srcPtr ->+  alloca $ \(contourLengthsPtrPtr :: Ptr (Ptr Int32)) ->+  alloca $ \(contoursPtrPtr :: Ptr (Ptr (Ptr (Ptr C'Point2i)))) ->+  alloca $ \(hierarchyPtrPtr :: Ptr (Ptr (Ptr C'Vec4i))) ->+  alloca $ \(numContoursPtr :: Ptr Int32) -> mask_ $ do+    [C.block| void {+      std::vector<std::vector<cv::Point>> contours;+      std::vector<cv::Vec4i> hierarchy;+      cv::findContours(+        *$(Mat * srcPtr),+        contours,+        hierarchy,+        $(int32_t c'mode),+        $(int32_t c'method)+      );++      *$(int32_t * numContoursPtr) = contours.size();++      cv::Point * * * * contoursPtrPtr = $(Point2i * * * * contoursPtrPtr);+      cv::Point * * * contoursPtr = new cv::Point * * [contours.size()];+      *contoursPtrPtr = contoursPtr;++      cv::Vec4i * * * hierarchyPtrPtr = $(Vec4i * * * hierarchyPtrPtr);+      cv::Vec4i * * hierarchyPtr = new cv::Vec4i * [contours.size()];+      *hierarchyPtrPtr = hierarchyPtr;++      int32_t * * contourLengthsPtrPtr = $(int32_t * * contourLengthsPtrPtr);+      int32_t * contourLengthsPtr = new int32_t [contours.size()];+      *contourLengthsPtrPtr = contourLengthsPtr;++      for (std::vector<std::vector<cv::Point>>::size_type i = 0; i < contours.size(); i++) {+        std::vector<cv::Point> & contourPoints = contours[i];+        cv::Vec4i hierarchyInfo = hierarchy[i];++        contourLengthsPtr[i] = contourPoints.size();++        cv::Point * * newContourPoints = new cv::Point * [contourPoints.size()];+        for (std::vector<cv::Point>::size_type j = 0; j < contourPoints.size(); j++) {+          cv::Point & orig = contourPoints[j];+          cv::Point * newPt = new cv::Point(orig.x, orig.y);+          newContourPoints[j] = newPt;+        }+        contoursPtr[i] = newContourPoints;++        hierarchyPtr[i] = new cv::Vec4i(+          hierarchyInfo[0],+          hierarchyInfo[1],+          hierarchyInfo[2],+          hierarchyInfo[3]+        );+      }+    }|]++    numContours <- fromIntegral <$> peek numContoursPtr++    contourLengthsPtr <- peek contourLengthsPtrPtr+    contourLengths <- peekArray numContours contourLengthsPtr++    contoursPtr <- peek contoursPtrPtr+    unmarshalledContours <- peekArray numContours contoursPtr++    allContours <- for (zip unmarshalledContours contourLengths) $ \(contourPointsPtr,n) ->+      fmap V.fromList+           (peekArray (fromIntegral n) contourPointsPtr >>= mapM (fromPtr . pure))++    hierarchyPtr <- peek hierarchyPtrPtr+    (hierarchy :: [V4 Int32]) <-+        peekArray numContours hierarchyPtr >>=+        mapM (fmap fromVec . fromPtr . pure)++    let treeHierarchy :: V.Vector ([Contour], Bool)+        treeHierarchy = V.fromList $+          zipWith+            (\(V4 nextSibling previousSibling firstChild parent) points ->+              ( Contour { contourPoints = points+                        , contourChildren =+                            if firstChild < 0+                            then mempty+                            else V.fromList $ fst $ treeHierarchy V.! fromIntegral firstChild+                        } : if nextSibling < 0+                            then []+                            else fst $ treeHierarchy V.! fromIntegral nextSibling+              , parent < 0 && previousSibling < 0+              )+            )+            hierarchy+            allContours++    [CU.block| void {+      delete [] *$(Point2i * * * * contoursPtrPtr);+      delete [] *$(Vec4i * * * hierarchyPtrPtr);+      delete [] *$(int32_t * * contourLengthsPtrPtr);+    } |]++    return $ V.fromList $ concat+           $ mapMaybe (\(contours,isRoot) -> guard isRoot $> contours)+           $ V.toList treeHierarchy+  where+    c'mode = marshalContourRetrievalMode mode+    c'method = marshalContourApproximationMethod method++{- | Approximates a polygonal curve(s) with the specified precision.++The functions approxPolyDP approximate a curve or a polygon with another+curve/polygon with less vertices so that the distance between them is less or+equal to the specified precision. It uses the+<http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm Douglas-Peucker algorithm>++<http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=contourarea#approxpolydp>+-}+approxPolyDP+    :: (IsPoint2 point2 Int32)+    => V.Vector (point2 Int32)+    -> Double -- ^ epsilon+    -> Bool   -- ^ is closed+    -> V.Vector Point2i -- vector of points+approxPolyDP curve epsilon isClosed = unsafePerformIO $+    withArrayPtr (V.map toPoint curve) $ \curvePtr ->+    alloca $ \(pointsResPtrPtr ::Ptr (Ptr (Ptr C'Point2i))) ->+    alloca $ \(numPointsResPtr :: Ptr Int32) -> mask_ $ do+      [C.block| void {+        std::vector<cv::Point> points_res;+        cv::_InputArray curve = cv::_InputArray ($(Point2i * curvePtr), $(int32_t c'numPoints));+        cv::approxPolyDP+        (  curve+        ,  points_res+        ,  $(double c'epsilon)+        ,  $(bool c'isClosed)+        );++        *$(int32_t * numPointsResPtr) = points_res.size();++        cv::Point * * * pointsResPtrPtr = $(Point2i * * * pointsResPtrPtr);+        cv::Point * * pointsResPtr = new cv::Point * [points_res.size()];+        *pointsResPtrPtr = pointsResPtr;++        for (std::vector<cv::Point>::size_type i = 0; i < points_res.size(); i++) {+            cv::Point & ptAddress = points_res[i];+            cv::Point * newPt = new cv::Point(ptAddress.x, ptAddress.y);+            pointsResPtr[i] = newPt;+        }+      }|]++      numPoints <- fromIntegral <$> peek numPointsResPtr++      pointsResPtr <- peek pointsResPtrPtr+      (pointsResList :: [Point2i]) <- peekArray numPoints pointsResPtr >>= mapM (fromPtr . pure) --CHECK THIS+      let pointsRes :: V.Vector (Point2i)+          pointsRes = V.fromList pointsResList++      [CU.block| void {+        delete [] *$(Point2i * * * pointsResPtrPtr);+      } |]++      return pointsRes+  where+    c'numPoints = fromIntegral $ V.length curve+    c'isClosed  = fromBool isClosed+    c'epsilon   = realToFrac epsilon++arcLength+    :: (IsPoint2 point2 Int32)+    => V.Vector (point2 Int32)+    -> Bool -- ^ is closed+    -> CvExcept Double+arcLength curve isClosed = unsafeWrapException $+    withArrayPtr (V.map toPoint curve) $ \curvePtr ->+    alloca $ \c'resultPtr ->+    handleCvException (realToFrac <$> peek c'resultPtr) $+        [cvExcept|+            cv::_InputArray curve =+              cv::_InputArray ( $(Point2i * curvePtr)+                              , $(int32_t c'numPoints)+                              );+            *$(double * c'resultPtr) =+               cv::arcLength( curve+                              , $(bool c'isClosed)+                            );+        |]+    where+      c'isClosed = fromBool isClosed+      c'numPoints = fromIntegral $ V.length curve++minAreaRect :: (IsPoint2 point2 Int32)+            => V.Vector (point2 Int32) -> RotatedRect+minAreaRect points =+    unsafePerformIO $ fromPtr $+    withArrayPtr (V.map toPoint points) $ \pointsPtr ->+      [CU.exp|+        RotatedRect * {+          new RotatedRect(+            cv::minAreaRect(+                cv::_InputArray( $(Point2i * pointsPtr)+                               , $(int32_t c'numPoints))))+        }+      |]+  where+    c'numPoints = fromIntegral $ V.length points
+ src/OpenCV/ImgProc/Types.hs view
@@ -0,0 +1,30 @@+module OpenCV.ImgProc.Types+    ( InterpolationMethod(..)+    , BorderMode(..)+    ) where++import "this" OpenCV.Core.Types ( Scalar )++--------------------------------------------------------------------------------++data InterpolationMethod+   = InterNearest -- ^ Nearest neighbor interpolation.+   | InterLinear -- ^ Bilinear interpolation.+   | InterCubic -- ^ Bicubic interpolation.+   | InterArea+     -- ^ Resampling using pixel area relation. It may be a preferred method for+     -- image decimation, as it gives moire'-free results. But when the image is+     -- zoomed, it is similar to the 'InterNearest' method.+   | InterLanczos4 -- ^ Lanczos interpolation over 8x8 neighborhood+     deriving Show++-- TODO (RvD): Show instance+-- Needs a Show instance for Scalar+data BorderMode+   = BorderConstant Scalar -- ^ 1D example: @iiiiii|abcdefgh|iiiiiii@  with some specified @i@+   | BorderReplicate   -- ^ 1D example: @aaaaaa|abcdefgh|hhhhhhh@+   | BorderReflect     -- ^ 1D example: @fedcba|abcdefgh|hgfedcb@+   | BorderWrap        -- ^ 1D example: @cdefgh|abcdefgh|abcdefg@+   | BorderReflect101  -- ^ 1D example: @gfedcb|abcdefgh|gfedcba@+   | BorderTransparent -- ^ 1D example: @uvwxyz|absdefgh|ijklmno@+   | BorderIsolated    -- ^ do not look outside of ROI
+ src/OpenCV/Internal.hs view
@@ -0,0 +1,19 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal+  ( objFromPtr+  ) where++import "base" Control.Exception ( mask_ )+import "base" Foreign.Concurrent ( newForeignPtr )+import "base" Foreign.ForeignPtr ( ForeignPtr  )+import "base" Foreign.Ptr ( Ptr )++objFromPtr :: (ForeignPtr c -> hask) -> (Ptr c -> IO ()) -> IO (Ptr c) -> IO hask+objFromPtr haskCons finalizer mkObjPtr = mask_ $ do+    objPtr <- mkObjPtr+    haskCons <$> newForeignPtr objPtr (finalizer objPtr)
+ src/OpenCV/Internal/C/Inline.hs view
@@ -0,0 +1,130 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++-- | Interface between OpenCV and inline-c(pp) (Haskell)+module OpenCV.Internal.C.Inline ( openCvCtx ) where++import "base" Foreign.Ptr ( FunPtr )+import "base" Data.Monoid ( (<>) )+import qualified "containers" Data.Map as M+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Types  as C+import qualified "inline-c" Language.C.Inline.Context as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Internal.C.Types++-- | Context useful to work with the OpenCV library+--+-- Based on 'C.cppCtx', 'C.bsCtx' and 'C.vecCtx'.+--+-- 'C.ctxTypesTable': converts OpenCV basic types to their counterparts in+-- "OpenCV.Internal.C.Inline".+--+-- No 'C.ctxAntiQuoters'.+openCvCtx :: C.Context+openCvCtx = C.cppCtx <> C.bsCtx <> C.vecCtx <> ctx+  where+    ctx = mempty { C.ctxTypesTable = openCvTypesTable }++openCvTypesTable :: C.TypesTable+openCvTypesTable = M.fromList+  [ ( C.TypeName "bool"        , [t| C.CInt        |] )++  , ( C.TypeName "Exception"   , [t| C'CvCppException |] )++  , ( C.TypeName "Matx12f"     , [t| C'Matx12f     |] )+  , ( C.TypeName "Matx12d"     , [t| C'Matx12d     |] )+  , ( C.TypeName "Matx13f"     , [t| C'Matx13f     |] )+  , ( C.TypeName "Matx13d"     , [t| C'Matx13d     |] )+  , ( C.TypeName "Matx14f"     , [t| C'Matx14f     |] )+  , ( C.TypeName "Matx14d"     , [t| C'Matx14d     |] )+  , ( C.TypeName "Matx16f"     , [t| C'Matx16f     |] )+  , ( C.TypeName "Matx16d"     , [t| C'Matx16d     |] )+  , ( C.TypeName "Matx21f"     , [t| C'Matx21f     |] )+  , ( C.TypeName "Matx21d"     , [t| C'Matx21d     |] )+  , ( C.TypeName "Matx22f"     , [t| C'Matx22f     |] )+  , ( C.TypeName "Matx22d"     , [t| C'Matx22d     |] )+  , ( C.TypeName "Matx23f"     , [t| C'Matx23f     |] )+  , ( C.TypeName "Matx23d"     , [t| C'Matx23d     |] )+  , ( C.TypeName "Matx31f"     , [t| C'Matx31f     |] )+  , ( C.TypeName "Matx31d"     , [t| C'Matx31d     |] )+  , ( C.TypeName "Matx32f"     , [t| C'Matx32f     |] )+  , ( C.TypeName "Matx32d"     , [t| C'Matx32d     |] )+  , ( C.TypeName "Matx33f"     , [t| C'Matx33f     |] )+  , ( C.TypeName "Matx33d"     , [t| C'Matx33d     |] )+  , ( C.TypeName "Matx34f"     , [t| C'Matx34f     |] )+  , ( C.TypeName "Matx34d"     , [t| C'Matx34d     |] )+  , ( C.TypeName "Matx41f"     , [t| C'Matx41f     |] )+  , ( C.TypeName "Matx41d"     , [t| C'Matx41d     |] )+  , ( C.TypeName "Matx43f"     , [t| C'Matx43f     |] )+  , ( C.TypeName "Matx43d"     , [t| C'Matx43d     |] )+  , ( C.TypeName "Matx44f"     , [t| C'Matx44f     |] )+  , ( C.TypeName "Matx44d"     , [t| C'Matx44d     |] )+  , ( C.TypeName "Matx51f"     , [t| C'Matx51f     |] )+  , ( C.TypeName "Matx51d"     , [t| C'Matx51d     |] )+  , ( C.TypeName "Matx61f"     , [t| C'Matx61f     |] )+  , ( C.TypeName "Matx61d"     , [t| C'Matx61d     |] )+  , ( C.TypeName "Matx66f"     , [t| C'Matx66f     |] )+  , ( C.TypeName "Matx66d"     , [t| C'Matx66d     |] )++  , ( C.TypeName "Vec2i"       , [t| C'Vec2i       |] )+  , ( C.TypeName "Vec2f"       , [t| C'Vec2f       |] )+  , ( C.TypeName "Vec2d"       , [t| C'Vec2d       |] )+  , ( C.TypeName "Vec3i"       , [t| C'Vec3i       |] )+  , ( C.TypeName "Vec3f"       , [t| C'Vec3f       |] )+  , ( C.TypeName "Vec3d"       , [t| C'Vec3d       |] )+  , ( C.TypeName "Vec4i"       , [t| C'Vec4i       |] )+  , ( C.TypeName "Vec4f"       , [t| C'Vec4f       |] )+  , ( C.TypeName "Vec4d"       , [t| C'Vec4d       |] )++  , ( C.TypeName "Point2i"     , [t| C'Point2i     |] )+  , ( C.TypeName "Point2f"     , [t| C'Point2f     |] )+  , ( C.TypeName "Point2d"     , [t| C'Point2d     |] )+  , ( C.TypeName "Point3i"     , [t| C'Point3i     |] )+  , ( C.TypeName "Point3f"     , [t| C'Point3f     |] )+  , ( C.TypeName "Point3d"     , [t| C'Point3d     |] )++  , ( C.TypeName "Size2i"      , [t| C'Size2i      |] )+  , ( C.TypeName "Size2f"      , [t| C'Size2f      |] )+  , ( C.TypeName "Size2d"      , [t| C'Size2d      |] )++  , ( C.TypeName "Rect2i"      , [t| C'Rect2i      |] )+  , ( C.TypeName "Rect2f"      , [t| C'Rect2f      |] )+  , ( C.TypeName "Rect2d"      , [t| C'Rect2d      |] )++  , ( C.TypeName "RotatedRect" , [t| C'RotatedRect |] )+  , ( C.TypeName "TermCriteria", [t| C'TermCriteria|] )+  , ( C.TypeName "Scalar"      , [t| C'Scalar      |] )+  , ( C.TypeName "Mat"         , [t| C'Mat         |] )+  , ( C.TypeName "Range"       , [t| C'Range       |] )++  , ( C.TypeName "KeyPoint"    , [t| C'KeyPoint    |] )+  , ( C.TypeName "DMatch"      , [t| C'DMatch      |] )++--, ( C.TypeName "MSER"                  , [t| C'MSER                   |] )+  , ( C.TypeName "Ptr_ORB"               , [t| C'Ptr_ORB                |] )+--, ( C.TypeName "BRISK"                 , [t| C'BRISK                  |] )+--, ( C.TypeName "KAZE"                  , [t| C'KAZE                   |] )+--, ( C.TypeName "AKAZE"                 , [t| C'AKAZE                  |] )+  , ( C.TypeName "Ptr_SimpleBlobDetector", [t| C'Ptr_SimpleBlobDetector |] )++  , ( C.TypeName "DescriptorMatcher"     , [t| C'DescriptorMatcher      |] )+  , ( C.TypeName "BFMatcher"             , [t| C'BFMatcher              |] )+  , ( C.TypeName "FlannBasedMatcher"     , [t| C'FlannBasedMatcher      |] )++  , ( C.TypeName "Ptr_BackgroundSubtractorKNN" , [t| C'Ptr_BackgroundSubtractorKNN  |] )+  , ( C.TypeName "Ptr_BackgroundSubtractorMOG2", [t| C'Ptr_BackgroundSubtractorMOG2 |] )++  , ( C.TypeName "VideoCapture", [t| C'VideoCapture |] )+  , ( C.TypeName "VideoWriter" , [t| C'VideoWriter  |] )++  , ( C.TypeName "CascadeClassifier", [t| C'CascadeClassifier |] )++  , ( C.TypeName "MouseCallback"   , [t| FunPtr C'MouseCallback    |] )+  , ( C.TypeName "TrackbarCallback", [t| FunPtr C'TrackbarCallback |] )+  ]
+ src/OpenCV/Internal/C/PlacementNew.hs view
@@ -0,0 +1,34 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.C.PlacementNew ( PlacementNew(..) ) where++import "base" Foreign.Ptr ( Ptr )++--------------------------------------------------------------------------------++-- | Copy source to destination using C++'s placement new feature+class PlacementNew a where+    -- | Copy source to destination using C++'s placement new feature+    --+    -- This method is intended for types that are proxies for actual+    -- types in C++.+    --+    -- > new(dst) CType(*src)+    --+    -- The copy should be performed by constructing a new object in+    -- the memory pointed to by @dst@. The new object is initialised+    -- using the value of @src@. This design allow underlying+    -- structures to be shared depending on the implementation of+    -- @CType@.+    placementNew+        :: Ptr a -- ^ Source+        -> Ptr a -- ^ Destination+        -> IO ()++    placementDelete+        :: Ptr a+        -> IO ()
+ src/OpenCV/Internal/C/PlacementNew/TH.hs view
@@ -0,0 +1,40 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance ) where++import "base" Data.Monoid ( (<>) )+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Internal.C.PlacementNew ( PlacementNew (..) )++mkPlacementNewInstance :: Name -> DecsQ+mkPlacementNewInstance name =+    [d|+      instance PlacementNew $(conT (mkName ctypeName)) where+          placementNew    = $(placementNewQ)+          placementDelete = $(placementDeleteQ)+    |]+  where+    typeName = nameBase name+    ctypeName = "C'"  <> typeName++    placementNewQ = do+      src <- newName "src"+      dst <- newName "dst"+      lamE [varP src, varP dst] $+        quoteExp C.exp $+          "void { new($(" <> typeName <> " * " <> nameBase dst <> ")) cv::" <> typeName <>+                   "(*$(" <> typeName <> " * " <> nameBase src <> ")) }"++    placementDeleteQ = do+      ptr <- newName "ptr"+      lamE [varP ptr] $+        quoteExp C.exp $+          "void { $(" <> typeName <> " * " <> nameBase ptr <> ")->~" <> typeName <> "() }"
+ src/OpenCV/Internal/C/Types.hs view
@@ -0,0 +1,230 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.C.Types where++import "base" Foreign.C.Types+import "base" Foreign.Ptr ( Ptr, nullPtr )+import "base" Data.Int ( Int32 )+import "base" GHC.TypeLits+import "this" OpenCV.Internal.Core.Types.Constants+import "this" OpenCV.Internal.Mutable++--------------------------------------------------------------------------------++data C'Matx  (dimR :: Nat) (dimC :: Nat) (depth :: *)+data C'Vec   (dim :: Nat) (depth :: *)+data C'Point (dim :: Nat) (depth :: *)+data C'Size  (depth :: *)+data C'Rect  (depth :: *)++type C'Matx12f = C'Matx 1 2 CFloat+type C'Matx12d = C'Matx 1 2 CDouble+type C'Matx13f = C'Matx 1 3 CFloat+type C'Matx13d = C'Matx 1 3 CDouble+type C'Matx14f = C'Matx 1 4 CFloat+type C'Matx14d = C'Matx 1 4 CDouble+type C'Matx16f = C'Matx 1 6 CFloat+type C'Matx16d = C'Matx 1 6 CDouble+type C'Matx21f = C'Matx 2 1 CFloat+type C'Matx21d = C'Matx 2 1 CDouble+type C'Matx22f = C'Matx 2 2 CFloat+type C'Matx22d = C'Matx 2 2 CDouble+type C'Matx23f = C'Matx 2 3 CFloat+type C'Matx23d = C'Matx 2 3 CDouble+type C'Matx31f = C'Matx 3 1 CFloat+type C'Matx31d = C'Matx 3 1 CDouble+type C'Matx32f = C'Matx 3 2 CFloat+type C'Matx32d = C'Matx 3 2 CDouble+type C'Matx33f = C'Matx 3 3 CFloat+type C'Matx33d = C'Matx 3 3 CDouble+type C'Matx34f = C'Matx 3 4 CFloat+type C'Matx34d = C'Matx 3 4 CDouble+type C'Matx41f = C'Matx 4 1 CFloat+type C'Matx41d = C'Matx 4 1 CDouble+type C'Matx43f = C'Matx 4 3 CFloat+type C'Matx43d = C'Matx 4 3 CDouble+type C'Matx44f = C'Matx 4 4 CFloat+type C'Matx44d = C'Matx 4 4 CDouble+type C'Matx51f = C'Matx 5 1 CFloat+type C'Matx51d = C'Matx 5 1 CDouble+type C'Matx61f = C'Matx 6 1 CFloat+type C'Matx61d = C'Matx 6 1 CDouble+type C'Matx66f = C'Matx 6 6 CFloat+type C'Matx66d = C'Matx 6 6 CDouble++type C'Vec2i = C'Vec 2 Int32+type C'Vec2f = C'Vec 2 CFloat+type C'Vec2d = C'Vec 2 CDouble++type C'Vec3i = C'Vec 3 Int32+type C'Vec3f = C'Vec 3 CFloat+type C'Vec3d = C'Vec 3 CDouble++type C'Vec4i = C'Vec 4 Int32+type C'Vec4f = C'Vec 4 CFloat+type C'Vec4d = C'Vec 4 CDouble++type C'Point2i = C'Point 2 Int32+type C'Point2f = C'Point 2 CFloat+type C'Point2d = C'Point 2 CDouble++type C'Point3i = C'Point 3 Int32+type C'Point3f = C'Point 3 CFloat+type C'Point3d = C'Point 3 CDouble++type C'Size2i = C'Size Int32+type C'Size2f = C'Size CFloat+type C'Size2d = C'Size CDouble++type C'Rect2i = C'Rect Int32+type C'Rect2f = C'Rect CFloat+type C'Rect2d = C'Rect CDouble++-- | Haskell representation of an OpenCV exception+data C'CvCppException+-- | Haskell representation of an OpenCV @cv::RotatedRect@ object+data C'RotatedRect+-- | Haskell representation of an OpenCV @cv::TermCriteria@ object+data C'TermCriteria+-- | Haskell representation of an OpenCV @cv::Range@ object+data C'Range+-- | Haskell representation of an OpenCV @cv::Scalar_\<double>@ object+data C'Scalar+-- | Haskell representation of an OpenCV @cv::Mat@ object+data C'Mat++-- | Haskell representation of an OpenCV @cv::Keypoint@ object+data C'KeyPoint+-- | Haskell representation of an OpenCV @cv::DMatch@ object+data C'DMatch++-- -- | Haskell representation of an OpenCV @cv::MSER@ object+-- data C'MSER+-- | Haskell representation of an OpenCV @cv::Ptr<cv::ORB>@ object+data C'Ptr_ORB+-- -- | Haskell representation of an OpenCV @cv::BRISK@ object+-- data C'BRISK+-- -- | Haskell representation of an OpenCV @cv::KAZE@ object+-- data C'KAZE+-- -- | Haskell representation of an OpenCV @cv::AKAZE@ object+-- data C'AKAZE+-- | Haskell representation of an OpenCV @cv::Ptr<cv::SimpleBlobDetector>@ object+data C'Ptr_SimpleBlobDetector++-- | Haskell representation of an OpenCV @cv::DescriptorMatcher@ object+data C'DescriptorMatcher+-- | Haskell representation of an OpenCV @cv::BFMatcher@ object+data C'BFMatcher+-- | Haskell representation of an OpenCV @cv::FlannBasedMatcher@ object+data C'FlannBasedMatcher++-- | Haskell representation of an OpenCV @cv::Ptr<cv::BackgroundSubtractorMOG2>@ object+data C'Ptr_BackgroundSubtractorKNN+-- | Haskell representation of an OpenCV @cv::Ptr<cv::BackgroundSubtractorKNN>@ object+data C'Ptr_BackgroundSubtractorMOG2+++-- | Haskell representation of an OpenCV @cv::VideoCapture@ object+data C'VideoCapture++-- | Haskell representation of an OpenCV @cv::VideoWriter@ object+data C'VideoWriter++-- | Haskell representation of an OpenCV @cv::CascadeClassifier@ object+data C'CascadeClassifier++-- | Callback function for mouse events+type C'MouseCallback+   =  Int32 -- ^ One of the @cv::MouseEvenTypes@ constants.+   -> Int32 -- ^ The x-coordinate of the mouse event.+   -> Int32 -- ^ The y-coordinate of the mouse event.+   -> Int32 -- ^ One of the @cv::MouseEventFlags@ constants.+   -> Ptr () -- ^ Optional pointer to user data.+   -> IO ()++-- | Callback function for trackbars+type C'TrackbarCallback+   =  Int32 -- ^ Current position of the specified trackbar.+   -> Ptr () -- ^ Optional pointer to user data.+   -> IO ()+++--------------------------------------------------------------------------------++-- | Information about the storage requirements of values in C+--+-- This class assumes that the type @a@ is merely a symbol that corresponds with+-- a type in C.+class CSizeOf a where+    -- | Computes the storage requirements (in bytes) of values of+    -- type @a@ in C.+    cSizeOf :: proxy a -> Int++instance CSizeOf C'Point2i where cSizeOf _proxy = c'sizeof_Point2i+instance CSizeOf C'Point2f where cSizeOf _proxy = c'sizeof_Point2f+instance CSizeOf C'Point2d where cSizeOf _proxy = c'sizeof_Point2d+instance CSizeOf C'Point3i where cSizeOf _proxy = c'sizeof_Point3i+instance CSizeOf C'Point3f where cSizeOf _proxy = c'sizeof_Point3f+instance CSizeOf C'Point3d where cSizeOf _proxy = c'sizeof_Point3d+instance CSizeOf C'Size2i  where cSizeOf _proxy = c'sizeof_Size2i+instance CSizeOf C'Size2f  where cSizeOf _proxy = c'sizeof_Size2f+instance CSizeOf C'Scalar  where cSizeOf _proxy = c'sizeof_Scalar+instance CSizeOf C'Range   where cSizeOf _proxy = c'sizeof_Range+instance CSizeOf C'Mat     where cSizeOf _proxy = c'sizeof_Mat++-- | Equivalent type in C+--+-- Actually a proxy type in Haskell that stands for the equivalent type in C.+type family C (a :: *) :: *++type instance C (Maybe a) = C a++-- | Mutable types have the same C equivalent as their unmutable variants.+type instance C (Mut a s) = C a++--------------------------------------------------------------------------------++-- | Perform an IO action with a pointer to the C equivalent of a value+class WithPtr a where+    -- | Perform an action with a temporary pointer to the underlying+    -- representation of @a@+    --+    -- The pointer is not guaranteed to be usuable outside the scope of this+    -- function. The same warnings apply as for 'withForeignPtr'.+    withPtr :: a -> (Ptr (C a) -> IO b) -> IO b++-- | 'Nothing' is represented as a 'nullPtr'.+instance (WithPtr a) => WithPtr (Maybe a) where+    withPtr Nothing    f = f nullPtr+    withPtr (Just obj) f = withPtr obj f++-- | Mutable types use the same underlying representation as unmutable types.+instance (WithPtr a) => WithPtr (Mut a s) where+    withPtr = withPtr . unMut++--------------------------------------------------------------------------------++-- | Types of which a value can be constructed from a pointer to the C+-- equivalent of that value+--+-- Used to wrap values created in C.+class FromPtr a where+    fromPtr :: IO (Ptr (C a)) -> IO a++--------------------------------------------------------------------------------++toCFloat :: Float -> CFloat+toCFloat = realToFrac++fromCFloat :: CFloat -> Float+fromCFloat = realToFrac++toCDouble :: Double -> CDouble+toCDouble = realToFrac++fromCDouble :: CDouble -> Double+fromCDouble = realToFrac
+ src/OpenCV/Internal/Calib3d/Constants.hsc view
@@ -0,0 +1,18 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Calib3d.Constants where++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/calib3d.hpp"++#include "namespace.hpp"++#num CV_FM_7POINT+#num CV_FM_8POINT+#num CV_FM_RANSAC+#num CV_FM_LMEDS
+ src/OpenCV/Internal/Core/ArrayOps.hsc view
@@ -0,0 +1,94 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.ArrayOps+    ( CmpType(..)+    , marshalCmpType+    , NormType(..)+    , NormAbsRel(..)+    , marshalNormType+    )+    where++import "base" Data.Bits ( (.|.) )+import "base" Data.Int++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/core.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++-- | Comparison type+data CmpType+   = Cmp_Eq+   | Cmp_Gt+   | Cmp_Ge+   | Cmp_Lt+   | Cmp_Le+   | Cmp_Ne+     deriving (Show, Eq)++#num CMP_EQ+#num CMP_GT+#num CMP_GE+#num CMP_LT+#num CMP_LE+#num CMP_NE++marshalCmpType :: CmpType -> Int32+marshalCmpType cmpOp =+    case cmpOp of+      Cmp_Eq -> c'CMP_EQ+      Cmp_Gt -> c'CMP_GT+      Cmp_Ge -> c'CMP_GE+      Cmp_Lt -> c'CMP_LT+      Cmp_Le -> c'CMP_LE+      Cmp_Ne -> c'CMP_NE++-- | Normalization type+data NormType+   = Norm_Inf+   | Norm_L1+   | Norm_L2+   | Norm_L2SQR+   | Norm_Hamming+   | Norm_Hamming2+   | Norm_MinMax+     deriving (Show, Eq)++data NormAbsRel+   = NormRelative+   | NormAbsolute+     deriving (Show, Eq)++#num NORM_INF+#num NORM_L1+#num NORM_L2+#num NORM_L2SQR+#num NORM_HAMMING+#num NORM_HAMMING2+#num NORM_MINMAX++#num NORM_RELATIVE++marshalNormType :: NormAbsRel -> NormType -> Int32+marshalNormType absRel normType =+    case absRel of+      NormRelative -> c'normType .|. c'NORM_RELATIVE+      NormAbsolute -> c'normType+  where+    c'normType = case normType of+        Norm_Inf      -> c'NORM_INF+        Norm_L1       -> c'NORM_L1+        Norm_L2       -> c'NORM_L2+        Norm_L2SQR    -> c'NORM_L2SQR+        Norm_Hamming  -> c'NORM_HAMMING+        Norm_Hamming2 -> c'NORM_HAMMING2+        Norm_MinMax   -> c'NORM_MINMAX
+ src/OpenCV/Internal/Core/Types.cpp view
@@ -0,0 +1,112 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+Scalar * inline_c_OpenCV_Internal_Core_Types_0_1b24a839693d320671a79485fe080fbb7355a4b6(double x_inline_c_0, double y_inline_c_1, double z_inline_c_2, double w_inline_c_3) {+return ( new cv::Scalar( x_inline_c_0+                                     , y_inline_c_1+                                     , z_inline_c_2+                                     , w_inline_c_3+                                     )+                     );+}++}++extern "C" {+RotatedRect * inline_c_OpenCV_Internal_Core_Types_1_9ea56c49f81d2b10cbc82e23b1d147a494702aa2(Point2f * centerPtr_inline_c_0, Size2f * sizePtr_inline_c_1, float angle_inline_c_2) {+return (+          new cv::RotatedRect( *centerPtr_inline_c_0+                             , *sizePtr_inline_c_1+                             , angle_inline_c_2+                             )+      );+}++}++extern "C" {+TermCriteria * inline_c_OpenCV_Internal_Core_Types_2_ec54942df5510b406f829c77b86a8160c5e005f2(int32_t ctype_27_inline_c_0, int32_t cmaxCount_27_inline_c_1, double cepsilon_27_inline_c_2) {+return (+      new cv::TermCriteria( ctype_27_inline_c_0+                          , cmaxCount_27_inline_c_1+                          , cepsilon_27_inline_c_2+                          )+    );+}++}++extern "C" {+Range * inline_c_OpenCV_Internal_Core_Types_3_c61bc1a3ba5434a1d82b055b88065a109674fe34(int32_t start_inline_c_0, int32_t end_inline_c_1) {+return ( new cv::Range( start_inline_c_0, end_inline_c_1) );+}++}++extern "C" {+Range * inline_c_OpenCV_Internal_Core_Types_4_82b2e212e109153a3890aefd82f32ae7fbac75bc() {++      cv::Range a = cv::Range::all();+      return new cv::Range(a.start, a.end);+    +}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_5_2a14b0f4fdf4947ed9c1c4c5b5fbb3ac023fd3e9(Scalar * sPtr_inline_c_0, double * xPtr_inline_c_1, double * yPtr_inline_c_2, double * zPtr_inline_c_3, double * wPtr_inline_c_4) {++          const Scalar & s = *sPtr_inline_c_0;+          *xPtr_inline_c_1 = s[0];+          *yPtr_inline_c_2 = s[1];+          *zPtr_inline_c_3 = s[2];+          *wPtr_inline_c_4 = s[3];+        +}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_6_efb01268b38779dc6977b46241f8d4bb29b2e499(Scalar * dst_inline_c_0, Scalar * src_inline_c_1) {+ new(dst_inline_c_0) cv::Scalar(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_7_cdde9ee703374d51bfb7f2dd78ebf22ab49b3cf7(Scalar * ptr_inline_c_0) {+ ptr_inline_c_0->~Scalar() ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_8_76e484cb7925a501e0119c9d1809f00bec5663a7(Range * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_9_2679f6a9c87ab8d51e9b3244c98b481d5e4bd49c(TermCriteria * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_10_1d7454cf4b3a0d88671f5b2941ad3ac0c74aeefb(RotatedRect * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_11_b56573ae17f3058ee640bf072b7a5c7b25cfe766(Scalar * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/Internal/Core/Types.hs view
@@ -0,0 +1,306 @@+{-# language CPP #-}+{-# language MultiParamTypeClasses #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types+    ( -- * Scalar+      Scalar(..)+    , newScalar+    , ToScalar(..), FromScalar(..)+      -- * RotatedRect+    , RotatedRect(..)+    , newRotatedRect+      -- * TermCriteria+    , TermCriteria(..)+    , newTermCriteria+      -- * Range+    , Range(..)+    , newRange+    , newWholeRange+      -- * Polygons+    , withPolygons+    , withArrayPtr+    ) where++import "base" Control.Exception ( bracket_ )+import "base" Data.Bits ( (.|.) )+import "base" Data.Functor ( ($>) )+import "base" Data.Int ( Int32 )+import "base" Data.Proxy ( Proxy(..) )+import "base" Foreign.C.Types+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Marshal.Alloc ( alloca, allocaBytes )+import "base" Foreign.Marshal.Array ( allocaArray )+import "base" Foreign.Ptr ( Ptr, plusPtr )+import "base" Foreign.Storable ( sizeOf, peek, poke )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "linear" Linear.V4 ( V4(..) )+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Core.Types.Size+import "this" OpenCV.Internal+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.Core.Types.Constants+import "this" OpenCV.Internal.C.PlacementNew+import "this" OpenCV.Internal.C.PlacementNew.TH+import "this" OpenCV.Internal.C.Types+import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------+-- Types+--------------------------------------------------------------------------------++-- | A 4-element vector with 64 bit floating point elements+--+-- The type 'Scalar' is widely used in OpenCV to pass pixel values.+--+-- <http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#scalar OpenCV Sphinx doc>+newtype Scalar = Scalar {unScalar :: ForeignPtr (C Scalar)}++-- | Rotated (i.e. not up-right) rectangles on a plane+--+-- Each rectangle is specified by the center point (mass center), length of each+-- side (represented by 'Size2f') and the rotation angle in degrees.+--+-- <http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#rotatedrect OpenCV Sphinx doc>+newtype RotatedRect = RotatedRect {unRotatedRect :: ForeignPtr (C RotatedRect)}++-- | Termination criteria for iterative algorithms+--+-- <http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#termcriteria OpenCV Sphinx doc>+newtype TermCriteria = TermCriteria {unTermCriteria :: ForeignPtr (C TermCriteria)}++-- | A continuous subsequence (slice) of a sequence+--+-- The type is used to specify a row or a column span in a matrix (`Mat`) and+-- for many other purposes. @'mkRange' a b@ is basically the same as @a:b@ in+-- Matlab or @a..b@ in Python. As in Python, start is an inclusive left boundary+-- of the range and end is an exclusive right boundary of the range. Such a+-- half-opened interval is usually denoted as @[start, end)@.+--+-- <http://docs.opencv.org/3.0-last-rst/modules/core/doc/basic_structures.html#range OpenCV Sphinx doc>+newtype Range = Range {unRange :: ForeignPtr (C Range)}+++--------------------------------------------------------------------------------+-- Conversions+--------------------------------------------------------------------------------++class ToScalar  a where toScalar  :: a -> Scalar++instance ToScalar  Scalar  where toScalar  = id++instance ToScalar  (V4 CDouble) where toScalar  = unsafePerformIO . newScalar++instance ToScalar  (V4 Double ) where toScalar  = toScalar  . fmap (realToFrac :: Double -> CDouble)++class FromScalar  a where fromScalar  :: Scalar  -> a++instance FromScalar  Scalar  where fromScalar  = id++instance FromScalar (V4 CDouble) where+    fromScalar s = unsafePerformIO $+      alloca $ \xPtr ->+      alloca $ \yPtr ->+      alloca $ \zPtr ->+      alloca $ \wPtr ->+      withPtr s $ \sPtr -> do+        [CU.block| void {+          const Scalar & s = *$(Scalar * sPtr);+          *$(double * xPtr) = s[0];+          *$(double * yPtr) = s[1];+          *$(double * zPtr) = s[2];+          *$(double * wPtr) = s[3];+        }|]+        V4 <$> peek xPtr+           <*> peek yPtr+           <*> peek zPtr+           <*> peek wPtr++instance FromScalar (V4 Double) where fromScalar = fmap (realToFrac :: CDouble -> Double) . fromScalar++--------------------------------------------------------------------------------+-- Constructing new values+--------------------------------------------------------------------------------++newScalar :: V4 CDouble -> IO Scalar+newScalar (V4 x y z w) = fromPtr $+    [CU.exp|Scalar * { new cv::Scalar( $(double x)+                                     , $(double y)+                                     , $(double z)+                                     , $(double w)+                                     )+                     }|]++newRotatedRect+    :: ( IsPoint2 point2 CFloat+       , IsSize   size   CFloat+       )+    => point2 CFloat -- ^ Rectangle mass center+    -> size   CFloat -- ^ Width and height of the rectangle+    -> CFloat+       -- ^ The rotation angle (in degrees). When the angle is 0, 90,+       -- 180, 270 etc., the rectangle becomes an up-right rectangle.+    -> IO RotatedRect+newRotatedRect center size angle = fromPtr $+    withPtr (toPoint center) $ \centerPtr ->+    withPtr (toSize  size)   $ \sizePtr   ->+      [CU.exp| RotatedRect * {+          new cv::RotatedRect( *$(Point2f * centerPtr)+                             , *$(Size2f * sizePtr)+                             , $(float angle)+                             )+      }|]++newTermCriteria+    :: Maybe Int    -- ^ Optionally the maximum number of iterations/elements.+    -> Maybe Double -- ^ Optionally the desired accuracy.+    -> IO TermCriteria+newTermCriteria mbMaxCount mbEpsilon = fromPtr $+    [CU.exp|TermCriteria * {+      new cv::TermCriteria( $(int32_t c'type    )+                          , $(int32_t c'maxCount)+                          , $(double  c'epsilon )+                          )+    }|]+  where+    c'type =   maybe 0 (const c'TERMCRITERIA_COUNT) mbMaxCount+           .|. maybe 0 (const c'TERMCRITERIA_EPS  ) mbEpsilon+    c'maxCount = maybe 0 fromIntegral mbMaxCount+    c'epsilon  = maybe 0 realToFrac   mbEpsilon++newRange+    :: Int32 -- ^ Inclusive start+    -> Int32 -- ^ Exlusive end+    -> IO Range+newRange start end = fromPtr $+    [CU.exp|Range * { new cv::Range( $(int32_t start), $(int32_t end)) }|]++-- | Special 'Range' value which means "the whole sequence" or "the whole range"+newWholeRange :: IO Range+newWholeRange = fromPtr $+    [CU.block|Range * {+      cv::Range a = cv::Range::all();+      return new cv::Range(a.start, a.end);+    }|]+++--------------------------------------------------------------------------------+-- Polygons+--------------------------------------------------------------------------------++withPolygons+    :: forall a point2+     . (IsPoint2 point2 Int32)+    => V.Vector (V.Vector (point2 Int32))+    -> (Ptr (Ptr (C Point2i)) -> IO a)+    -> IO a+withPolygons polygons act =+    allocaArray (V.length polygons) $ \polygonsPtr -> do+      let go :: Ptr (Ptr (C Point2i)) -> Int -> IO a+          go !acc !ix+            | ix < V.length polygons =+                let pts = V.map toPoint $ V.unsafeIndex polygons ix+                in withArrayPtr pts $ \ptsPtr -> do+                     poke acc ptsPtr+                     go (acc `plusPtr` sizeOf (undefined :: Ptr (Ptr (C Point2i)))) (ix + 1)+            | otherwise = act polygonsPtr+      go polygonsPtr 0++-- | Perform an action with a temporary pointer to an array of values+--+-- The input values are placed consecutively in memory using the 'PlacementNew'+-- mechanism.+--+-- This function is intended for types which are not managed by the Haskell+-- runtime, but by a foreign system (such as C).+--+-- The pointer is not guaranteed to be usuable outside the scope of this+-- function. The same warnings apply as for 'withForeignPtr'.+withArrayPtr+    :: forall a b+     . (WithPtr a, CSizeOf (C a), PlacementNew (C a))+    => V.Vector a+    -> (Ptr (C a) -> IO b)+    -> IO b+withArrayPtr arr act =+    allocaBytes arraySize $ \arrPtr ->+      bracket_+        (V.foldM'_ copyNext arrPtr arr)+        (deconstructArray arrPtr )+        (act arrPtr)+  where+    elemSize = cSizeOf (Proxy :: Proxy (C a))+    arraySize = elemSize * V.length arr++    copyNext :: Ptr (C a) -> a -> IO (Ptr (C a))+    copyNext !ptr obj = copyObj ptr obj $> plusPtr ptr elemSize++    copyObj :: Ptr (C a) -> a -> IO ()+    copyObj dstPtr src =+        withPtr src $ \srcPtr ->+          placementNew srcPtr dstPtr++    deconstructArray :: Ptr (C a) -> IO ()+    deconstructArray !begin = deconstructNext begin+      where+        deconstructNext !ptr+            | ptr == end = pure ()+            | otherwise = do placementDelete ptr+                             deconstructNext $ ptr `plusPtr` elemSize++        end :: Ptr (C a)+        end = begin `plusPtr` arraySize++--------------------------------------------------------------------------------++type instance C Scalar       = C'Scalar+type instance C RotatedRect  = C'RotatedRect+type instance C TermCriteria = C'TermCriteria+type instance C Range        = C'Range++--------------------------------------------------------------------------------++instance WithPtr Scalar       where withPtr = withForeignPtr . unScalar+instance WithPtr RotatedRect  where withPtr = withForeignPtr . unRotatedRect+instance WithPtr TermCriteria where withPtr = withForeignPtr . unTermCriteria+instance WithPtr Range        where withPtr = withForeignPtr . unRange++--------------------------------------------------------------------------------++mkPlacementNewInstance ''Scalar++--------------------------------------------------------------------------------++instance FromPtr Scalar where+    fromPtr = objFromPtr Scalar $ \ptr ->+                [CU.exp| void { delete $(Scalar * ptr) }|]++instance FromPtr RotatedRect where+    fromPtr = objFromPtr RotatedRect $ \ptr ->+                [CU.exp| void { delete $(RotatedRect * ptr) }|]++instance FromPtr TermCriteria where+    fromPtr = objFromPtr TermCriteria $ \ptr ->+                [CU.exp| void { delete $(TermCriteria * ptr) }|]++instance FromPtr Range where+    fromPtr = objFromPtr Range $ \ptr ->+                [CU.exp| void { delete $(Range * ptr) }|]
+ src/OpenCV/Internal/Core/Types/Constants.hsc view
@@ -0,0 +1,35 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Constants where++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "termcriteria.hpp"++#include "namespace.hpp"+#include "hsc_macros.hpp"++#sizeof Point2i+#sizeof Point2f+#sizeof Point2d++#sizeof Point3i+#sizeof Point3f+#sizeof Point3d++#sizeof Size2i+#sizeof Size2f++#sizeof Scalar+#sizeof Range+#sizeof KeyPoint+#sizeof DMatch++#sizeof Mat++#num TERMCRITERIA_COUNT+#num TERMCRITERIA_EPS
+ src/OpenCV/Internal/Core/Types/Mat.cpp view
@@ -0,0 +1,86 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_0_8768adeedcae20c11dd5e602ef044df2ee6a09fd() {+return ( new Mat() );+}++}++extern "C" {+Exception * inline_c_OpenCV_Internal_Core_Types_Mat_1_5f31dc1188e4b3f4d0035cc5ace1eb9bef10a6b6(Mat * dstPtr_inline_c_0, int32_t cndims_27_inline_c_1, int32_t * shapePtr_inline_c_2, int32_t ctype_27_inline_c_3, Scalar * scalarPtr_inline_c_4) {++  try+  {   +          *dstPtr_inline_c_0 =+            Mat( cndims_27_inline_c_1+               , shapePtr_inline_c_2+               , ctype_27_inline_c_3+               , *scalarPtr_inline_c_4+               );+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_Mat_2_00f93178ab847fcc332d169992583a5da893c0b0(Mat * matPtr_inline_c_0, int32_t *const dimsPtr_inline_c_1, size_t **const stepPtr2_inline_c_2, uint8_t **const dataPtr2_inline_c_3) {++        const Mat * const matPtr = matPtr_inline_c_0;+        *dimsPtr_inline_c_1 = matPtr->dims;+        *stepPtr2_inline_c_2 = matPtr->step.p;+        *dataPtr2_inline_c_3 = matPtr->data;+      +}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_3_a16c0b433745dc68200cf06194a285990fbd7c64(Mat * matPtr_inline_c_0) {+return ( new Mat(matPtr_inline_c_0->clone()) );+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_Mat_4_52c637925cd5824494e212b21b7b4da6b5a7303d(Mat * matPtr_inline_c_0, int32_t *const flagsPtr_inline_c_1, int32_t *const dimsPtr_inline_c_2, int32_t **const sizePtr_inline_c_3) {++        const Mat * const matPtr = matPtr_inline_c_0;+        *flagsPtr_inline_c_1 = matPtr->flags;+        *dimsPtr_inline_c_2 = matPtr->dims;+        *sizePtr_inline_c_3 = matPtr->size.p;+      +}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_Mat_5_d5614b8cb3656a53b9c01ee01b93e309410817f7(Mat * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_Mat_6_042465638c29b7efc44f066175472fe3d06dfba9(Mat * dst_inline_c_0, Mat * src_inline_c_1) {+ new(dst_inline_c_0) cv::Mat(*src_inline_c_1) ;+}++}++extern "C" {+void inline_c_OpenCV_Internal_Core_Types_Mat_7_f5866e170cd14346d5a568ea79d8d4c825431619(Mat * ptr_inline_c_0) {+ ptr_inline_c_0->~Mat() ;+}++}
+ src/OpenCV/Internal/Core/Types/Mat.hs view
@@ -0,0 +1,574 @@+{-# language CPP #-}+{-# LANGUAGE RankNTypes #-}+{-# language QuasiQuotes #-}+{-# language ConstraintKinds #-}+{-# language TemplateHaskell #-}+{-# language UndecidableInstances #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++{-# options_ghc -fno-warn-orphans #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Mat+    ( -- * Matrix+      Mat(..)++    , typeCheckMat+    , relaxMat+    , coerceMat+    , unsafeCoerceMat++    , keepMatAliveDuring+    , newEmptyMat+    , newMat+    , withMatData+    , matElemAddress+    , mkMat+    , cloneMat++      -- * Mutable matrix+    , typeCheckMatM+    , relaxMatM+    , coerceMatM+    , unsafeCoerceMatM++    , mkMatM+    , createMat+    , withMatM+    , cloneMatM++      -- * Meta information+    , MatInfo(..)+    , matInfo++    , dimPositions++    , Depth(..)+    , marshalDepth+    , unmarshalDepth+    , marshalFlags+    , unmarshalFlags++    , ShapeT+    , ChannelsT+    , DepthT+    , StaticDepthT++    , ToShape(toShape)+    , ToShapeDS(toShapeDS)+    , ToChannels, toChannels+    , ToChannelsDS, toChannelsDS+    , ToDepth(toDepth)+    , ToDepthDS(toDepthDS)+    ) where++import "base" Control.Monad.ST ( ST )+import "base" Data.Int+import "base" Data.Maybe+import "base" Data.Monoid ( (<>) )+import "base" Data.Proxy+import "base" Data.Word+import "base" Foreign.C.Types+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr, touchForeignPtr )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Array ( allocaArray, peekArray )+import "base" Foreign.Ptr ( Ptr, plusPtr )+import "base" Foreign.Storable ( Storable(..), peek )+import "base" GHC.TypeLits+import "base" System.IO.Unsafe ( unsafePerformIO )+import "base" Unsafe.Coerce ( unsafeCoerce )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState, unsafePrimToPrim )+import "this" OpenCV.Internal+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.C.PlacementNew.TH+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat.Depth+import "this" OpenCV.Internal.Core.Types.Mat.Marshal+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.Mutable+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V+import qualified "vector" Data.Vector.Generic as VG++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------+-- Matrix+--------------------------------------------------------------------------------++newtype Mat (shape    :: DS [DS Nat])+            (channels :: DS Nat)+            (depth    :: DS *)+      = Mat {unMat :: ForeignPtr (C (Mat shape channels depth))}++type instance C (Mat shape channels depth) = C'Mat++type instance Mutable (Mat shape channels depth) = Mut (Mat shape channels depth)++instance WithPtr (Mat shape channels depth) where+    withPtr = withForeignPtr . unMat++instance FromPtr (Mat shape channels depth) where+    fromPtr = objFromPtr Mat $ \ptr ->+                [CU.exp| void { delete $(Mat * ptr) }|]++instance FreezeThaw (Mat shape channels depth) where+    freeze = cloneMatM . unMut+    thaw = fmap Mut . cloneMatM++    unsafeFreeze = pure . unMut+    unsafeThaw = pure . Mut++{- | Tests whether a 'Mat' is deserving of its type level attributes++Checks if the properties encoded in the type of a 'Mat' correspond to+the value level representation. For each property that does not hold+this function will produce an error message. If everything checks out+it will produce an empty list.++The following properties are checked:++ * Dimensionality+ * Size of each dimension+ * Number of channels+ * Depth (data type of elements)++If a property is explicitly encoded as statically unknown ('D'ynamic)+it will not be checked.+-}+typeCheckMat+    :: forall shape channels depth+     . ( ToShapeDS    (Proxy shape)+       , ToChannelsDS (Proxy channels)+       , ToDepthDS    (Proxy depth)+       )+    => Mat shape channels depth -- ^ The matrix to be checked.+    -> [CoerceMatError] -- ^ Error messages.+typeCheckMat mat =+       fromMaybe [] (checkShape <$> dsToMaybe dsExpectedShape)+    <> maybeToList (dsToMaybe dsExpectedNumChannels >>= checkNumChannels)+    <> maybeToList (dsToMaybe dsExpectedDepth >>= checkDepth)+  where+    mi = matInfo mat++    dsExpectedShape :: DS [DS Int32]+    dsExpectedShape = toShapeDS (Proxy :: Proxy shape)++    dsExpectedNumChannels :: DS Int32+    dsExpectedNumChannels = toChannelsDS (Proxy :: Proxy channels)++    dsExpectedDepth :: DS Depth+    dsExpectedDepth = toDepthDS (Proxy :: Proxy depth)++    checkShape :: [DS Int32] -> [CoerceMatError]+    checkShape expectedShape = maybe checkSizes (:[]) dimCheck+      where+        dimCheck :: Maybe CoerceMatError+        dimCheck | expectedDim == actualDim = Nothing+                 | otherwise = Just $ ShapeError $ ExpectationError expectedDim actualDim+          where+            expectedDim = length expectedShape+            actualDim = length (miShape mi)++        checkSizes :: [CoerceMatError]+        checkSizes = catMaybes $ zipWith3 checkSize [1..] expectedShape (miShape mi)+          where+            checkSize :: Int -> DS Int32 -> Int32 -> Maybe CoerceMatError+            checkSize dimIx dsExpected actual = dsToMaybe dsExpected >>= \expected ->+                if expected == actual+                then Nothing+                else Just $ SizeError dimIx+                          $ fromIntegral+                            <$> ExpectationError expected actual++    checkNumChannels :: Int32 -> Maybe CoerceMatError+    checkNumChannels expectedNumChannels+        | miChannels mi == expectedNumChannels = Nothing+        | otherwise = Just $ ChannelError+                           $ fromIntegral+                             <$> ExpectationError expectedNumChannels (miChannels mi)++    checkDepth :: Depth -> Maybe CoerceMatError+    checkDepth expectedDepth+        | miDepth mi == expectedDepth = Nothing+        | otherwise = Just $ DepthError+                           $ ExpectationError expectedDepth (miDepth mi)++-- | Relaxes the type level constraints+--+-- Only identical or looser constraints are allowed. For tighter+-- constraints use 'coerceMat'.+--+-- This allows you to \'forget\' type level guarantees for zero+-- cost. Similar to 'unsafeCoerceMat', but totally safe.+--+-- [Identical] @a@ to @b@ with @a ~ b@+-- [Looser]  @(\''S' a)@ to @\''D'@ or @(\''S' a)@ to @(\''S' b)@ with @'MayRelax' a b@+-- [Tighter] @\''D'@ to @(\''S' a)@+relaxMat+    :: ( MayRelax shapeIn    shapeOut+       , MayRelax channelsIn channelsOut+       , MayRelax depthIn    depthOut+       )+    => Mat shapeIn  channelsIn  depthIn  -- ^ Original 'Mat'.+    -> Mat shapeOut channelsOut depthOut -- ^ 'Mat' with relaxed constraints.+relaxMat = unsafeCoerce++coerceMat+    :: ( ToShapeDS    (Proxy shapeOut)+       , ToChannelsDS (Proxy channelsOut)+       , ToDepthDS    (Proxy depthOut)+       )+    => Mat shapeIn channelsIn depthIn -- ^+    -> CvExcept (Mat shapeOut channelsOut depthOut)+coerceMat matIn | null errors = pure matOut+                | otherwise   = throwE $ CoerceMatError errors+  where+    matOut = unsafeCoerceMat matIn+    errors = typeCheckMat matOut++unsafeCoerceMat+    :: Mat shapeIn  channelsIn  depthIn+    -> Mat shapeOut channelsOut depthOut+unsafeCoerceMat = unsafeCoerce++-- | Similar to 'withPtr' in that it keeps the 'ForeignPtr' alive+-- during the execution of the given action but it doesn't extract the 'Ptr'+-- from the 'ForeignPtr'.+keepMatAliveDuring :: Mat shape channels depth -> IO a -> IO a+keepMatAliveDuring mat m = do+    x <- m+    touchForeignPtr $ unMat mat+    pure x++newEmptyMat :: IO (Mat ('S '[]) ('S 1) ('S Word8))+newEmptyMat = unsafeCoerceMat <$> fromPtr [CU.exp|Mat * { new Mat() }|]++-- TODO (RvD): what happens if we construct a mat with more than 4 channels?+-- A scalar is just 4 values. What would be the default value of the 5th channel?+newMat+    :: ( ToShape    shape+       , ToChannels channels+       , ToDepth    depth+       , ToScalar   scalar+       -- , MinLengthDS 2 shape+       -- , 1 .<=? channels+       -- , channels .<=? 512+       -- , 2 <= Length shape+       -- , 1 <= channels+       -- , channels <= 512+       )+    => shape -- ^+    -> channels+    -> depth+    -> scalar+    -> CvExceptT IO (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth))+newMat shape channels depth defValue = ExceptT $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withVector shape' $ \shapePtr ->+      withPtr (toScalar defValue) $ \scalarPtr ->+      withPtr dst $ \dstPtr ->+        [cvExcept|+          *$(Mat * dstPtr) =+            Mat( $(int32_t c'ndims)+               , $(int32_t * shapePtr)+               , $(int32_t c'type)+               , *$(Scalar * scalarPtr)+               );+        |]+  where+    c'ndims = fromIntegral $ VG.length shape'+    c'type  = marshalFlags depth' channels'++    shape'    = toShape shape+    channels' = toChannels channels+    depth'    = toDepth depth++-- TODO (BvD): Move to some Utility module.+withVector+    :: (VG.Vector v a, Storable a)+    => v a -- ^+    -> (Ptr a -> IO b)+    -> IO b+withVector v f =+    allocaArray n $ \ptr ->+      let go !ix+              | ix < n = do+                  pokeElemOff ptr ix (VG.unsafeIndex v ix)+                  go (ix+1)+              | otherwise = f ptr+      in go 0+  where+    n = VG.length v++withMatData+    :: Mat shape channels depth -- ^+    -> ([CSize] -> Ptr Word8 -> IO a)+    -> IO a+withMatData mat f = withPtr mat $ \matPtr ->+    alloca $ \(dimsPtr  :: Ptr Int32      ) ->+    alloca $ \(stepPtr2 :: Ptr (Ptr CSize)) ->+    alloca $ \(dataPtr2 :: Ptr (Ptr Word8)) -> do+      [CU.block|void {+        const Mat * const matPtr = $(Mat * matPtr);+        *$(int32_t *   const dimsPtr ) = matPtr->dims;+        *$(size_t  * * const stepPtr2) = matPtr->step.p;+        *$(uint8_t * * const dataPtr2) = matPtr->data;+      }|]+      dims    <- peek dimsPtr+      stepPtr <- peek stepPtr2+      dataPtr <- peek dataPtr2+      step    <- peekArray (fromIntegral dims) stepPtr+      f step dataPtr++matElemAddress :: Ptr Word8 -> [Int] -> [Int] -> Ptr a+matElemAddress dataPtr step pos = dataPtr `plusPtr` offset+    where+      offset = sum $ zipWith (*) step pos++-- TODO (RvD): check for negative sizes+-- This crashes OpenCV+mkMat+    :: ( ToShape    shape+       , ToChannels channels+       , ToDepth    depth+       , ToScalar   scalar+       )+    => shape    -- ^+    -> channels -- ^+    -> depth    -- ^+    -> scalar   -- ^+    -> CvExcept (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth))+mkMat shape channels depth defValue =+    unsafeCvExcept $ newMat shape channels depth defValue++cloneMat :: Mat shape channels depth+         -> Mat shape channels depth+cloneMat = unsafePerformIO . cloneMatIO++cloneMatIO :: Mat shape channels depth+           -> IO (Mat shape channels depth)+cloneMatIO mat =+    fmap unsafeCoerceMat $ fromPtr $ withPtr mat $ \matPtr ->+      [C.exp|Mat * { new Mat($(Mat * matPtr)->clone()) }|]++--------------------------------------------------------------------------------+-- Mutable matrix+--------------------------------------------------------------------------------++typeCheckMatM+    :: forall shape channels depth s+     . ( ToShapeDS    (Proxy shape)+       , ToChannelsDS (Proxy channels)+       , ToDepthDS    (Proxy depth)+       )+    => Mut (Mat shape channels depth) s -- ^ The matrix to be checked.+    -> [CoerceMatError] -- ^ Error messages.+typeCheckMatM = typeCheckMat . unMut++relaxMatM+    :: ( MayRelax shapeIn    shapeOut+       , MayRelax channelsIn channelsOut+       , MayRelax depthIn    depthOut+       )+    => Mut (Mat shapeIn  channelsIn  depthIn ) s -- ^ Original 'Mat'.+    -> Mut (Mat shapeOut channelsOut depthOut) s -- ^ 'Mat' with relaxed constraints.+relaxMatM = unsafeCoerce++coerceMatM+    :: ( ToShapeDS    (Proxy shapeOut)+       , ToChannelsDS (Proxy channelsOut)+       , ToDepthDS    (Proxy depthOut)+       )+    => Mut (Mat shapeIn channelsIn depthIn) s -- ^+    -> CvExcept (Mut (Mat shapeOut channelsOut depthOut) s)+coerceMatM = fmap Mut . coerceMat . unMut++unsafeCoerceMatM+    :: Mut (Mat shapeIn  channelsIn  depthIn ) s+    -> Mut (Mat shapeOut channelsOut depthOut) s+unsafeCoerceMatM = unsafeCoerce++-- TODO (RvD): check for negative sizes+-- This crashes OpenCV+mkMatM+    :: ( PrimMonad m+       , ToShape    shape+       , ToChannels channels+       , ToDepth    depth+       , ToScalar   scalar+       )+    => shape    -- ^+    -> channels -- ^+    -> depth    -- ^+    -> scalar   -- ^+    -> CvExceptT m (Mut (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth)) (PrimState m))+mkMatM shape channels depth defValue = do+    mat <- mapExceptT unsafePrimToPrim $ newMat shape channels depth defValue+    unsafeThaw mat++createMat+    :: (forall s. CvExceptT (ST s) (Mut (Mat shape channels depth) s)) -- ^+    -> CvExcept (Mat shape channels depth)+createMat mk = runCvExceptST $ unsafeFreeze =<< mk++withMatM+    :: ( ToShape    shape+       , ToChannels channels+       , ToDepth    depth+       , ToScalar   scalar+       )+    => shape    -- ^+    -> channels -- ^+    -> depth    -- ^+    -> scalar   -- ^+    -> (  forall s+       .  Mut (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth)) (PrimState (ST s))+       -> CvExceptT (ST s) ()+       )+    -> CvExcept (Mat (ShapeT shape) (ChannelsT channels) (DepthT depth))+withMatM shape channels depth defValue f = createMat $ do+    matM <- mkMatM shape channels depth defValue+    f matM+    pure matM++cloneMatM :: (PrimMonad m)+          => Mat shape channels depth+          -> m (Mat shape channels depth)+cloneMatM = unsafePrimToPrim . cloneMatIO+++--------------------------------------------------------------------------------+-- Meta information+--------------------------------------------------------------------------------++data MatInfo+   = MatInfo+     { miShape    :: ![Int32]+     , miDepth    :: !Depth+     , miChannels :: !Int32+     }+     deriving (Show, Eq)++matInfo :: Mat shape channels depth -> MatInfo+matInfo mat = unsafePerformIO $+    withPtr mat $ \matPtr ->+    alloca $ \(flagsPtr :: Ptr Int32) ->+    alloca $ \(dimsPtr  :: Ptr Int32) ->+    alloca $ \(sizePtr  :: Ptr (Ptr Int32)) -> do+      [CU.block|void {+        const Mat * const matPtr = $(Mat * matPtr);+        *$(int32_t *   const flagsPtr) = matPtr->flags;+        *$(int32_t *   const dimsPtr ) = matPtr->dims;+        *$(int32_t * * const sizePtr ) = matPtr->size.p;+      }|]+      (depth, channels) <- unmarshalFlags <$> peek flagsPtr+      dims <- peek dimsPtr+      size <- peek sizePtr+      shape <- peekArray (fromIntegral dims) size+      pure MatInfo+           { miShape    = shape+           , miDepth    = depth+           , miChannels = channels+           }++-- | All possible positions (indexes) for a given shape (list of+-- sizes per dimension).+--+-- @+-- dimPositions [3, 4]+-- [ [0, 0], [0, 1], [0, 2], [0, 3]+-- , [1, 0], [1, 1], [1, 2], [1, 3]+-- , [2, 0], [2, 1], [2, 2], [2, 3]+-- ]+-- @+dimPositions :: (Num a, Enum a) => [a] -> [[a]]+dimPositions = traverse (enumFromTo 0 . pred)++--------------------------------------------------------------------------------++type family ShapeT (a :: ka) :: DS [DS Nat] where+    ShapeT [Int32]          = 'D+    ShapeT (V.Vector Int32) = 'D+    ShapeT (x ::: xs)       = 'S (DSNats (x ::: xs))+    ShapeT (xs :: [Nat])    = 'S (DSNats xs)+    ShapeT (Proxy a)        = ShapeT a++type ChannelsT a = DSNat a++--------------------------------------------------------------------------------++class ToShape a where+    toShape :: a -> V.Vector Int32++-- | identity+instance ToShape (V.Vector Int32) where+    toShape = id++-- | direct conversion to 'V.Vector'+instance ToShape [Int32] where+    toShape = V.fromList++-- | empty 'V.Vector'+instance ToShape (Proxy '[]) where+    toShape _proxy = V.empty++-- | fold over the type level list+instance (ToInt32 (Proxy a), ToShape (Proxy as))+      => ToShape (Proxy (a ': as)) where+    toShape _proxy =+        V.cons+          (toInt32 (Proxy :: Proxy a))+          (toShape (Proxy :: Proxy as))++-- | empty 'V.Vector'+instance ToShape Z where+    toShape Z = V.empty++-- | fold over ':::'+instance (ToInt32 a, ToShape as) => ToShape (a ::: as) where+    toShape (a ::: as) = V.cons (toInt32 a) (toShape as)++--------------------------------------------------------------------------------++class ToShapeDS a where+    toShapeDS :: a -> DS [DS Int32]++instance ToShapeDS (proxy 'D) where+    toShapeDS _proxy = D++instance (ToNatListDS (Proxy as)) => ToShapeDS (Proxy ('S as)) where+    toShapeDS _proxy = S $ toNatListDS (Proxy :: Proxy as)++--------------------------------------------------------------------------------++type ToChannels a = ToInt32 a++toChannels :: (ToInt32 a) => a -> Int32+toChannels = toInt32++type ToChannelsDS a = ToNatDS a++toChannelsDS :: (ToChannelsDS a) => a -> DS Int32+toChannelsDS = toNatDS++--------------------------------------------------------------------------------++mkPlacementNewInstance ''Mat
+ src/OpenCV/Internal/Core/Types/Mat/Depth.hs view
@@ -0,0 +1,74 @@+{-# language CPP #-}+{-# language MultiParamTypeClasses #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Mat.Depth+    ( Depth(..)+    , ToDepth(toDepth)+    , ToDepthDS(toDepthDS)+    , DepthT+    , StaticDepthT+    ) where++import "base" Data.Int+import "base" Data.Proxy+import "base" Data.Word+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++data Depth =+     Depth_8U+   | Depth_8S+   | Depth_16U+   | Depth_16S+   | Depth_32S+   | Depth_32F+   | Depth_64F+   | Depth_USRTYPE1+     deriving (Bounded, Enum, Eq, Show)++--------------------------------------------------------------------------------++class ToDepth a where+    toDepth :: a -> Depth++instance ToDepth Depth where toDepth = id+instance ToDepth (proxy Word8 ) where toDepth _proxy = Depth_8U+instance ToDepth (proxy Int8  ) where toDepth _proxy = Depth_8S+instance ToDepth (proxy Word16) where toDepth _proxy = Depth_16U+instance ToDepth (proxy Int16 ) where toDepth _proxy = Depth_16S+instance ToDepth (proxy Int32 ) where toDepth _proxy = Depth_32S+instance ToDepth (proxy Float ) where toDepth _proxy = Depth_32F+instance ToDepth (proxy Double) where toDepth _proxy = Depth_64F+-- TODO (BvD): instance ToDepth ? where toDepth = const Depth_USRTYPE1+-- RvD: perhaps ByteString? Or a fixed size (statically) vector of bytes++--------------------------------------------------------------------------------++class ToDepthDS a where+    toDepthDS :: a -> DS Depth++instance ToDepthDS Depth      where toDepthDS _depth = D+instance ToDepthDS (proxy 'D) where toDepthDS _proxy = D++instance ToDepthDS (proxy ('S Word8 )) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Word8 )+instance ToDepthDS (proxy ('S Int8  )) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Int8  )+instance ToDepthDS (proxy ('S Word16)) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Word16)+instance ToDepthDS (proxy ('S Int16 )) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Int16 )+instance ToDepthDS (proxy ('S Int32 )) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Int32 )+instance ToDepthDS (proxy ('S Float )) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Float )+instance ToDepthDS (proxy ('S Double)) where toDepthDS _proxy = S $ toDepth (Proxy :: Proxy Double)++--------------------------------------------------------------------------------++type family DepthT a :: DS * where+    DepthT Depth     = 'D+    DepthT (proxy d) = 'S d++type family StaticDepthT a :: * where+    StaticDepthT (proxy d) = d+    StaticDepthT d         = d
+ src/OpenCV/Internal/Core/Types/Mat/HMat.hs view
@@ -0,0 +1,158 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Mat.HMat+    ( HMat(..)+    , HElems(..)+    , hElemsDepth+    , hElemsLength+    , ToHElems(toHElems)++    , matToHMat+    , hMatToMat+    ) where++import "base" Data.Foldable+import "base" Data.Int+import "base" Data.Word+import "base" Foreign.C.Types+import "base" Foreign.Ptr ( Ptr )+import "base" Foreign.Storable ( Storable(..), peekElemOff, pokeElemOff )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "bytestring" Data.ByteString as B+import "linear" Linear.Vector ( zero )+import "linear" Linear.V4 ( V4(..) )+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.TypeLevel+import qualified "vector" Data.Vector as V+import qualified "vector" Data.Vector.Generic as VG+import qualified "vector" Data.Vector.Unboxed as VU+import qualified "vector" Data.Vector.Unboxed.Mutable as VUM++--------------------------------------------------------------------------------++data HMat+   = HMat+     { hmShape    :: ![Int32]+     , hmChannels :: !Int32+     , hmElems    :: !HElems+     } deriving (Show, Eq)++data HElems+   = HElems_8U       !(VU.Vector Word8)+   | HElems_8S       !(VU.Vector Int8)+   | HElems_16U      !(VU.Vector Word16)+   | HElems_16S      !(VU.Vector Int16)+   | HElems_32S      !(VU.Vector Int32)+   | HElems_32F      !(VU.Vector Float)+   | HElems_64F      !(VU.Vector Double)+   | HElems_USRTYPE1 !(V.Vector B.ByteString)+     deriving (Show, Eq)++hElemsDepth :: HElems -> Depth+hElemsDepth = \case+    HElems_8U       _v -> Depth_8U+    HElems_8S       _v -> Depth_8S+    HElems_16U      _v -> Depth_16U+    HElems_16S      _v -> Depth_16S+    HElems_32S      _v -> Depth_32S+    HElems_32F      _v -> Depth_32F+    HElems_64F      _v -> Depth_64F+    HElems_USRTYPE1 _v -> Depth_USRTYPE1++hElemsLength :: HElems -> Int+hElemsLength = \case+    HElems_8U       v -> VG.length v+    HElems_8S       v -> VG.length v+    HElems_16U      v -> VG.length v+    HElems_16S      v -> VG.length v+    HElems_32S      v -> VG.length v+    HElems_32F      v -> VG.length v+    HElems_64F      v -> VG.length v+    HElems_USRTYPE1 v -> VG.length v++class ToHElems a where+    toHElems :: VU.Vector a -> HElems++instance ToHElems Word8  where toHElems = HElems_8U+instance ToHElems Int8   where toHElems = HElems_8S+instance ToHElems Word16 where toHElems = HElems_16U+instance ToHElems Int16  where toHElems = HElems_16S+instance ToHElems Int32  where toHElems = HElems_32S+instance ToHElems Float  where toHElems = HElems_32F+instance ToHElems Double where toHElems = HElems_64F++matToHMat :: Mat shape channels depth -> HMat+matToHMat mat = unsafePerformIO $ withMatData mat $ \step dataPtr -> do+    elems <- copyElems info (map fromIntegral step) dataPtr+    pure HMat+         { hmShape    = miShape    info+         , hmChannels = miChannels info+         , hmElems    = elems+         }+  where+    info = matInfo mat++    copyElems+        :: MatInfo+        -> [Int]     -- ^ step+        -> Ptr Word8 -- ^ data+        -> IO HElems+    copyElems (MatInfo shape depth channels) step dataPtr =+        case depth of+          Depth_8U  -> HElems_8U  <$> copyToVec+          Depth_8S  -> HElems_8S  <$> copyToVec+          Depth_16U -> HElems_16U <$> copyToVec+          Depth_16S -> HElems_16S <$> copyToVec+          Depth_32S -> HElems_32S <$> copyToVec+          Depth_32F -> HElems_32F <$> copyToVec+          Depth_64F -> HElems_64F <$> copyToVec+          Depth_USRTYPE1 -> HElems_USRTYPE1 <$> error "todo"+      where+        copyToVec :: (Storable a, VU.Unbox a) => IO (VU.Vector a)+        copyToVec = do+            v <- VUM.unsafeNew $ product0 (map fromIntegral shape) * (fromIntegral channels)+            forM_ (zip [0,channels..] $ dimPositions $ map fromIntegral shape) $ \(posIx, pos) -> do+                let elemPtr = matElemAddress dataPtr step pos+                forM_ [0 .. channels - 1] $ \channelIx -> do+                  e <- peekElemOff elemPtr $ fromIntegral channelIx+                  VUM.unsafeWrite v (fromIntegral $ posIx + channelIx) e+            VU.unsafeFreeze v++hMatToMat :: HMat -> Mat 'D 'D 'D+hMatToMat (HMat shape channels elems) = unsafePerformIO $ do+    mat <- exceptErrorIO $ newMat sizes channels depth scalar+    withMatData mat copyElems+    pure mat+  where+    sizes = V.fromList shape+    depth = hElemsDepth elems++    scalar :: Scalar+    scalar = toScalar (zero :: V4 CDouble)++    copyElems :: [CSize] -> Ptr Word8 -> IO ()+    copyElems step dataPtr = case elems of+        HElems_8U       v -> copyFromVec v+        HElems_8S       v -> copyFromVec v+        HElems_16U      v -> copyFromVec v+        HElems_16S      v -> copyFromVec v+        HElems_32S      v -> copyFromVec v+        HElems_32F      v -> copyFromVec v+        HElems_64F      v -> copyFromVec v+        HElems_USRTYPE1 _v -> error "todo"+      where+        copyFromVec :: (Storable a, VU.Unbox a) => VU.Vector a -> IO ()+        copyFromVec v =+            forM_ (zip [0, fromIntegral channels ..] $ dimPositions (fromIntegral <$> shape)) $ \(posIx, pos) -> do+              let elemPtr = matElemAddress dataPtr (fromIntegral <$> step) pos+              forM_ [0 .. channels - 1] $ \channelIx ->+                pokeElemOff elemPtr (fromIntegral channelIx) $ VU.unsafeIndex v (fromIntegral $ posIx + channelIx)++product0 :: (Num a) => [a] -> a+product0 [] = 0+product0 xs = product xs
+ src/OpenCV/Internal/Core/Types/Mat/Marshal.hsc view
@@ -0,0 +1,77 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Mat.Marshal+    ( marshalDepth+    , unmarshalDepth+    , marshalFlags+    , unmarshalFlags+    ) where++import "base" Data.Bits+import "base" Data.Int+import "base" Data.Monoid ( (<>) )+import "this" OpenCV.Internal.Core.Types.Mat.Depth++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/core.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++#num CV_8U+#num CV_8S+#num CV_16U+#num CV_16S+#num CV_32S+#num CV_32F+#num CV_64F+#num CV_USRTYPE1++marshalDepth :: Depth -> Int32+marshalDepth = \case+    Depth_8U       -> c'CV_8U+    Depth_8S       -> c'CV_8S+    Depth_16U      -> c'CV_16U+    Depth_16S      -> c'CV_16S+    Depth_32S      -> c'CV_32S+    Depth_32F      -> c'CV_32F+    Depth_64F      -> c'CV_64F+    Depth_USRTYPE1 -> c'CV_USRTYPE1++unmarshalDepth :: Int32 -> Depth+unmarshalDepth n+    | n == c'CV_8U       = Depth_8U+    | n == c'CV_8S       = Depth_8S+    | n == c'CV_16U      = Depth_16U+    | n == c'CV_16S      = Depth_16S+    | n == c'CV_32S      = Depth_32S+    | n == c'CV_32F      = Depth_32F+    | n == c'CV_64F      = Depth_64F+    | n == c'CV_USRTYPE1 = Depth_USRTYPE1+    | otherwise          = error $ "unknown depth " <> show n++#num CV_CN_SHIFT++marshalFlags+    :: Depth+    -> Int32 -- ^ Number of channels+    -> Int32+marshalFlags depth cn =+    marshalDepth depth+      .|. ((cn - 1) `unsafeShiftL` c'CV_CN_SHIFT)++#num CV_CN_MAX+#num CV_MAT_DEPTH_MASK++unmarshalFlags :: Int32 -> (Depth, Int32)+unmarshalFlags n =+    ( unmarshalDepth $ n .&. c'CV_MAT_DEPTH_MASK+    , 1 + ((n `unsafeShiftR` c'CV_CN_SHIFT) .&. (c'CV_CN_MAX - 1))+    )
+ src/OpenCV/Internal/Core/Types/Mat/ToFrom.cpp view
@@ -0,0 +1,307 @@++#include "opencv2/core.hpp"++#include "haskell_opencv_matx_typedefs.hpp"++using namespace cv;++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_0_0b4a62ec427ab2026755892cbce6d99281ca3e6b(Vec4d * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_1_1e9a2ac9b7f375489b1402a45fada434d61f94ab(Vec4f * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_2_36cb789c879453eee67df8a386d46f5c2c587f56(Vec4i * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_3_942d6618c0fe7f6b9593fc883669524d0d9fb227(Vec3d * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_4_b3090145918705b77f10036ff2143482f46f2000(Vec3f * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_5_05dd7c934cb60b53490b79f16fe45af9fbaec9c2(Vec3i * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_6_6ddc28a7e03249693033ca7c6a8c0135085e8c7e(Vec2d * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_7_02eb999953c24952016530e4d2b0cd1324dcf2b0(Vec2f * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_8_6bb22999b6b050d5ac86e6984a03f887ff92869b(Vec2i * vecPtr_inline_c_0) {+return (                                    new cv::Mat(*vecPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_9_7d7f73c0b46f8baa76378762885fc6a6bed9f8e8(Matx66d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_10_128a0da7555089a341c68840e2f9b233452c95a0(Matx66f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_11_d5eb541705f28bd53dd7a69dbd70d47f741335cf(Matx61d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_12_2a493b0b3c4f2c67550f6a3f73b0aafa3513fb69(Matx61f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_13_8f5c233071748410b50a201aa2153d4f2d553f24(Matx51d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_14_c2fff5fd5ff4dfdb086e6bd9f73ade8470fb5d21(Matx51f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_15_2a562a86dc1b9757af2c1b812f95b880980e57e1(Matx44d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_16_8c8c57f97f89df5748204bbe5663ecb2b5d94da2(Matx44f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_17_af42cdd7bb243571475ab963f212fd5a10d3502d(Matx43d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_18_ce60ea97659f2605dd06601ae1df24e60068c466(Matx43f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_19_d175891079fb26a1501b7c42c5c0e6d54a56bed5(Matx41d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_20_a48f3bf9a9a4dae2340a50d2c77ced59d92f1e7e(Matx41f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_21_39e9a8089a76e17cf7899f56a0bc809d66ad748c(Matx34d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_22_8178c2bd3f85a221e26692bdb78ce0eb008f3f1d(Matx34f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_23_abb3f5c03c857879d7be5d421dc86538447c4f09(Matx33d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_24_2d75ca50c440f5a6e27fe2914183afee147f6fdb(Matx33f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_25_4c6f1d03642f100349b976eaf03d1942836b04e6(Matx32d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_26_304a66a864f53a670157dccab6b4d77145dcb663(Matx32f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_27_d87e61baada48adb272b1c3d22d3e36ac49c31d6(Matx31d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_28_1ad748701b04668af63d83ad3eb71a9062d77c03(Matx31f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_29_c148fc5d41eae792f80646df7451f6fd83661ebb(Matx23d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_30_0d87f13f869b54c7d3be9b6a2253cfe70e29091e(Matx23f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_31_6ac96f8c93771e9e0d3c6a6b661686a823ada3e2(Matx22d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_32_da9adea007a8a4326278f8e111d196407bdaaba3(Matx22f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_33_eca473cb3b20c52d6f56c76b87b794d6dff08a77(Matx21d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_34_4aea234c82d147d8026b542eaa3df0f4a79578bb(Matx21f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_35_93f1240e7f9ffcefd5a36ba09f255cb803598eff(Matx16d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_36_21af6d717acc7cde7d12727c234bba875e251589(Matx16f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_37_9022eda55895d984c013f67a43809740eb9b0729(Matx14d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_38_b0259f9daae441d86b4dc3f6f629ba31b12fa704(Matx14f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_39_0fc44fd1bfef1edde38f265c3d53b2d59e42b626(Matx13d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_40_faded17ee945cc4d3d26b6c2b54aad7d80d60795(Matx13f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_41_5131effdb62ad7e1c09d0a396e20d56b6bd8a80e(Matx12d * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}++extern "C" {+Mat * inline_c_OpenCV_Internal_Core_Types_Mat_ToFrom_42_7abd6a2eb31c14304b28a0aa525e105497baf217(Matx12f * matxPtr_inline_c_0) {+return (                                     new cv::Mat(*matxPtr_inline_c_0, false)           );+}++}
+ src/OpenCV/Internal/Core/Types/Mat/ToFrom.hs view
@@ -0,0 +1,213 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}+{-# language UndecidableInstances #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Mat.ToFrom+  ( MatShape+  , MatChannels+  , MatDepth+  , ToMat(..)+  , FromMat(..)+  ) where++import           "base" Data.Proxy ( Proxy(..) )+import           "base" Foreign.Storable ( Storable )+import           "base" GHC.TypeLits+import           "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import           "linear" Linear.Matrix ( M23, M33 )+import           "linear" Linear.V2 ( V2(..) )+import           "linear" Linear.V3 ( V3(..) )+import           "linear" Linear.V4 ( V4 )+import qualified "repa" Data.Array.Repa as Repa+import           "this" OpenCV.Core.Types.Matx+import           "this" OpenCV.Core.Types.Mat.Repa+import           "this" OpenCV.Core.Types.Vec+import           "this" OpenCV.Internal.C.Inline ( openCvCtx )+import           "this" OpenCV.Internal.C.Types+import           "this" OpenCV.Internal.Core.Types.Mat+import           "this" OpenCV.Internal.Exception+import           "this" OpenCV.TypeLevel+import           "this" OpenCV.Unsafe+++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "haskell_opencv_matx_typedefs.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------++type family MatShape    (a :: *) :: DS [DS Nat]+type family MatChannels (a :: *) :: DS Nat+type family MatDepth    (a :: *) :: DS *++type instance MatShape    (Mat shape channels depth) = shape+type instance MatChannels (Mat shape channels depth) = channels+type instance MatDepth    (Mat shape channels depth) = depth++type instance MatShape    (Matx m n depth) = ShapeT '[m, n]+type instance MatChannels (Matx m n depth) = 'S 1+type instance MatDepth    (Matx m n depth) = 'S depth++type instance MatShape    (Vec dim depth) = ShapeT '[dim]+type instance MatChannels (Vec dim depth) = 'S 1+type instance MatDepth    (Vec dim depth) = 'S depth++type instance MatShape    (M23 depth) = ShapeT [2, 3]+type instance MatChannels (M23 depth) = 'S 1+type instance MatDepth    (M23 depth) = 'S depth++type instance MatShape    (M33 depth) = ShapeT [3, 3]+type instance MatChannels (M33 depth) = 'S 1+type instance MatDepth    (M33 depth) = 'S depth++class ToMat a where+    toMat :: a -> Mat (MatShape a) (MatChannels a) (MatDepth a)++class FromMat a where+    fromMat :: Mat (MatShape a) (MatChannels a) (MatDepth a) -> a++instance ToMat   (Mat shape channels depth) where toMat   = id+instance FromMat (Mat shape channels depth) where fromMat = id++--------------------------------------------------------------------------------+-- Matx instances++#define MATX_TO_MAT(NAME)                          \+instance ToMat NAME where {                        \+    toMat matx = unsafePerformIO $ fromPtr $       \+        withPtr matx $ \matxPtr ->                 \+          [CU.exp| Mat * {                         \+            new cv::Mat(*$(NAME * matxPtr), false) \+          }|];                                     \+};++MATX_TO_MAT(Matx12f)+MATX_TO_MAT(Matx12d)+MATX_TO_MAT(Matx13f)+MATX_TO_MAT(Matx13d)+MATX_TO_MAT(Matx14f)+MATX_TO_MAT(Matx14d)+MATX_TO_MAT(Matx16f)+MATX_TO_MAT(Matx16d)+MATX_TO_MAT(Matx21f)+MATX_TO_MAT(Matx21d)+MATX_TO_MAT(Matx22f)+MATX_TO_MAT(Matx22d)+MATX_TO_MAT(Matx23f)+MATX_TO_MAT(Matx23d)+MATX_TO_MAT(Matx31f)+MATX_TO_MAT(Matx31d)+MATX_TO_MAT(Matx32f)+MATX_TO_MAT(Matx32d)+MATX_TO_MAT(Matx33f)+MATX_TO_MAT(Matx33d)+MATX_TO_MAT(Matx34f)+MATX_TO_MAT(Matx34d)+MATX_TO_MAT(Matx41f)+MATX_TO_MAT(Matx41d)+MATX_TO_MAT(Matx43f)+MATX_TO_MAT(Matx43d)+MATX_TO_MAT(Matx44f)+MATX_TO_MAT(Matx44d)+MATX_TO_MAT(Matx51f)+MATX_TO_MAT(Matx51d)+MATX_TO_MAT(Matx61f)+MATX_TO_MAT(Matx61d)+MATX_TO_MAT(Matx66f)+MATX_TO_MAT(Matx66d)++--------------------------------------------------------------------------------+-- Vec instances++#define VEC_TO_MAT(NAME)                          \+instance ToMat NAME where {                       \+    toMat vec = unsafePerformIO $ fromPtr $       \+        withPtr vec $ \vecPtr ->                  \+          [CU.exp| Mat * {                        \+            new cv::Mat(*$(NAME * vecPtr), false) \+          }|];                                    \+};++VEC_TO_MAT(Vec2i)+VEC_TO_MAT(Vec2f)+VEC_TO_MAT(Vec2d)+VEC_TO_MAT(Vec3i)+VEC_TO_MAT(Vec3f)+VEC_TO_MAT(Vec3d)+VEC_TO_MAT(Vec4i)+VEC_TO_MAT(Vec4f)+VEC_TO_MAT(Vec4d)++--------------------------------------------------------------------------------+-- Linear instances++instance (Storable depth) => FromMat (M23 depth) where+    fromMat = repaToM23 . toRepa++instance (Storable depth) => FromMat (M33 depth) where+    fromMat = repaToM33 . toRepa++repaToM23 :: (Storable e) => Repa.Array (M '[ 'S 2, 'S 3 ] 1) Repa.DIM3 e -> M23 e+repaToM23 a =+    V2 (V3 (i 0 0) (i 0 1) (i 0 2))+       (V3 (i 1 0) (i 1 1) (i 1 2))+  where+    i row col = Repa.unsafeIndex a $ Repa.ix3 0 col row++repaToM33 :: (Storable e) => Repa.Array (M '[ 'S 3, 'S 3 ] 1) Repa.DIM3 e -> M33 e+repaToM33 a =+    V3 (V3 (i 0 0) (i 0 1) (i 0 2))+       (V3 (i 1 0) (i 1 1) (i 1 2))+       (V3 (i 2 0) (i 2 1) (i 2 2))+  where+    i row col = Repa.unsafeIndex a $ Repa.ix3 0 col row++instance (ToDepth (Proxy depth), Storable depth)+      => ToMat (M23 depth) where+    toMat (V2 (V3 i00 i01 i02)+              (V3 i10 i11 i12)+          ) =+      exceptError $ withMatM+        (Proxy :: Proxy [2, 3])+        (Proxy :: Proxy 1)+        (Proxy :: Proxy depth)+        (pure 0 :: V4 Double) $ \imgM -> do+          unsafeWrite imgM [0, 0] 0 i00+          unsafeWrite imgM [1, 0] 0 i10+          unsafeWrite imgM [0, 1] 0 i01+          unsafeWrite imgM [1, 1] 0 i11+          unsafeWrite imgM [0, 2] 0 i02+          unsafeWrite imgM [1, 2] 0 i12++instance (ToDepth (Proxy depth), Storable depth)+      => ToMat (M33 depth) where+    toMat (V3 (V3 i00 i01 i02)+              (V3 i10 i11 i12)+              (V3 i20 i21 i22)+          ) =+      exceptError $ withMatM+        (Proxy :: Proxy [3, 3])+        (Proxy :: Proxy 1)+        (Proxy :: Proxy depth)+        (pure 0 :: V4 Double) $ \imgM -> do+          unsafeWrite imgM [0, 0] 0 i00+          unsafeWrite imgM [1, 0] 0 i10+          unsafeWrite imgM [2, 0] 0 i20+          unsafeWrite imgM [0, 1] 0 i01+          unsafeWrite imgM [1, 1] 0 i11+          unsafeWrite imgM [2, 1] 0 i21+          unsafeWrite imgM [0, 2] 0 i02+          unsafeWrite imgM [1, 2] 0 i12+          unsafeWrite imgM [2, 2] 0 i22
+ src/OpenCV/Internal/Core/Types/Matx.hs view
@@ -0,0 +1,40 @@+{-# language CPP #-}+{-# language MultiParamTypeClasses #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Matx+    ( Matx(..)+    , MatxDimR+    , MatxDimC+    , IsMatx(..)+    ) where++import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" GHC.TypeLits+import "this" OpenCV.Internal.C.Types++--------------------------------------------------------------------------------++newtype Matx (dimR :: Nat) (dimC :: Nat) (depth :: *)+      = Matx {unMatx :: ForeignPtr (C'Matx dimR dimC depth)}++type instance C (Matx dimR dimC depth) = C'Matx dimR dimC depth++instance WithPtr (Matx dimR dimC depth) where+    withPtr = withForeignPtr . unMatx++type family MatxDimR (m :: * -> *) :: Nat+type family MatxDimC (m :: * -> *) :: Nat++type instance MatxDimR (Matx dimR dimC) = dimR+type instance MatxDimC (Matx dimR dimC) = dimC++class IsMatx (m :: * -> *) depth where+    toMatx   :: m depth -> Matx (MatxDimR m) (MatxDimC m) depth+    fromMatx :: Matx (MatxDimR m) (MatxDimC m) depth -> m depth++    toMatxIO :: m depth -> IO (Matx (MatxDimR m) (MatxDimC m) depth)+    toMatxIO = pure . toMatx
+ src/OpenCV/Internal/Core/Types/Matx/TH.hs view
@@ -0,0 +1,136 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Matx.TH+  ( mkMatxType+  ) where++import "base" Data.List ( intercalate )+import "base" Data.Monoid ( (<>) )+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Internal+import "this" OpenCV.Internal.Core.Types.Matx+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types++mkMatxType+    :: String  -- ^ Matx type name, for both Haskell and C+    -> Integer -- ^ Row dimension+    -> Integer -- ^ Column dimension+    -> Name    -- ^ Depth type name in Haskell+    -> String  -- ^ Depth type name in C+    -> Q [Dec]+mkMatxType mTypeNameStr dimR dimC depthTypeName cDepthTypeStr+    | dimR < 1 || dimR > 6 || dimC < 1 || dimC > 6 =+        fail $ "mkMatxType: Unsupported dimension: " <> show dimR <> "x" <> show dimC+    | otherwise =+      fmap concat . sequence $+        [ (:[]) <$> matxTySynD+        , fromPtrDs+        , isMatxOpenCVInstanceDs+          -- The largest Matx constructor in C++ takes 16 arguments.+          -- TODO (RvD): for larger number of arguments we can use the+          -- constructor that initializes from a plain array.+        , if dimR * dimC <= 16+          then newMatxDs+          else pure []+        , mkPlacementNewInstance mTypeName+        ]+  where+    mTypeName :: Name+    mTypeName = mkName mTypeNameStr++    cMatxTypeStr :: String+    cMatxTypeStr = mTypeNameStr++    mTypeQ :: Q Type+    mTypeQ = conT mTypeName++    depthTypeQ :: Q Type+    depthTypeQ = conT depthTypeName++    dimRTypeQ, dimCTypeQ :: Q Type+    dimRTypeQ = litT (numTyLit dimR)+    dimCTypeQ = litT (numTyLit dimC)++    matxTySynD :: Q Dec+    matxTySynD =+        tySynD mTypeName+               []+               ([t|Matx|] `appT` dimRTypeQ `appT` dimCTypeQ `appT` depthTypeQ)++    fromPtrDs :: Q [Dec]+    fromPtrDs =+        [d|+        instance FromPtr $(mTypeQ) where+          fromPtr = objFromPtr Matx $ $(finalizerExpQ)+        |]+      where+        finalizerExpQ :: Q Exp+        finalizerExpQ = do+          ptr <- newName "ptr"+          lamE [varP ptr] $+            quoteExp CU.exp $+              "void { delete $(" <> cMatxTypeStr <> " * " <> nameBase ptr <> ") }"++    isMatxOpenCVInstanceDs :: Q [Dec]+    isMatxOpenCVInstanceDs =+        [d|+        instance IsMatx (Matx $(dimRTypeQ) $(dimCTypeQ)) $(depthTypeQ) where+          toMatx   = id+          toMatxIO = pure+          fromMatx = id+        |]++    newMatxDs :: Q [Dec]+    newMatxDs = sequence+        [ sigD funName funTypeQ+        , withVarNames =<< mapM newName fieldNames+        ]+      where+        -- example: Float -> Float -> Float -> Float -> IO Matx22f+        funTypeQ :: Q Type+        funTypeQ = foldr (\_fieldName acc -> arrowT `appT` depthTypeQ `appT` acc)+                         ([t|IO|] `appT` mTypeQ)+                         fieldNames++        funName :: Name+        funName = mkName $ "new" <> mTypeNameStr++        fieldNames :: [String]+        fieldNames = [fieldName r c | r <- [1..dimR], c <- [1..dimC]]+          where+            fieldName :: Integer -> Integer -> String+            fieldName r c = "f" <> show r <> show c++        withVarNames :: [Name] -> Q Dec+        withVarNames varNames = funD funName [funClause]+          where+            funClause :: Q Clause+            funClause = clause (map varP varNames) funBody []++            funBody :: Q Body+            funBody = normalB $ appE [e|fromPtr|] $ quoteExp CU.exp $ concat+                        [ cMatxTypeStr+                        , " * { new cv::Matx<"+                        , cDepthTypeStr+                        , ", "+                        , show dimR+                        , ", "+                        , show dimC+                        , ">"+                        , "("+                        , intercalate ", " (map fieldQuote varNames)+                        , ")"+                        , "}"+                        ]++            fieldQuote :: Name -> String+            fieldQuote n = "$(" <> cDepthTypeStr <> " " <> nameBase n <> ")"
+ src/OpenCV/Internal/Core/Types/Point.hs view
@@ -0,0 +1,69 @@+{-# language CPP #-}+{-# language ConstraintKinds #-}+{-# language MultiParamTypeClasses #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Point+  ( Point(..)+  , PointDim+  , IsPoint(..)+  , IsPoint2+  , IsPoint3+  ) where++import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" GHC.TypeLits+import "linear" Linear ( V2, V3 )+import "this" OpenCV.Internal.C.Types++--------------------------------------------------------------------------------++newtype Point (dim :: Nat) (depth :: *)+      = Point {unPoint :: ForeignPtr (C'Point dim depth)}++type instance C (Point dim depth) = C'Point dim depth++instance WithPtr (Point dim depth) where+    withPtr = withForeignPtr . unPoint++type family PointDim (v :: * -> *) :: Nat++type instance PointDim (Point dim) = dim++type instance PointDim V2 = 2+type instance PointDim V3 = 3++class IsPoint (p :: * -> *) (depth :: *)  where+    toPoint   :: p depth -> Point (PointDim p) depth+    fromPoint :: Point (PointDim p) depth -> p depth++    toPointIO :: p depth -> IO (Point (PointDim p) depth)+    toPointIO = pure . toPoint++type IsPoint2 p depth = (IsPoint p depth, PointDim p ~ 2)+type IsPoint3 p depth = (IsPoint p depth, PointDim p ~ 3)++--------------------------------------------------------------------------------++instance (IsPoint V2 a, Show a)+      => Show (Point 2 a) where+    showsPrec prec point =+        showParen (prec >= 10)+        $ showString "toPoint "+        . showParen True (shows v2)+      where+        v2 :: V2 a+        v2 = fromPoint point++instance (IsPoint V3 a, Show a)+      => Show (Point 3 a) where+    showsPrec prec point =+        showParen (prec >= 10)+        $ showString "toPoint "+        . showParen True (shows v3)+      where+        v3 :: V3 a+        v3 = fromPoint point
+ src/OpenCV/Internal/Core/Types/Point/TH.hs view
@@ -0,0 +1,187 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Point.TH+  ( mkPointType+  ) where++import "base" Data.List ( intercalate )+import "base" Data.Monoid ( (<>) )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "linear" Linear ( V2(..), V3(..) )+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Point+import "this" OpenCV.Internal++mkPointType+    :: String  -- ^ Point type name, for both Haskell and C+    -> Integer -- ^ Point dimension+    -> String  -- ^ Point template name in C+    -> Name    -- ^ Depth type name in Haskell+    -> String  -- ^ Depth type name in C+    -> Q [Dec]+mkPointType pTypeNameStr dim cTemplateStr depthTypeName cDepthTypeStr+    | dim < 2 || dim > 3 = fail $ "mkPointType: Unsupported dimension: " <> show dim+    | otherwise =+      fmap concat . sequence $+        [ pure <$> pointTySynD+        , fromPtrDs+        , isPointOpenCVInstanceDs+        , isPointHaskellInstanceDs+        , mkPlacementNewInstance pTypeName+        ]+  where+    pTypeName :: Name+    pTypeName = mkName pTypeNameStr++    cPointTypeStr :: String+    cPointTypeStr = pTypeNameStr++    pTypeQ :: Q Type+    pTypeQ = conT pTypeName++    depthTypeQ :: Q Type+    depthTypeQ = conT depthTypeName++    dimTypeQ :: Q Type+    dimTypeQ = litT (numTyLit dim)++    pointTySynD :: Q Dec+    pointTySynD =+        tySynD pTypeName+               []+               ([t|Point|] `appT` dimTypeQ `appT` depthTypeQ)++    fromPtrDs :: Q [Dec]+    fromPtrDs =+        [d|+        instance FromPtr $(pTypeQ) where+          fromPtr = objFromPtr Point $ $(finalizerExpQ)+        |]+      where+        finalizerExpQ :: Q Exp+        finalizerExpQ = do+          ptr <- newName "ptr"+          lamE [varP ptr] $+            quoteExp CU.exp $+              "void { delete $(" <> cPointTypeStr <> " * " <> nameBase ptr <> ") }"++    isPointOpenCVInstanceDs :: Q [Dec]+    isPointOpenCVInstanceDs =+        [d|+        instance IsPoint (Point $(dimTypeQ)) $(depthTypeQ) where+          toPoint   = id+          toPointIO = pure+          fromPoint = id+        |]++    isPointHaskellInstanceDs :: Q [Dec]+    isPointHaskellInstanceDs =+        let ix = fromInteger dim - 2+        in withLinear (linearTypeQs   !! ix)+                      (linearConNames !! ix)+      where+        linearTypeQs :: [Q Type]+        linearTypeQs = map conT [''V2, ''V3]++        linearConNames :: [Name]+        linearConNames = ['V2, 'V3]++        withLinear :: Q Type -> Name -> Q [Dec]+        withLinear lpTypeQ lvConName =+            [d|+            instance IsPoint $(lpTypeQ) $(depthTypeQ) where+              toPoint   = unsafePerformIO . toPointIO+              toPointIO = $(toPointIOExpQ)+              fromPoint = $(fromPointExpQ)+            |]+          where+            toPointIOExpQ :: Q Exp+            toPointIOExpQ = do+                ns <- mapM newName elemNames+                lamE [conP lvConName $ map varP ns]+                 $ appE [e|fromPtr|]+                 $ quoteExp CU.exp+                 $ inlineCStr ns+              where+                inlineCStr :: [Name] -> String+                inlineCStr ns = concat+                    [ cPointTypeStr+                    , " * { new cv::" <> cTemplateStr+                    , "<" <> cDepthTypeStr <> ">"+                    , "(" <> intercalate ", " (map elemQuote ns) <> ")"+                    , " }"+                    ]+                  where+                    elemQuote :: Name -> String+                    elemQuote n = "$(" <> cDepthTypeStr <> " " <> nameBase n <> ")"++            fromPointExpQ :: Q Exp+            fromPointExpQ = do+                point <- newName "point"+                pointPtr <- newName "pointPtr"+                ptrNames <- mapM (newName . (<> "Ptr")) elemNames+                withPtrNames point pointPtr ptrNames+              where+                withPtrNames :: Name -> Name -> [Name] -> Q Exp+                withPtrNames point pointPtr ptrNames =+                    lamE [varP point]+                      $ appE [e|unsafePerformIO|]+                      $ withPtrVarsExpQ ptrNames+                  where++                    withPtrVarsExpQ :: [Name] -> Q Exp+                    withPtrVarsExpQ = foldr (\p -> appE [e|alloca|] . lamE [varP p]) withAllocatedVars++                    withAllocatedVars :: Q Exp+                    withAllocatedVars =+                        appE ([e|withPtr|] `appE` varE point)+                          $ lamE [varP pointPtr]+                          $ doE+                            [ noBindS $ quoteExp CU.block inlineCStr+                            , noBindS extractExpQ+                            ]++                    inlineCStr :: String+                    inlineCStr = unlines $+                        concat+                          [ "void {"+                          , "const cv::" <> cTemplateStr+                          , "<" <> cDepthTypeStr <> ">"+                          , " & p = *$("+                          , cPointTypeStr+                          , " * "+                          , nameBase pointPtr+                          , ");"+                          ]+                        : map ptrLine (zip [0..] ptrNames)+                        <> ["}"]+                      where+                        ptrLine :: (Int, Name) -> String+                        ptrLine (ix, ptrName) =+                            "*$(" <> cDepthTypeStr <> " * " <> nameBase ptrName <> ") = p." <> elemNames !! ix <> ";"++                    -- Applies the constructor to the values that are+                    -- read from the pointers.+                    extractExpQ :: Q Exp+                    extractExpQ = foldl (\acc peekExp -> [e|(<*>)|] `appE` acc `appE` peekExp)+                                        ([e|pure|] `appE` conE lvConName)+                                        peekExpQs+                      where+                        peekExpQs :: [Q Exp]+                        peekExpQs = map (\p -> [e|peek|] `appE` varE p) ptrNames++            elemNames :: [String]+            elemNames = take (fromInteger dim)+                             ["x", "y", "z"]
+ src/OpenCV/Internal/Core/Types/Rect.hs view
@@ -0,0 +1,103 @@+{-# language CPP #-}+{-# language ConstraintKinds #-}+{-# language DeriveFunctor #-}+{-# language DeriveTraversable #-}+{-# language MultiParamTypeClasses #-}+{-# language UndecidableInstances #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Rect+  ( Rect(..)+  , RectPoint+  , RectSize+  , HRect(..)+  , IsRect(..)+  ) where++import "aeson" Data.Aeson+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "linear" Linear.V2 ( V2(..) )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Core.Types.Point ( Point )+import "this" OpenCV.Core.Types.Size ( Size )+#if MIN_VERSION_base(4,9,0)+import "base" Data.Foldable ( Foldable )+import "base" Data.Traversable ( Traversable )+#endif++--------------------------------------------------------------------------------++newtype Rect (depth :: *)+      = Rect {unRect :: ForeignPtr (C'Rect depth)}++type instance C (Rect depth) = C'Rect depth++instance WithPtr (Rect depth) where withPtr = withForeignPtr . unRect++-- | Native Haskell represenation of a rectangle.+data HRect a+   = HRect+     { hRectTopLeft :: !(V2 a)+     , hRectSize    :: !(V2 a)+     } deriving (Foldable, Functor, Traversable, Show)++type family RectPoint (r :: * -> *) :: * -> *+type family RectSize  (r :: * -> *) :: * -> *++type instance RectPoint Rect = Point 2+type instance RectSize  Rect = Size++type instance RectPoint HRect = V2+type instance RectSize  HRect = V2++class IsRect (r :: * -> *) (depth :: *) where+    toRect   :: r depth -> Rect depth+    fromRect :: Rect depth -> r depth++    toRectIO :: r depth -> IO (Rect depth)+    toRectIO = pure . toRect++    rectTopLeft     :: r depth -> RectPoint r depth+    rectBottomRight :: r depth -> RectPoint r depth+    rectSize        :: r depth -> RectSize  r depth+    rectArea        :: r depth -> depth+    rectContains    :: RectPoint r depth -> r depth -> Bool++--------------------------------------------------------------------------------++instance (IsRect HRect a, Show a)+      => Show (Rect a) where+    showsPrec prec rect = showParen (prec >= 10) $+                              showString "toRect "+                            . showParen True (shows hr)+      where+        hr :: HRect a+        hr = fromRect rect++instance (ToJSON a) => ToJSON (HRect a) where+    toJSON hr = object [ "pos"  .= (x, y)+                       , "size" .= (w, h)+                       ]+      where+        V2 x y = hRectTopLeft hr+        V2 w h = hRectSize    hr++instance (FromJSON a) => FromJSON (HRect a) where+    parseJSON = withObject "HRect" $ \obj ->+                  HRect  <$> (uncurry V2 <$> obj .: "pos")+                         <*> (uncurry V2 <$> obj .: "size")++instance ( ToJSON a+         , IsRect HRect a+         )+      => ToJSON (Rect a) where+    toJSON = toJSON . (fromRect :: Rect a -> HRect a)++instance ( FromJSON a+         , IsRect HRect a+         )+      => FromJSON (Rect a) where+    parseJSON value = (toRect :: HRect a -> Rect a) <$> parseJSON value
+ src/OpenCV/Internal/Core/Types/Rect/TH.hs view
@@ -0,0 +1,171 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Rect.TH+  ( mkRectType+  ) where++import "base" Data.Monoid ( (<>) )+import "base" Foreign.Marshal.Utils ( toBool )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "linear" Linear.Vector ( (^+^) )+import "linear" Linear.V2 ( V2(..) )+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Core.Types.Size+import "this" OpenCV.Internal+import "this" OpenCV.Internal.Core.Types.Rect+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types++--------------------------------------------------------------------------------++mkRectType+    :: String -- ^ Rectangle type name, for both Haskell and C+    -> Name   -- ^ Depth type name in Haskell+    -> String -- ^ Depth type name in C+    -> String -- ^ Point type name in C+    -> String -- ^ Size type name in C+    -> Q [Dec]+mkRectType rTypeNameStr depthTypeName cDepthTypeStr cPointTypeStr cSizeTypeStr =+    fmap concat . sequence $+      [ (:[]) <$> rectTySynD+      , fromPtrDs+      , isRectOpenCVInstanceDs+      , isRectHaskellInstanceDs+      , mkPlacementNewInstance rTypeName+      ]+  where+    rTypeName :: Name+    rTypeName = mkName rTypeNameStr++    cRectTypeStr :: String+    cRectTypeStr = rTypeNameStr++    rTypeQ :: Q Type+    rTypeQ = conT rTypeName++    depthTypeQ :: Q Type+    depthTypeQ = conT depthTypeName++    rectTySynD :: Q Dec+    rectTySynD =+        tySynD rTypeName [] ([t|Rect|] `appT` depthTypeQ)++    fromPtrDs :: Q [Dec]+    fromPtrDs =+        [d|+        instance FromPtr $(rTypeQ) where+          fromPtr = objFromPtr Rect $ $(finalizerExpQ)+        |]+      where+        finalizerExpQ :: Q Exp+        finalizerExpQ = do+          ptr <- newName "ptr"+          lamE [varP ptr] $+            quoteExp CU.exp $+              "void { delete $(" <> cRectTypeStr <> " * " <> nameBase ptr <> ") }"++    isRectOpenCVInstanceDs :: Q [Dec]+    isRectOpenCVInstanceDs =+        [d|+        instance IsRect Rect $(depthTypeQ) where+          toRect   = id+          fromRect = id++          rectTopLeft     rect = unsafePerformIO $ fromPtr $ withPtr rect $ $(rectTopLeftExpQ)+          rectBottomRight rect = unsafePerformIO $ fromPtr $ withPtr rect $ $(rectBottomRightExpQ)+          rectSize        rect = unsafePerformIO $ fromPtr $ withPtr rect $ $(rectSizeExpQ)+          rectArea        rect = unsafePerformIO $ withPtr rect $ $(rectAreaExpQ)+          rectContains         = $(rectContainsExpQ)+        |]+      where+        rectTopLeftExpQ :: Q Exp+        rectTopLeftExpQ = do+          rectPtr <- newName "rectPtr"+          lamE [varP rectPtr] $ quoteExp CU.exp $+            cPointTypeStr <> " * { new " <> cPointTypeStr <> "($(" <> cRectTypeStr <> " * rectPtr)->tl()) }"++        rectBottomRightExpQ :: Q Exp+        rectBottomRightExpQ = do+          rectPtr <- newName "rectPtr"+          lamE [varP rectPtr] $ quoteExp CU.exp $+            cPointTypeStr <> " * { new " <> cPointTypeStr <> "($(" <> cRectTypeStr <> " * rectPtr)->br()) }"++        rectSizeExpQ :: Q Exp+        rectSizeExpQ = do+          rectPtr <- newName "rectPtr"+          lamE [varP rectPtr] $ quoteExp CU.exp $+            cSizeTypeStr <> " * { new " <> cSizeTypeStr <> "($(" <> cRectTypeStr <> " * rectPtr)->size()) }"++        rectAreaExpQ :: Q Exp+        rectAreaExpQ = do+          rectPtr <- newName "rectPtr"+          lamE [varP rectPtr] $ quoteExp CU.exp $+            cDepthTypeStr <> " { $(" <> cRectTypeStr <> " * rectPtr)->area() }"++        rectContainsExpQ :: Q Exp+        rectContainsExpQ = do+          point <- newName "point"+          rect  <- newName "rect"+          pointPtr <- newName "pointPtr"+          rectPtr  <- newName "rectPtr"++          lamE [varP point, varP rect]+            $ appE [e|toBool|]+            $ appE [e|unsafePerformIO|]+            $ appE ([e|withPtr|] `appE` ([e|toPoint|] `appE` varE point))+            $ lamE [varP pointPtr]+            $ appE ([e|withPtr|] `appE` (varE rect))+            $ lamE [varP rectPtr]+            $ quoteExp CU.exp+            $ "int { $(" <> cRectTypeStr <> " * rectPtr)->contains(*$(" <> cPointTypeStr <> " * pointPtr)) }"++    isRectHaskellInstanceDs :: Q [Dec]+    isRectHaskellInstanceDs =+        [d|+        instance IsRect HRect $(depthTypeQ) where+          toRect hr = unsafePerformIO $ toRectIO hr+          fromRect rect = HRect+                          { hRectTopLeft = fromPoint $ rectTopLeft rect+                          , hRectSize    = fromSize  $ rectSize    rect+                          }++          toRectIO = $(toRectIOExpQ)++          rectTopLeft     hr = hRectTopLeft hr+          rectBottomRight hr = hRectTopLeft hr ^+^ hRectSize hr+          rectSize        hr = hRectSize hr++          rectArea hr = let V2 w h = hRectSize hr+                        in w * h++          rectContains (V2 px py) (HRect (V2 rx ry) (V2 rw rh)) =+                 px >= rx && px < rx + rw+              && py >= ry && py < ry + rh+        |]+      where+        toRectIOExpQ :: Q Exp+        toRectIOExpQ = do+          x <- newName "x"+          y <- newName "y"+          w <- newName "w"+          h <- newName "h"+          lamE [conP 'HRect [conP 'V2 [varP x, varP y], conP 'V2 [varP w, varP h]]] $+            appE [e|fromPtr|] $+              quoteExp CU.exp $ concat+                [ cRectTypeStr <> " * { "+                , "new cv::Rect_<" <> cDepthTypeStr <> ">("+                , "$(" <> cDepthTypeStr <> " x), "+                , "$(" <> cDepthTypeStr <> " y), "+                , "$(" <> cDepthTypeStr <> " w), "+                , "$(" <> cDepthTypeStr <> " h)"+                , ")}"+                ]
+ src/OpenCV/Internal/Core/Types/Size.hs view
@@ -0,0 +1,46 @@+{-# language CPP #-}+{-# language ConstraintKinds #-}+{-# language MultiParamTypeClasses #-}+{-# language UndecidableInstances #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Size+  ( Size(..)+  , IsSize(..)+  ) where++import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "linear" Linear ( V2 )+import "this" OpenCV.Internal.C.Types++--------------------------------------------------------------------------------++newtype Size (depth :: *)+      = Size {unSize :: ForeignPtr (C'Size depth)}++type instance C (Size depth) = C'Size depth++instance WithPtr (Size depth) where+    withPtr = withForeignPtr . unSize++class IsSize (p :: * -> *) (depth :: *)  where+    toSize   :: p depth -> Size depth+    fromSize :: Size depth -> p depth++    toSizeIO :: p depth -> IO (Size depth)+    toSizeIO = pure . toSize++--------------------------------------------------------------------------------++instance (IsSize V2 a, Show a)+      => Show (Size a) where+    showsPrec prec size =+        showParen (prec >= 10)+        $ showString "toSize "+        . showParen True (shows v2)+      where+        v2 :: V2 a+        v2 = fromSize size
+ src/OpenCV/Internal/Core/Types/Size/TH.hs view
@@ -0,0 +1,167 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Size.TH+  ( mkSizeType+  ) where++import "base" Data.List ( intercalate )+import "base" Data.Monoid ( (<>) )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "linear" Linear ( V2(..) )+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Size+import "this" OpenCV.Internal++mkSizeType+    :: String  -- ^ Size type name, for both Haskell and C+    -> Name    -- ^ Depth type name in Haskell+    -> String  -- ^ Depth type name in C+    -> Q [Dec]+mkSizeType pTypeNameStr depthTypeName cDepthTypeStr =+      fmap concat . sequence $+        [ pure <$> sizeTySynD+        , fromPtrDs+        , isSizeOpenCVInstanceDs+        , isSizeHaskellInstanceDs+        , mkPlacementNewInstance pTypeName+        ]+  where+    pTypeName :: Name+    pTypeName = mkName pTypeNameStr++    cSizeTypeStr :: String+    cSizeTypeStr = pTypeNameStr++    cTemplateStr :: String+    cTemplateStr = "Size_"++    pTypeQ :: Q Type+    pTypeQ = conT pTypeName++    depthTypeQ :: Q Type+    depthTypeQ = conT depthTypeName++    sizeTySynD :: Q Dec+    sizeTySynD =+        tySynD pTypeName+               []+               ([t|Size|] `appT` depthTypeQ)++    fromPtrDs :: Q [Dec]+    fromPtrDs =+        [d|+        instance FromPtr $(pTypeQ) where+          fromPtr = objFromPtr Size $ $(finalizerExpQ)+        |]+      where+        finalizerExpQ :: Q Exp+        finalizerExpQ = do+          ptr <- newName "ptr"+          lamE [varP ptr] $+            quoteExp CU.exp $+              "void { delete $(" <> cSizeTypeStr <> " * " <> nameBase ptr <> ") }"++    isSizeOpenCVInstanceDs :: Q [Dec]+    isSizeOpenCVInstanceDs =+        [d|+        instance IsSize Size $(depthTypeQ) where+          toSize   = id+          toSizeIO = pure+          fromSize = id+        |]++    isSizeHaskellInstanceDs :: Q [Dec]+    isSizeHaskellInstanceDs =+        [d|+        instance IsSize V2 $(depthTypeQ) where+          toSize   = unsafePerformIO . toSizeIO+          toSizeIO = $(toSizeIOExpQ)+          fromSize = $(fromSizeExpQ)+        |]+      where+        toSizeIOExpQ :: Q Exp+        toSizeIOExpQ = do+            ns <- mapM newName fieldNames+            lamE [conP 'V2 $ map varP ns]+             $ appE [e|fromPtr|]+             $ quoteExp CU.exp+             $ inlineCStr ns+          where+            inlineCStr :: [Name] -> String+            inlineCStr ns = concat+                [ cSizeTypeStr+                , " * { new cv::" <> cTemplateStr+                , "<" <> cDepthTypeStr <> ">"+                , "(" <> intercalate ", " (map fieldQuote ns) <> ")"+                , " }"+                ]+              where+                fieldQuote :: Name -> String+                fieldQuote n = "$(" <> cDepthTypeStr <> " " <> nameBase n <> ")"++        fromSizeExpQ :: Q Exp+        fromSizeExpQ = do+            size     <- newName "size"+            sizePtr  <- newName "sizePtr"+            ptrNames <- mapM (newName . (<> "Ptr")) fieldNames+            withPtrNames size sizePtr ptrNames+          where+            withPtrNames :: Name -> Name -> [Name] -> Q Exp+            withPtrNames size sizePtr ptrNames =+                lamE [varP size]+                  $ appE [e|unsafePerformIO|]+                  $ withPtrVarsExpQ ptrNames+              where+                withPtrVarsExpQ :: [Name] -> Q Exp+                withPtrVarsExpQ = foldr (\p -> appE [e|alloca|] . lamE [varP p]) withAllocatedVars++                withAllocatedVars :: Q Exp+                withAllocatedVars =+                    appE ([e|withPtr|] `appE` varE size)+                      $ lamE [varP sizePtr]+                      $ doE+                        [ noBindS $ quoteExp CU.block inlineCStr+                        , noBindS extractExpQ+                        ]++                inlineCStr :: String+                inlineCStr = unlines $+                    concat+                      [ "void {"+                      , "const cv::" <> cTemplateStr+                      , "<" <> cDepthTypeStr <> ">"+                      , " & p = *$("+                      , cSizeTypeStr+                      , " * "+                      , nameBase sizePtr+                      , ");"+                      ]+                    : map ptrLine (zip fieldNames ptrNames)+                    <> ["}"]+                  where+                    ptrLine :: (String, Name) -> String+                    ptrLine (fieldName, ptrName) =+                        "*$(" <> cDepthTypeStr <> " * " <> nameBase ptrName <> ") = p." <> fieldName <> ";"++                extractExpQ :: Q Exp+                extractExpQ = foldl (\acc peekExp -> [e|(<*>)|] `appE` acc `appE` peekExp)+                                    ([e|pure V2|])+                                    peekExpQs+                  where+                    peekExpQs :: [Q Exp]+                    peekExpQs = map (\p -> [e|peek|] `appE` varE p) ptrNames++        fieldNames :: [String]+        fieldNames = ["width", "height"]
+ src/OpenCV/Internal/Core/Types/Vec.hs view
@@ -0,0 +1,74 @@+{-# language CPP #-}+{-# language MultiParamTypeClasses #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Vec+    ( Vec(..)+    , VecDim+    , IsVec(..)+    ) where++import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" GHC.TypeLits+import "linear" Linear ( V2, V3, V4 )+import "this" OpenCV.Internal.C.Types++--------------------------------------------------------------------------------++newtype Vec (dim :: Nat) (depth :: *)+      = Vec {unVec :: ForeignPtr (C'Vec dim depth)}++type instance C (Vec dim depth) = C'Vec dim depth++instance WithPtr (Vec dim depth) where+    withPtr = withForeignPtr . unVec++type family VecDim (v :: * -> *) :: Nat++type instance VecDim (Vec dim) = dim++type instance VecDim V2 = 2+type instance VecDim V3 = 3+type instance VecDim V4 = 4++class IsVec (v :: * -> *) (depth :: *)  where+    toVec   :: v depth -> Vec (VecDim v) depth+    fromVec :: Vec (VecDim v) depth -> v depth++    toVecIO :: v depth -> IO (Vec (VecDim v) depth)+    toVecIO = pure . toVec++--------------------------------------------------------------------------------++instance (IsVec V2 a, Show a)+      => Show (Vec 2 a) where+    showsPrec prec vec =+        showParen (prec >= 10)+        $ showString "toVec "+        . showParen True (shows v2)+      where+        v2 :: V2 a+        v2 = fromVec vec++instance (IsVec V3 a, Show a)+      => Show (Vec 3 a) where+    showsPrec prec vec =+        showParen (prec >= 10)+        $ showString "toVec "+        . showParen True (shows v3)+      where+        v3 :: V3 a+        v3 = fromVec vec++instance (IsVec V4 a, Show a)+      => Show (Vec 4 a) where+    showsPrec prec vec =+        showParen (prec >= 10)+        $ showString "toVec "+        . showParen True (shows v4)+      where+        v4 :: V4 a+        v4 = fromVec vec
+ src/OpenCV/Internal/Core/Types/Vec/TH.hs view
@@ -0,0 +1,188 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Core.Types.Vec.TH+  ( mkVecType+  ) where++import "base" Data.List ( intercalate )+import "base" Data.Monoid ( (<>) )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Storable ( peek )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import "linear" Linear ( V2(..), V3(..), V4(..) )+import "template-haskell" Language.Haskell.TH+import "template-haskell" Language.Haskell.TH.Quote ( quoteExp )+import "this" OpenCV.Internal.C.PlacementNew.TH ( mkPlacementNewInstance )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Vec+import "this" OpenCV.Internal++mkVecType+    :: String  -- ^ Vec type name, for both Haskell and C+    -> Integer -- ^ Vec dimension+    -> Name    -- ^ Depth type name in Haskell+    -> String  -- ^ Depth type name in C+    -> Q [Dec]+mkVecType vTypeNameStr dim depthTypeName cDepthTypeStr+    | dim < 2 || dim > 4 = fail $ "mkVecType: Unsupported dimension: " <> show dim+    | otherwise =+      fmap concat . sequence $+        [ pure <$> vecTySynD+        , fromPtrDs+        , isVecOpenCVInstanceDs+        , isVecHaskellInstanceDs+        , mkPlacementNewInstance vTypeName+        ]+  where+    vTypeName :: Name+    vTypeName = mkName vTypeNameStr++    cVecTypeStr :: String+    cVecTypeStr = vTypeNameStr++    vTypeQ :: Q Type+    vTypeQ = conT vTypeName++    depthTypeQ :: Q Type+    depthTypeQ = conT depthTypeName++    dimTypeQ :: Q Type+    dimTypeQ = litT (numTyLit dim)++    vecTySynD :: Q Dec+    vecTySynD =+        tySynD vTypeName+               []+               ([t|Vec|] `appT` dimTypeQ `appT` depthTypeQ)++    fromPtrDs :: Q [Dec]+    fromPtrDs =+        [d|+        instance FromPtr $(vTypeQ) where+          fromPtr = objFromPtr Vec $ $(finalizerExpQ)+        |]+      where+        finalizerExpQ :: Q Exp+        finalizerExpQ = do+          ptr <- newName "ptr"+          lamE [varP ptr] $+            quoteExp CU.exp $+              "void { delete $(" <> cVecTypeStr <> " * " <> nameBase ptr <> ") }"++    isVecOpenCVInstanceDs :: Q [Dec]+    isVecOpenCVInstanceDs =+        [d|+        instance IsVec (Vec $(dimTypeQ)) $(depthTypeQ) where+          toVec   = id+          toVecIO = pure+          fromVec = id+        |]++    isVecHaskellInstanceDs :: Q [Dec]+    isVecHaskellInstanceDs =+        let ix = fromInteger dim - 2+        in withLinear (linearTypeQs   !! ix)+                      (linearConNames !! ix)+      where+        linearTypeQs :: [Q Type]+        linearTypeQs = map conT [''V2, ''V3, ''V4]++        linearConNames :: [Name]+        linearConNames = ['V2, 'V3, 'V4]++        withLinear :: Q Type -> Name -> Q [Dec]+        withLinear lvTypeQ lvConName =+            [d|+            instance IsVec $(lvTypeQ) $(depthTypeQ) where+              toVec   = unsafePerformIO . toVecIO+              toVecIO = $(toVecIOExpQ)+              fromVec = $(fromVecExpQ)+            |]+          where+            toVecIOExpQ :: Q Exp+            toVecIOExpQ = do+                ns <- mapM newName elemNames+                lamE [conP lvConName $ map varP ns]+                 $ appE [e|fromPtr|]+                 $ quoteExp CU.exp+                 $ inlineCStr ns+              where+                inlineCStr :: [Name] -> String+                inlineCStr ns = concat+                    [ cVecTypeStr+                    , " * { new cv::Vec<"+                    , cDepthTypeStr+                    , ", "+                    , show dim+                    , ">(" <> intercalate ", " (map elemQuote ns) <> ")"+                    , " }"+                    ]+                  where+                    elemQuote :: Name -> String+                    elemQuote n = "$(" <> cDepthTypeStr <> " " <> nameBase n <> ")"++            fromVecExpQ :: Q Exp+            fromVecExpQ = do+                vec <- newName "vec"+                vecPtr <- newName "vecPtr"+                ptrNames <- mapM (newName . (<> "Ptr")) elemNames+                withPtrNames vec vecPtr ptrNames+              where+                withPtrNames :: Name -> Name -> [Name] -> Q Exp+                withPtrNames vec vecPtr ptrNames =+                    lamE [varP vec]+                      $ appE [e|unsafePerformIO|]+                      $ withPtrVarsExpQ ptrNames+                  where++                    withPtrVarsExpQ :: [Name] -> Q Exp+                    withPtrVarsExpQ = foldr (\p -> appE [e|alloca|] . lamE [varP p]) withAllocatedVars++                    withAllocatedVars :: Q Exp+                    withAllocatedVars =+                        appE ([e|withPtr|] `appE` varE vec)+                          $ lamE [varP vecPtr]+                          $ doE+                            [ noBindS $ quoteExp CU.block inlineCStr+                            , noBindS extractExpQ+                            ]++                    inlineCStr :: String+                    inlineCStr = unlines $+                        concat+                          [ "void {"+                          , "const cv::Vec<"+                          , cDepthTypeStr+                          , ", " <> show dim <> "> & p = *$("+                          , cVecTypeStr+                          , " * "+                          , nameBase vecPtr+                          , ");"+                          ]+                        : map ptrLine (zip [0..] ptrNames)+                        <> ["}"]+                      where+                        ptrLine :: (Int, Name) -> String+                        ptrLine (ix, ptrName) =+                            "*$(" <> cDepthTypeStr <> " * " <> nameBase ptrName <> ") = p[" <> show ix <> "];"++                    -- Applies the constructor to the values that are+                    -- read from the pointers.+                    extractExpQ :: Q Exp+                    extractExpQ = foldl (\acc peekExp -> [e|(<*>)|] `appE` acc `appE` peekExp)+                                        ([e|pure|] `appE` conE lvConName)+                                        peekExpQs+                      where+                        peekExpQs :: [Q Exp]+                        peekExpQs = map (\p -> [e|peek|] `appE` varE p) ptrNames++            elemNames :: [String]+            elemNames = take (fromInteger dim)+                             ["x", "y", "z", "w"]
+ src/OpenCV/Internal/Exception.cpp view
@@ -0,0 +1,18 @@++#include "opencv2/core.hpp"++using namespace cv;++extern "C" {+const char * inline_c_OpenCV_Internal_Exception_0_9c662f8b58a9de54c461812288a8567063b02b4d(Exception * cvExceptionPtr_inline_c_0) {+return ( cvExceptionPtr_inline_c_0->what() );+}++}++extern "C" {+void inline_c_OpenCV_Internal_Exception_1_2402dbf3aea4f7f79392b71ed42618962a22e9aa(Exception * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/Internal/Exception.hs view
@@ -0,0 +1,162 @@+{-# language CPP #-}+{-# language DeriveFunctor #-}+{-# language QuasiQuotes #-}+{-# language RankNTypes #-}+{-# language TemplateHaskell #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Exception+    ( -- * Exception type+      CvException(..)+    , CoerceMatError(..)+    , ExpectationError(..)+    , CvCppException++      -- * Handling C++ exceptions+    , handleCvException++      -- * Quasi quoters+    , cvExcept+    , cvExceptU++      -- * Monadic interface+    , CvExcept+    , CvExceptT+    , pureExcept++      -- * Promoting exceptions to errors+    , exceptError+    , exceptErrorIO+    , exceptErrorM+    , runCvExceptST++      -- * Unsafe stuff+    , unsafeCvExcept+    , unsafeWrapException+    ) where++import "base" Control.Monad.ST ( ST, runST )+import "base" Control.Exception ( Exception, mask_, throw, throwIO )+import "base" Control.Monad ( (<=<) )+import "base" Data.Functor.Identity+import "base" Data.Monoid ( (<>) )+import "base" Foreign.C.String ( peekCString )+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Ptr ( Ptr, nullPtr )+import "base" System.IO.Unsafe ( unsafePerformIO )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "template-haskell" Language.Haskell.TH.Quote ( QuasiQuoter, quoteExp )+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat.Depth+import "this" OpenCV.Internal ( objFromPtr )+import "transformers" Control.Monad.Trans.Except++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.using "namespace cv"+++--------------------------------------------------------------------------------+-- Exceptions+--------------------------------------------------------------------------------++data CvException+   = BindingException !CvCppException+   | CoerceMatError ![CoerceMatError]+     deriving Show++data CoerceMatError+   = ShapeError        !(ExpectationError Int)+   | SizeError    !Int !(ExpectationError Int)+   | ChannelError      !(ExpectationError Int)+   | DepthError        !(ExpectationError Depth)+     deriving Show++data ExpectationError a+   = ExpectationError+     { expectedValue :: !a+     , actualValue   :: !a+     } deriving (Show, Functor)++instance Exception CvException++newtype CvCppException = CvCppException { unCvCppException :: ForeignPtr (C CvCppException) }++type instance C CvCppException = C'CvCppException++instance WithPtr CvCppException where+    withPtr = withForeignPtr . unCvCppException++instance FromPtr CvCppException where+    fromPtr = objFromPtr CvCppException $ \ptr ->+                [CU.exp| void { delete $(Exception * ptr) }|]++instance Show CvCppException where+    show cvException = unsafePerformIO $+        withPtr cvException $ \cvExceptionPtr -> do+          charPtr <- [CU.exp| const char * { $(Exception * cvExceptionPtr)->what() } |]+          peekCString charPtr++handleCvException+    :: IO a+    -> IO (Ptr (C CvCppException))+    -> IO (Either CvException a)+handleCvException okAct act = mask_ $ do+    exceptionPtr <- act+    if exceptionPtr /= nullPtr+      then do cppErr <- fromPtr (pure exceptionPtr)+              pure $ Left $ BindingException cppErr+      else Right <$> okAct++cvExcept :: QuasiQuoter+cvExcept = C.block {quoteExp = \s -> quoteExp C.block $ cvExceptWrap s}++cvExceptU :: QuasiQuoter+cvExceptU = CU.block {quoteExp = \s -> quoteExp CU.block $ cvExceptWrap s}++cvExceptWrap :: String -> String+cvExceptWrap s = unlines+   [ "Exception * {"+   , "  try"+   , "  {   " <> s <> ""+   , "    return NULL;"+   , "  }"+   , "  catch (const cv::Exception & e)"+   , "  {"+   , "    return new cv::Exception(e);"+   , "  }"+   , "}"+   ]++type CvExcept    a = Except  CvException   a+type CvExceptT m a = ExceptT CvException m a++pureExcept :: (Applicative m) => CvExcept a -> CvExceptT m a+pureExcept = mapExceptT (pure . runIdentity)++exceptError :: CvExcept a -> a+exceptError = either throw id . runExcept++exceptErrorIO :: CvExceptT IO a -> IO a+exceptErrorIO = either throwIO pure <=< runExceptT++exceptErrorM :: (Monad m) => CvExceptT m a -> m a+exceptErrorM = either throw pure <=< runExceptT++runCvExceptST :: (forall s. CvExceptT (ST s) a) -> CvExcept a+runCvExceptST act = except $ runST $ runExceptT act++unsafeCvExcept :: CvExceptT IO a -> CvExcept a+unsafeCvExcept = mapExceptT (Identity . unsafePerformIO)++unsafeWrapException :: IO (Either CvException a) -> CvExcept a+unsafeWrapException = unsafeCvExcept . ExceptT
+ src/OpenCV/Internal/ImgCodecs.hsc view
@@ -0,0 +1,175 @@+{-# language CPP #-}+{-# language OverloadedLists #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.ImgCodecs+    ( ImreadMode(..)+    , marshalImreadMode+    , JpegParams(..)+    , defaultJpegParams+    , marshalJpegParams+    , PngStrategy(..)+    , marshalPngStrategy+    , PngParams(..)+    , defaultPngParams+    , marshalPngParams+    , OutputFormat(..)+    , marshalOutputFormat+    ) where++import "base" Data.Int+import "base" Data.Word+import "base" Foreign.C.Types+import "base" Foreign.Marshal.Utils ( fromBool )+import qualified "vector" Data.Vector.Storable as VS+++#include <stdint.h>+#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgcodecs.hpp"++#include "namespace.hpp"++data ImreadMode+   = ImreadUnchanged+   | ImreadGrayscale+   | ImreadColor+   | ImreadAnyDepth+   | ImreadAnyColor+   | ImreadLoadGdal+     deriving (Show)++#num IMREAD_UNCHANGED+#num IMREAD_GRAYSCALE+#num IMREAD_COLOR+#num IMREAD_ANYDEPTH+#num IMREAD_ANYCOLOR+#num IMREAD_LOAD_GDAL++marshalImreadMode :: ImreadMode -> Int32+marshalImreadMode = \case+    ImreadUnchanged -> c'IMREAD_UNCHANGED+    ImreadGrayscale -> c'IMREAD_GRAYSCALE+    ImreadColor     -> c'IMREAD_COLOR+    ImreadAnyDepth  -> c'IMREAD_ANYDEPTH+    ImreadAnyColor  -> c'IMREAD_ANYCOLOR+    ImreadLoadGdal  -> c'IMREAD_LOAD_GDAL++data JpegParams =+     JpegParams+     { jpegParamQuality         :: Int -- ^ \[0..100\]+     , jpegParamProgressive     :: Bool+     , jpegParamOptimize        :: Bool+     , jpegParamRestartInterval :: Word16+     , jpegParamLumaQuality     :: Int+     , jpegParamChromaQuality   :: Int+     } deriving Show++defaultJpegParams :: JpegParams+defaultJpegParams =+    JpegParams+    { jpegParamQuality         = 95+    , jpegParamProgressive     = False+    , jpegParamOptimize        = False+    , jpegParamRestartInterval = 0+    , jpegParamLumaQuality     = -1+    , jpegParamChromaQuality   = -1+    }++#num IMWRITE_JPEG_QUALITY+#num IMWRITE_JPEG_PROGRESSIVE+#num IMWRITE_JPEG_OPTIMIZE+#num IMWRITE_JPEG_RST_INTERVAL+#num IMWRITE_JPEG_LUMA_QUALITY+#num IMWRITE_JPEG_CHROMA_QUALITY++marshalJpegParams :: JpegParams -> VS.Vector CInt+marshalJpegParams params =+    [ c'IMWRITE_JPEG_QUALITY       , fromIntegral $ jpegParamQuality         params+    , c'IMWRITE_JPEG_PROGRESSIVE   , fromBool     $ jpegParamProgressive     params+    , c'IMWRITE_JPEG_OPTIMIZE      , fromBool     $ jpegParamOptimize        params+    , c'IMWRITE_JPEG_RST_INTERVAL  , fromIntegral $ jpegParamRestartInterval params+    , c'IMWRITE_JPEG_LUMA_QUALITY  , fromIntegral $ jpegParamLumaQuality     params+    , c'IMWRITE_JPEG_CHROMA_QUALITY, fromIntegral $ jpegParamChromaQuality   params+    ]++data PngStrategy+   = PngStrategyDefault+   | PngStrategyFiltered+   | PngStrategyHuffmanOnly+   | PngStrategyRLE+   | PngStrategyFixed+     deriving Show++#num IMWRITE_PNG_STRATEGY_DEFAULT+#num IMWRITE_PNG_STRATEGY_FILTERED+#num IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY+#num IMWRITE_PNG_STRATEGY_RLE+#num IMWRITE_PNG_STRATEGY_FIXED++marshalPngStrategy :: PngStrategy -> CInt+marshalPngStrategy = \case+   PngStrategyDefault     -> c'IMWRITE_PNG_STRATEGY_DEFAULT+   PngStrategyFiltered    -> c'IMWRITE_PNG_STRATEGY_FILTERED+   PngStrategyHuffmanOnly -> c'IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY+   PngStrategyRLE         -> c'IMWRITE_PNG_STRATEGY_RLE+   PngStrategyFixed       -> c'IMWRITE_PNG_STRATEGY_FIXED++data PngParams =+     PngParams+     { pngParamCompression :: Int+     , pngParamStrategy    :: PngStrategy+     , pngParamBinaryLevel :: Bool+     } deriving Show++defaultPngParams :: PngParams+defaultPngParams =+    PngParams+    { pngParamCompression = 3+    , pngParamStrategy    = PngStrategyDefault+    , pngParamBinaryLevel = False+    }++#num IMWRITE_PNG_COMPRESSION+#num IMWRITE_PNG_STRATEGY+#num IMWRITE_PNG_BILEVEL++marshalPngParams :: PngParams -> VS.Vector CInt+marshalPngParams params =+    [ c'IMWRITE_PNG_COMPRESSION, fromIntegral        $ pngParamCompression params+    , c'IMWRITE_PNG_STRATEGY   , marshalPngStrategy $ pngParamStrategy    params+    , c'IMWRITE_PNG_BILEVEL    , fromBool            $ pngParamBinaryLevel params+    ]++data OutputFormat+   = OutputBmp+   | OutputExr+   | OutputHdr Bool -- ^ Compression (run length encoding)+   | OutputJpeg JpegParams+   | OutputJpeg2000+   | OutputPng PngParams+   | OutputPxm Bool -- ^ Binary+   | OutputSunras+   | OutputTiff+   | OutputWebP Int -- ^ Quality [1..100], > 100 == lossless+     deriving Show++#num IMWRITE_PXM_BINARY+#num IMWRITE_WEBP_QUALITY++marshalOutputFormat :: OutputFormat -> (String, VS.Vector CInt)+marshalOutputFormat = \case+    OutputBmp          -> (".bmp" , [])+    OutputExr          -> (".exr" , [])+    OutputHdr comp     -> (".hdr" , [fromBool comp])+    OutputJpeg params  -> (".jpeg", marshalJpegParams params)+    OutputJpeg2000     -> (".jp2" , [])+    OutputPng params   -> (".png" , marshalPngParams params)+    OutputPxm binary   -> (".pxm" , [c'IMWRITE_PXM_BINARY, fromBool binary])+    OutputSunras       -> (".sr"  , [])+    OutputTiff         -> (".tiff", [])+    OutputWebP quality -> (".webp", [c'IMWRITE_WEBP_QUALITY, fromIntegral quality])
+ src/OpenCV/Internal/ImgProc/MiscImgTransform.hsc view
@@ -0,0 +1,302 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.ImgProc.MiscImgTransform where++import "base" Data.Bits+import "base" Data.Int+import "base" Foreign.C.Types+import "linear" Linear.V2 ( V2(..) )+import "this" OpenCV.Core.Types.Rect++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"++--------------------------------------------------------------------------------++data ThreshType+   = Thresh_Binary    !Double+   | Thresh_BinaryInv !Double+   | Thresh_Truncate+   | Thresh_ToZero+   | Thresh_ToZeroInv+     deriving (Show, Eq)++#num THRESH_BINARY+#num THRESH_BINARY_INV+#num THRESH_TRUNC+#num THRESH_TOZERO+#num THRESH_TOZERO_INV++marshalThreshType :: ThreshType -> (Int32, CDouble)+marshalThreshType = \case+    Thresh_Binary    maxVal -> (c'THRESH_BINARY    , realToFrac maxVal)+    Thresh_BinaryInv maxVal -> (c'THRESH_BINARY_INV, realToFrac maxVal)+    Thresh_Truncate         -> (c'THRESH_TRUNC     , 0)+    Thresh_ToZero           -> (c'THRESH_TOZERO    , 0)+    Thresh_ToZeroInv        -> (c'THRESH_TOZERO_INV, 0)++data ThreshValue+   = ThreshVal_Abs !Double+   | ThreshVal_Otsu+   | ThreshVal_Triangle+     deriving (Show, Eq)++#num THRESH_OTSU+#num THRESH_TRIANGLE++marshalThreshValue :: ThreshValue -> (Int32, CDouble)+marshalThreshValue = \case+    ThreshVal_Abs val  -> (0                , realToFrac val)+    ThreshVal_Otsu     -> (c'THRESH_OTSU    , 0)+    ThreshVal_Triangle -> (c'THRESH_TRIANGLE, 0)++#num FLOODFILL_FIXED_RANGE+#num FLOODFILL_MASK_ONLY++--------------------------------------------------------------------------------++data GrabCutOperationMode+    = GrabCut_InitWithRect (Rect Int32)+        -- ^ Initialize the state and the mask using the provided rectangle. After that, run iterCount iterations of the algorithm.+        -- The rectangle represents a ROI containing a segmented object. The pixels outside of the ROI are marked as “obvious background”.+    | GrabCut_InitWithMask+        -- ^ Initialize the state using the provided mask.+    | GrabCut_InitWithRectAndMask (Rect Int32)+        -- ^ Combination of 'GCInitWithRect' and 'GCInitWithMask'. All the pixels outside of the ROI are automatically initialized with GC_BGD.+    | GrabCut_Eval+        -- ^ Just resume the algorithm.+      deriving (Show)++#num GC_INIT_WITH_RECT+#num GC_INIT_WITH_MASK+#num GC_EVAL++marshalGrabCutOperationMode :: GrabCutOperationMode -> Int32+marshalGrabCutOperationMode = \case+    GrabCut_InitWithRect _        -> c'GC_INIT_WITH_RECT+    GrabCut_InitWithMask          -> c'GC_INIT_WITH_MASK+    GrabCut_InitWithRectAndMask _ -> c'GC_INIT_WITH_RECT .|. c'GC_INIT_WITH_MASK+    GrabCut_Eval                  -> c'GC_EVAL++marshalGrabCutOperationModeRect :: GrabCutOperationMode -> Rect Int32+marshalGrabCutOperationModeRect = \case+    GrabCut_InitWithRect r        -> r+    GrabCut_InitWithMask          -> emptyRect+    GrabCut_InitWithRectAndMask r -> r+    GrabCut_Eval                  -> emptyRect+  where+    emptyRect = toRect (HRect { hRectTopLeft = V2 0 0, hRectSize = V2 0 0 })++--------------------------------------------------------------------------------++#num COLOR_BGR2BGRA+#num COLOR_RGB2RGBA+#num COLOR_BGRA2BGR+#num COLOR_RGBA2RGB+#num COLOR_BGR2RGBA+#num COLOR_RGB2BGRA+#num COLOR_RGBA2BGR+#num COLOR_BGRA2RGB+#num COLOR_BGR2RGB+#num COLOR_RGB2BGR+#num COLOR_BGRA2RGBA+#num COLOR_RGBA2BGRA+#num COLOR_BGR2GRAY+#num COLOR_RGB2GRAY+#num COLOR_GRAY2BGR+#num COLOR_GRAY2RGB+#num COLOR_GRAY2BGRA+#num COLOR_GRAY2RGBA+#num COLOR_BGRA2GRAY+#num COLOR_RGBA2GRAY+#num COLOR_BGR2BGR565+#num COLOR_RGB2BGR565+#num COLOR_BGR5652BGR+#num COLOR_BGR5652RGB+#num COLOR_BGRA2BGR565+#num COLOR_RGBA2BGR565+#num COLOR_BGR5652BGRA+#num COLOR_BGR5652RGBA+#num COLOR_GRAY2BGR565+#num COLOR_BGR5652GRAY+#num COLOR_BGR2BGR555+#num COLOR_RGB2BGR555+#num COLOR_BGR5552BGR+#num COLOR_BGR5552RGB+#num COLOR_BGRA2BGR555+#num COLOR_RGBA2BGR555+#num COLOR_BGR5552BGRA+#num COLOR_BGR5552RGBA+#num COLOR_GRAY2BGR555+#num COLOR_BGR5552GRAY+#num COLOR_BGR2XYZ+#num COLOR_RGB2XYZ+#num COLOR_XYZ2BGR+#num COLOR_XYZ2RGB+#num COLOR_BGR2YCrCb+#num COLOR_RGB2YCrCb+#num COLOR_YCrCb2BGR+#num COLOR_YCrCb2RGB+#num COLOR_BGR2HSV+#num COLOR_RGB2HSV+#num COLOR_BGR2Lab+#num COLOR_RGB2Lab+#num COLOR_BGR2Luv+#num COLOR_RGB2Luv+#num COLOR_BGR2HLS+#num COLOR_RGB2HLS+#num COLOR_HSV2BGR+#num COLOR_HSV2RGB+#num COLOR_Lab2BGR+#num COLOR_Lab2RGB+#num COLOR_Luv2BGR+#num COLOR_Luv2RGB+#num COLOR_HLS2BGR+#num COLOR_HLS2RGB+#num COLOR_BGR2HSV_FULL+#num COLOR_RGB2HSV_FULL+#num COLOR_BGR2HLS_FULL+#num COLOR_RGB2HLS_FULL+#num COLOR_HSV2BGR_FULL+#num COLOR_HSV2RGB_FULL+#num COLOR_HLS2BGR_FULL+#num COLOR_HLS2RGB_FULL+#num COLOR_LBGR2Lab+#num COLOR_LRGB2Lab+#num COLOR_LBGR2Luv+#num COLOR_LRGB2Luv+#num COLOR_Lab2LBGR+#num COLOR_Lab2LRGB+#num COLOR_Luv2LBGR+#num COLOR_Luv2LRGB+#num COLOR_BGR2YUV+#num COLOR_RGB2YUV+#num COLOR_YUV2BGR+#num COLOR_YUV2RGB+#num COLOR_YUV2RGB_NV12+#num COLOR_YUV2BGR_NV12+#num COLOR_YUV2RGB_NV21+#num COLOR_YUV2BGR_NV21+#num COLOR_YUV420sp2RGB+#num COLOR_YUV420sp2BGR+#num COLOR_YUV2RGBA_NV12+#num COLOR_YUV2BGRA_NV12+#num COLOR_YUV2RGBA_NV21+#num COLOR_YUV2BGRA_NV21+#num COLOR_YUV420sp2RGBA+#num COLOR_YUV420sp2BGRA+#num COLOR_YUV2RGB_YV12+#num COLOR_YUV2BGR_YV12+#num COLOR_YUV2RGB_IYUV+#num COLOR_YUV2BGR_IYUV+#num COLOR_YUV2RGB_I420+#num COLOR_YUV2BGR_I420+#num COLOR_YUV420p2RGB+#num COLOR_YUV420p2BGR+#num COLOR_YUV2RGBA_YV12+#num COLOR_YUV2BGRA_YV12+#num COLOR_YUV2RGBA_IYUV+#num COLOR_YUV2BGRA_IYUV+#num COLOR_YUV2RGBA_I420+#num COLOR_YUV2BGRA_I420+#num COLOR_YUV420p2RGBA+#num COLOR_YUV420p2BGRA+#num COLOR_YUV2GRAY_420+#num COLOR_YUV2GRAY_NV21+#num COLOR_YUV2GRAY_NV12+#num COLOR_YUV2GRAY_YV12+#num COLOR_YUV2GRAY_IYUV+#num COLOR_YUV2GRAY_I420+#num COLOR_YUV420sp2GRAY+#num COLOR_YUV420p2GRAY+#num COLOR_YUV2RGB_UYVY+#num COLOR_YUV2BGR_UYVY+-- #num COLOR_YUV2RGB_VYUY+-- #num COLOR_YUV2BGR_VYUY+#num COLOR_YUV2RGB_Y422+#num COLOR_YUV2BGR_Y422+#num COLOR_YUV2RGB_UYNV+#num COLOR_YUV2BGR_UYNV+#num COLOR_YUV2RGBA_UYVY+#num COLOR_YUV2BGRA_UYVY+-- #num COLOR_YUV2RGBA_VYUY+-- #num COLOR_YUV2BGRA_VYUY+#num COLOR_YUV2RGBA_Y422+#num COLOR_YUV2BGRA_Y422+#num COLOR_YUV2RGBA_UYNV+#num COLOR_YUV2BGRA_UYNV+#num COLOR_YUV2RGB_YUY2+#num COLOR_YUV2BGR_YUY2+#num COLOR_YUV2RGB_YVYU+#num COLOR_YUV2BGR_YVYU+#num COLOR_YUV2RGB_YUYV+#num COLOR_YUV2BGR_YUYV+#num COLOR_YUV2RGB_YUNV+#num COLOR_YUV2BGR_YUNV+#num COLOR_YUV2RGBA_YUY2+#num COLOR_YUV2BGRA_YUY2+#num COLOR_YUV2RGBA_YVYU+#num COLOR_YUV2BGRA_YVYU+#num COLOR_YUV2RGBA_YUYV+#num COLOR_YUV2BGRA_YUYV+#num COLOR_YUV2RGBA_YUNV+#num COLOR_YUV2BGRA_YUNV+#num COLOR_YUV2GRAY_UYVY+#num COLOR_YUV2GRAY_YUY2+-- #num CV_YUV2GRAY_VYUY+#num COLOR_YUV2GRAY_Y422+#num COLOR_YUV2GRAY_UYNV+#num COLOR_YUV2GRAY_YVYU+#num COLOR_YUV2GRAY_YUYV+#num COLOR_YUV2GRAY_YUNV+#num COLOR_RGBA2mRGBA+#num COLOR_mRGBA2RGBA+#num COLOR_RGB2YUV_I420+#num COLOR_BGR2YUV_I420+#num COLOR_RGB2YUV_IYUV+#num COLOR_BGR2YUV_IYUV+#num COLOR_RGBA2YUV_I420+#num COLOR_BGRA2YUV_I420+#num COLOR_RGBA2YUV_IYUV+#num COLOR_BGRA2YUV_IYUV+#num COLOR_RGB2YUV_YV12+#num COLOR_BGR2YUV_YV12+#num COLOR_RGBA2YUV_YV12+#num COLOR_BGRA2YUV_YV12+#num COLOR_BayerBG2BGR+#num COLOR_BayerGB2BGR+#num COLOR_BayerRG2BGR+#num COLOR_BayerGR2BGR+#num COLOR_BayerBG2RGB+#num COLOR_BayerGB2RGB+#num COLOR_BayerRG2RGB+#num COLOR_BayerGR2RGB+#num COLOR_BayerBG2GRAY+#num COLOR_BayerGB2GRAY+#num COLOR_BayerRG2GRAY+#num COLOR_BayerGR2GRAY+#num COLOR_BayerBG2BGR_VNG+#num COLOR_BayerGB2BGR_VNG+#num COLOR_BayerRG2BGR_VNG+#num COLOR_BayerGR2BGR_VNG+#num COLOR_BayerBG2RGB_VNG+#num COLOR_BayerGB2RGB_VNG+#num COLOR_BayerRG2RGB_VNG+#num COLOR_BayerGR2RGB_VNG+#num COLOR_BayerBG2BGR_EA+#num COLOR_BayerGB2BGR_EA+#num COLOR_BayerRG2BGR_EA+#num COLOR_BayerGR2BGR_EA+#num COLOR_BayerBG2RGB_EA+#num COLOR_BayerGB2RGB_EA+#num COLOR_BayerRG2RGB_EA+#num COLOR_BayerGR2RGB_EA
+ src/OpenCV/Internal/ImgProc/MiscImgTransform/ColorCodes.hs view
@@ -0,0 +1,753 @@+{-# language CPP #-}+{-# language MultiParamTypeClasses #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.Internal.ImgProc.MiscImgTransform.ColorCodes where++import "base" Data.Int ( Int32 )+import "base" Data.Proxy ( Proxy(..) )+import "base" Data.Word+import "base" GHC.TypeLits+import "this" OpenCV.Internal.ImgProc.MiscImgTransform+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++{- | Valid color conversions described by the following graph:++<<doc/color_conversions.png>>+-}+class ColorConversion (fromColor :: ColorCode) (toColor :: ColorCode) where+    colorConversionCode :: Proxy fromColor -> Proxy toColor -> Int32++-- | Names of color encodings+data ColorCode+    = BayerBG   -- ^ ('bayerBG') Bayer pattern with BG in the second row, second and third column+    | BayerGB   -- ^ ('bayerGB') Bayer pattern with GB in the second row, second and third column+    | BayerGR   -- ^ ('bayerGR') Bayer pattern with GR in the second row, second and third column+    | BayerRG   -- ^ ('bayerRG') Bayer pattern with RG in the second row, second and third column++    | BGR       -- ^ ('bgr') 24 bit RGB color space with channels: (B8:G8:R8)+    | BGR555    -- ^ ('bgr555') 15 bit RGB color space+    | BGR565    -- ^ ('bgr565') 16 bit RGB color space++    | BGRA      -- ^ ('bgra') 32 bit RGBA color space with channels: (B8:G8:R8:A8)+    | BGRA_I420 -- ^ ('bgra_I420')+    | BGRA_IYUV -- ^ ('bgra_IYUV')+    | BGRA_NV12 -- ^ ('bgra_NV12')+    | BGRA_NV21 -- ^ ('bgra_NV21')+    | BGRA_UYNV -- ^ ('bgra_UYNV')+    | BGRA_UYVY -- ^ ('bgra_UYVY')+    | BGRA_Y422 -- ^ ('bgra_Y422')+    | BGRA_YUNV -- ^ ('bgra_YUNV')+    | BGRA_YUY2 -- ^ ('bgra_YUY2')+    | BGRA_YUYV -- ^ ('bgra_YUYV')+    | BGRA_YV12 -- ^ ('bgra_YV12')+    | BGRA_YVYU -- ^ ('bgra_YVYU')++    | BGR_EA    -- ^ ('bgr_EA') Edge-Aware+    | BGR_FULL  -- ^ ('bgr_FULL')+    | BGR_I420  -- ^ ('bgr_I420')+    | BGR_IYUV  -- ^ ('bgr_IYUV')+    | BGR_NV12  -- ^ ('bgr_NV12')+    | BGR_NV21  -- ^ ('bgr_NV21')+    | BGR_UYNV  -- ^ ('bgr_UYNV')+    | BGR_UYVY  -- ^ ('bgr_UYVY')+    | BGR_VNG   -- ^ ('bgr_VNG')+    | BGR_Y422  -- ^ ('bgr_Y422')+    | BGR_YUNV  -- ^ ('bgr_YUNV')+    | BGR_YUY2  -- ^ ('bgr_YUY2')+    | BGR_YUYV  -- ^ ('bgr_YUYV')+    | BGR_YV12  -- ^ ('bgr_YV12')+    | BGR_YVYU  -- ^ ('bgr_YVYU')++    | GRAY      -- ^ ('gray') 8 bit single channel color space+    | GRAY_420  -- ^ ('gray_420')+    | GRAY_I420 -- ^ ('gray_I420')+    | GRAY_IYUV -- ^ ('gray_IYUV')+    | GRAY_NV12 -- ^ ('gray_NV12')+    | GRAY_NV21 -- ^ ('gray_NV21')+    | GRAY_UYNV -- ^ ('gray_UYNV')+    | GRAY_UYVY -- ^ ('gray_UYVY')+    | GRAY_Y422 -- ^ ('gray_Y422')+    | GRAY_YUNV -- ^ ('gray_YUNV')+    | GRAY_YUY2 -- ^ ('gray_YUY2')+    | GRAY_YUYV -- ^ ('gray_YUYV')+    | GRAY_YV12 -- ^ ('gray_YV12')+    | GRAY_YVYU -- ^ ('gray_YVYU')++    | HLS       -- ^ ('hls')+    | HLS_FULL  -- ^ ('hls_FULL')+    | HSV       -- ^ ('hsv')+    | HSV_FULL  -- ^ ('hsv_FULL')+    | Lab       -- ^ ('lab')+    | LBGR      -- ^ ('lbgr')+    | LRGB      -- ^ ('lrgb')+    | Luv       -- ^ ('luv')+    | MRGBA     -- ^ ('mrgba')+    | RGB       -- ^ ('rgb') 24 bit RGB color space with channels: (R8:G8:B8)++    | RGBA      -- ^ ('rgba')+    | RGBA_I420 -- ^ ('rgba_I420')+    | RGBA_IYUV -- ^ ('rgba_IYUV')+    | RGBA_NV12 -- ^ ('rgba_NV12')+    | RGBA_NV21 -- ^ ('rgba_NV21')+    | RGBA_UYNV -- ^ ('rgba_UYNV')+    | RGBA_UYVY -- ^ ('rgba_UYVY')+    | RGBA_Y422 -- ^ ('rgba_Y422')+    | RGBA_YUNV -- ^ ('rgba_YUNV')+    | RGBA_YUY2 -- ^ ('rgba_YUY2')+    | RGBA_YUYV -- ^ ('rgba_YUYV')+    | RGBA_YV12 -- ^ ('rgba_YV12')+    | RGBA_YVYU -- ^ ('rgba_YVYU')++    | RGB_EA    -- ^ ('rgb_EA') Edge-Aware+    | RGB_FULL  -- ^ ('rgb_FULL')+    | RGB_I420  -- ^ ('rgb_I420')+    | RGB_IYUV  -- ^ ('rgb_IYUV')+    | RGB_NV12  -- ^ ('rgb_NV12')+    | RGB_NV21  -- ^ ('rgb_NV21')+    | RGB_UYNV  -- ^ ('rgb_UYNV')+    | RGB_UYVY  -- ^ ('rgb_UYVY')+    | RGB_VNG   -- ^ ('rgb_VNG')+    | RGB_Y422  -- ^ ('rgb_Y422')+    | RGB_YUNV  -- ^ ('rgb_YUNV')+    | RGB_YUY2  -- ^ ('rgb_YUY2')+    | RGB_YUYV  -- ^ ('rgb_YUYV')+    | RGB_YV12  -- ^ ('rgb_YV12')+    | RGB_YVYU  -- ^ ('rgb_YVYU')++    | XYZ       -- ^ ('xyz')+    | YCrCb     -- ^ ('yCrCb')++    | YUV       -- ^ ('yuv')+    | YUV420p   -- ^ ('yuv420p')+    | YUV420sp  -- ^ ('yuv420sp')+    | YUV_I420  -- ^ ('yuv_I420')+    | YUV_IYUV  -- ^ ('yuv_IYUV')+    | YUV_YV12  -- ^ ('yuv_YV12')++--------------------------------------------------------------------------------++bayerBG    :: Proxy 'BayerBG  ; bayerBG    = Proxy+bayerGB    :: Proxy 'BayerGB  ; bayerGB    = Proxy+bayerGR    :: Proxy 'BayerGR  ; bayerGR    = Proxy+bayerRG    :: Proxy 'BayerRG  ; bayerRG    = Proxy+bgr        :: Proxy 'BGR      ; bgr        = Proxy+bgr555     :: Proxy 'BGR555   ; bgr555     = Proxy+bgr565     :: Proxy 'BGR565   ; bgr565     = Proxy+bgra       :: Proxy 'BGRA     ; bgra       = Proxy+bgra_I420  :: Proxy 'BGRA_I420; bgra_I420  = Proxy+bgra_IYUV  :: Proxy 'BGRA_IYUV; bgra_IYUV  = Proxy+bgra_NV12  :: Proxy 'BGRA_NV12; bgra_NV12  = Proxy+bgra_NV21  :: Proxy 'BGRA_NV21; bgra_NV21  = Proxy+bgra_UYNV  :: Proxy 'BGRA_UYNV; bgra_UYNV  = Proxy+bgra_UYVY  :: Proxy 'BGRA_UYVY; bgra_UYVY  = Proxy+bgra_Y422  :: Proxy 'BGRA_Y422; bgra_Y422  = Proxy+bgra_YUNV  :: Proxy 'BGRA_YUNV; bgra_YUNV  = Proxy+bgra_YUY2  :: Proxy 'BGRA_YUY2; bgra_YUY2  = Proxy+bgra_YUYV  :: Proxy 'BGRA_YUYV; bgra_YUYV  = Proxy+bgra_YV12  :: Proxy 'BGRA_YV12; bgra_YV12  = Proxy+bgra_YVYU  :: Proxy 'BGRA_YVYU; bgra_YVYU  = Proxy+bgr_EA     :: Proxy 'BGR_EA   ; bgr_EA     = Proxy+bgr_FULL   :: Proxy 'BGR_FULL ; bgr_FULL   = Proxy+bgr_I420   :: Proxy 'BGR_I420 ; bgr_I420   = Proxy+bgr_IYUV   :: Proxy 'BGR_IYUV ; bgr_IYUV   = Proxy+bgr_NV12   :: Proxy 'BGR_NV12 ; bgr_NV12   = Proxy+bgr_NV21   :: Proxy 'BGR_NV21 ; bgr_NV21   = Proxy+bgr_UYNV   :: Proxy 'BGR_UYNV ; bgr_UYNV   = Proxy+bgr_UYVY   :: Proxy 'BGR_UYVY ; bgr_UYVY   = Proxy+bgr_VNG    :: Proxy 'BGR_VNG  ; bgr_VNG    = Proxy+bgr_Y422   :: Proxy 'BGR_Y422 ; bgr_Y422   = Proxy+bgr_YUNV   :: Proxy 'BGR_YUNV ; bgr_YUNV   = Proxy+bgr_YUY2   :: Proxy 'BGR_YUY2 ; bgr_YUY2   = Proxy+bgr_YUYV   :: Proxy 'BGR_YUYV ; bgr_YUYV   = Proxy+bgr_YV12   :: Proxy 'BGR_YV12 ; bgr_YV12   = Proxy+bgr_YVYU   :: Proxy 'BGR_YVYU ; bgr_YVYU   = Proxy+gray       :: Proxy 'GRAY     ; gray       = Proxy+gray_420   :: Proxy 'GRAY_420 ; gray_420   = Proxy+gray_I420  :: Proxy 'GRAY_I420; gray_I420  = Proxy+gray_IYUV  :: Proxy 'GRAY_IYUV; gray_IYUV  = Proxy+gray_NV12  :: Proxy 'GRAY_NV12; gray_NV12  = Proxy+gray_NV21  :: Proxy 'GRAY_NV21; gray_NV21  = Proxy+gray_UYNV  :: Proxy 'GRAY_UYNV; gray_UYNV  = Proxy+gray_UYVY  :: Proxy 'GRAY_UYVY; gray_UYVY  = Proxy+gray_Y422  :: Proxy 'GRAY_Y422; gray_Y422  = Proxy+gray_YUNV  :: Proxy 'GRAY_YUNV; gray_YUNV  = Proxy+gray_YUY2  :: Proxy 'GRAY_YUY2; gray_YUY2  = Proxy+gray_YUYV  :: Proxy 'GRAY_YUYV; gray_YUYV  = Proxy+gray_YV12  :: Proxy 'GRAY_YV12; gray_YV12  = Proxy+gray_YVYU  :: Proxy 'GRAY_YVYU; gray_YVYU  = Proxy+hls        :: Proxy 'HLS      ; hls        = Proxy+hls_FULL   :: Proxy 'HLS_FULL ; hls_FULL   = Proxy+hsv        :: Proxy 'HSV      ; hsv        = Proxy+hsv_FULL   :: Proxy 'HSV_FULL ; hsv_FULL   = Proxy+lab        :: Proxy 'Lab      ; lab        = Proxy+lbgr       :: Proxy 'LBGR     ; lbgr       = Proxy+lrgb       :: Proxy 'LRGB     ; lrgb       = Proxy+luv        :: Proxy 'Luv      ; luv        = Proxy+mrgba      :: Proxy 'MRGBA    ; mrgba      = Proxy+rgb        :: Proxy 'RGB      ; rgb        = Proxy+rgba       :: Proxy 'RGBA     ; rgba       = Proxy+rgba_I420  :: Proxy 'RGBA_I420; rgba_I420  = Proxy+rgba_IYUV  :: Proxy 'RGBA_IYUV; rgba_IYUV  = Proxy+rgba_NV12  :: Proxy 'RGBA_NV12; rgba_NV12  = Proxy+rgba_NV21  :: Proxy 'RGBA_NV21; rgba_NV21  = Proxy+rgba_UYNV  :: Proxy 'RGBA_UYNV; rgba_UYNV  = Proxy+rgba_UYVY  :: Proxy 'RGBA_UYVY; rgba_UYVY  = Proxy+rgba_Y422  :: Proxy 'RGBA_Y422; rgba_Y422  = Proxy+rgba_YUNV  :: Proxy 'RGBA_YUNV; rgba_YUNV  = Proxy+rgba_YUY2  :: Proxy 'RGBA_YUY2; rgba_YUY2  = Proxy+rgba_YUYV  :: Proxy 'RGBA_YUYV; rgba_YUYV  = Proxy+rgba_YV12  :: Proxy 'RGBA_YV12; rgba_YV12  = Proxy+rgba_YVYU  :: Proxy 'RGBA_YVYU; rgba_YVYU  = Proxy+rgb_EA     :: Proxy 'RGB_EA   ; rgb_EA     = Proxy+rgb_FULL   :: Proxy 'RGB_FULL ; rgb_FULL   = Proxy+rgb_I420   :: Proxy 'RGB_I420 ; rgb_I420   = Proxy+rgb_IYUV   :: Proxy 'RGB_IYUV ; rgb_IYUV   = Proxy+rgb_NV12   :: Proxy 'RGB_NV12 ; rgb_NV12   = Proxy+rgb_NV21   :: Proxy 'RGB_NV21 ; rgb_NV21   = Proxy+rgb_UYNV   :: Proxy 'RGB_UYNV ; rgb_UYNV   = Proxy+rgb_UYVY   :: Proxy 'RGB_UYVY ; rgb_UYVY   = Proxy+rgb_VNG    :: Proxy 'RGB_VNG  ; rgb_VNG    = Proxy+rgb_Y422   :: Proxy 'RGB_Y422 ; rgb_Y422   = Proxy+rgb_YUNV   :: Proxy 'RGB_YUNV ; rgb_YUNV   = Proxy+rgb_YUY2   :: Proxy 'RGB_YUY2 ; rgb_YUY2   = Proxy+rgb_YUYV   :: Proxy 'RGB_YUYV ; rgb_YUYV   = Proxy+rgb_YV12   :: Proxy 'RGB_YV12 ; rgb_YV12   = Proxy+rgb_YVYU   :: Proxy 'RGB_YVYU ; rgb_YVYU   = Proxy+xyz        :: Proxy 'XYZ      ; xyz        = Proxy+yCrCb      :: Proxy 'YCrCb    ; yCrCb      = Proxy+yuv        :: Proxy 'YUV      ; yuv        = Proxy+yuv420p    :: Proxy 'YUV420p  ; yuv420p    = Proxy+yuv420sp   :: Proxy 'YUV420sp ; yuv420sp   = Proxy+yuv_I420   :: Proxy 'YUV_I420 ; yuv_I420   = Proxy+yuv_IYUV   :: Proxy 'YUV_IYUV ; yuv_IYUV   = Proxy+yuv_YV12   :: Proxy 'YUV_YV12 ; yuv_YV12   = Proxy++--------------------------------------------------------------------------------++instance ColorConversion 'BGR      'BGRA      where colorConversionCode _ _ = c'COLOR_BGR2BGRA+instance ColorConversion 'RGB      'RGBA      where colorConversionCode _ _ = c'COLOR_RGB2RGBA+instance ColorConversion 'BGRA     'BGR       where colorConversionCode _ _ = c'COLOR_BGRA2BGR+instance ColorConversion 'RGBA     'RGB       where colorConversionCode _ _ = c'COLOR_RGBA2RGB+instance ColorConversion 'BGR      'RGBA      where colorConversionCode _ _ = c'COLOR_BGR2RGBA+instance ColorConversion 'RGB      'BGRA      where colorConversionCode _ _ = c'COLOR_RGB2BGRA+instance ColorConversion 'RGBA     'BGR       where colorConversionCode _ _ = c'COLOR_RGBA2BGR+instance ColorConversion 'BGRA     'RGB       where colorConversionCode _ _ = c'COLOR_BGRA2RGB+instance ColorConversion 'BGR      'RGB       where colorConversionCode _ _ = c'COLOR_BGR2RGB+instance ColorConversion 'RGB      'BGR       where colorConversionCode _ _ = c'COLOR_RGB2BGR+instance ColorConversion 'BGRA     'RGBA      where colorConversionCode _ _ = c'COLOR_BGRA2RGBA+instance ColorConversion 'RGBA     'BGRA      where colorConversionCode _ _ = c'COLOR_RGBA2BGRA+instance ColorConversion 'BGR      'GRAY      where colorConversionCode _ _ = c'COLOR_BGR2GRAY+instance ColorConversion 'RGB      'GRAY      where colorConversionCode _ _ = c'COLOR_RGB2GRAY+instance ColorConversion 'GRAY     'BGR       where colorConversionCode _ _ = c'COLOR_GRAY2BGR+instance ColorConversion 'GRAY     'RGB       where colorConversionCode _ _ = c'COLOR_GRAY2RGB+instance ColorConversion 'GRAY     'BGRA      where colorConversionCode _ _ = c'COLOR_GRAY2BGRA+instance ColorConversion 'GRAY     'RGBA      where colorConversionCode _ _ = c'COLOR_GRAY2RGBA+instance ColorConversion 'BGRA     'GRAY      where colorConversionCode _ _ = c'COLOR_BGRA2GRAY+instance ColorConversion 'RGBA     'GRAY      where colorConversionCode _ _ = c'COLOR_RGBA2GRAY+instance ColorConversion 'BGR      'BGR565    where colorConversionCode _ _ = c'COLOR_BGR2BGR565+instance ColorConversion 'RGB      'BGR565    where colorConversionCode _ _ = c'COLOR_RGB2BGR565+instance ColorConversion 'BGR565   'BGR       where colorConversionCode _ _ = c'COLOR_BGR5652BGR+instance ColorConversion 'BGR565   'RGB       where colorConversionCode _ _ = c'COLOR_BGR5652RGB+instance ColorConversion 'BGRA     'BGR565    where colorConversionCode _ _ = c'COLOR_BGRA2BGR565+instance ColorConversion 'RGBA     'BGR565    where colorConversionCode _ _ = c'COLOR_RGBA2BGR565+instance ColorConversion 'BGR565   'BGRA      where colorConversionCode _ _ = c'COLOR_BGR5652BGRA+instance ColorConversion 'BGR565   'RGBA      where colorConversionCode _ _ = c'COLOR_BGR5652RGBA+instance ColorConversion 'GRAY     'BGR565    where colorConversionCode _ _ = c'COLOR_GRAY2BGR565+instance ColorConversion 'BGR565   'GRAY      where colorConversionCode _ _ = c'COLOR_BGR5652GRAY+instance ColorConversion 'BGR      'BGR555    where colorConversionCode _ _ = c'COLOR_BGR2BGR555+instance ColorConversion 'RGB      'BGR555    where colorConversionCode _ _ = c'COLOR_RGB2BGR555+instance ColorConversion 'BGR555   'BGR       where colorConversionCode _ _ = c'COLOR_BGR5552BGR+instance ColorConversion 'BGR555   'RGB       where colorConversionCode _ _ = c'COLOR_BGR5552RGB+instance ColorConversion 'BGRA     'BGR555    where colorConversionCode _ _ = c'COLOR_BGRA2BGR555+instance ColorConversion 'RGBA     'BGR555    where colorConversionCode _ _ = c'COLOR_RGBA2BGR555+instance ColorConversion 'BGR555   'BGRA      where colorConversionCode _ _ = c'COLOR_BGR5552BGRA+instance ColorConversion 'BGR555   'RGBA      where colorConversionCode _ _ = c'COLOR_BGR5552RGBA+instance ColorConversion 'GRAY     'BGR555    where colorConversionCode _ _ = c'COLOR_GRAY2BGR555+instance ColorConversion 'BGR555   'GRAY      where colorConversionCode _ _ = c'COLOR_BGR5552GRAY+instance ColorConversion 'BGR      'XYZ       where colorConversionCode _ _ = c'COLOR_BGR2XYZ+instance ColorConversion 'RGB      'XYZ       where colorConversionCode _ _ = c'COLOR_RGB2XYZ+instance ColorConversion 'XYZ      'BGR       where colorConversionCode _ _ = c'COLOR_XYZ2BGR+instance ColorConversion 'XYZ      'RGB       where colorConversionCode _ _ = c'COLOR_XYZ2RGB+instance ColorConversion 'BGR      'YCrCb     where colorConversionCode _ _ = c'COLOR_BGR2YCrCb+instance ColorConversion 'RGB      'YCrCb     where colorConversionCode _ _ = c'COLOR_RGB2YCrCb+instance ColorConversion 'YCrCb    'BGR       where colorConversionCode _ _ = c'COLOR_YCrCb2BGR+instance ColorConversion 'YCrCb    'RGB       where colorConversionCode _ _ = c'COLOR_YCrCb2RGB+instance ColorConversion 'BGR      'HSV       where colorConversionCode _ _ = c'COLOR_BGR2HSV+instance ColorConversion 'RGB      'HSV       where colorConversionCode _ _ = c'COLOR_RGB2HSV+instance ColorConversion 'BGR      'Lab       where colorConversionCode _ _ = c'COLOR_BGR2Lab+instance ColorConversion 'RGB      'Lab       where colorConversionCode _ _ = c'COLOR_RGB2Lab+instance ColorConversion 'BGR      'Luv       where colorConversionCode _ _ = c'COLOR_BGR2Luv+instance ColorConversion 'RGB      'Luv       where colorConversionCode _ _ = c'COLOR_RGB2Luv+instance ColorConversion 'BGR      'HLS       where colorConversionCode _ _ = c'COLOR_BGR2HLS+instance ColorConversion 'RGB      'HLS       where colorConversionCode _ _ = c'COLOR_RGB2HLS+instance ColorConversion 'HSV      'BGR       where colorConversionCode _ _ = c'COLOR_HSV2BGR+instance ColorConversion 'HSV      'RGB       where colorConversionCode _ _ = c'COLOR_HSV2RGB+instance ColorConversion 'Lab      'BGR       where colorConversionCode _ _ = c'COLOR_Lab2BGR+instance ColorConversion 'Lab      'RGB       where colorConversionCode _ _ = c'COLOR_Lab2RGB+instance ColorConversion 'Luv      'BGR       where colorConversionCode _ _ = c'COLOR_Luv2BGR+instance ColorConversion 'Luv      'RGB       where colorConversionCode _ _ = c'COLOR_Luv2RGB+instance ColorConversion 'HLS      'BGR       where colorConversionCode _ _ = c'COLOR_HLS2BGR+instance ColorConversion 'HLS      'RGB       where colorConversionCode _ _ = c'COLOR_HLS2RGB+instance ColorConversion 'BGR      'HSV_FULL  where colorConversionCode _ _ = c'COLOR_BGR2HSV_FULL+instance ColorConversion 'RGB      'HSV_FULL  where colorConversionCode _ _ = c'COLOR_RGB2HSV_FULL+instance ColorConversion 'BGR      'HLS_FULL  where colorConversionCode _ _ = c'COLOR_BGR2HLS_FULL+instance ColorConversion 'RGB      'HLS_FULL  where colorConversionCode _ _ = c'COLOR_RGB2HLS_FULL+instance ColorConversion 'HSV      'BGR_FULL  where colorConversionCode _ _ = c'COLOR_HSV2BGR_FULL+instance ColorConversion 'HSV      'RGB_FULL  where colorConversionCode _ _ = c'COLOR_HSV2RGB_FULL+instance ColorConversion 'HLS      'BGR_FULL  where colorConversionCode _ _ = c'COLOR_HLS2BGR_FULL+instance ColorConversion 'HLS      'RGB_FULL  where colorConversionCode _ _ = c'COLOR_HLS2RGB_FULL+instance ColorConversion 'LBGR     'Lab       where colorConversionCode _ _ = c'COLOR_LBGR2Lab+instance ColorConversion 'LRGB     'Lab       where colorConversionCode _ _ = c'COLOR_LRGB2Lab+instance ColorConversion 'LBGR     'Luv       where colorConversionCode _ _ = c'COLOR_LBGR2Luv+instance ColorConversion 'LRGB     'Luv       where colorConversionCode _ _ = c'COLOR_LRGB2Luv+instance ColorConversion 'Lab      'LBGR      where colorConversionCode _ _ = c'COLOR_Lab2LBGR+instance ColorConversion 'Lab      'LRGB      where colorConversionCode _ _ = c'COLOR_Lab2LRGB+instance ColorConversion 'Luv      'LBGR      where colorConversionCode _ _ = c'COLOR_Luv2LBGR+instance ColorConversion 'Luv      'LRGB      where colorConversionCode _ _ = c'COLOR_Luv2LRGB+instance ColorConversion 'BGR      'YUV       where colorConversionCode _ _ = c'COLOR_BGR2YUV+instance ColorConversion 'RGB      'YUV       where colorConversionCode _ _ = c'COLOR_RGB2YUV+instance ColorConversion 'YUV      'BGR       where colorConversionCode _ _ = c'COLOR_YUV2BGR+instance ColorConversion 'YUV      'RGB       where colorConversionCode _ _ = c'COLOR_YUV2RGB+instance ColorConversion 'YUV      'RGB_NV12  where colorConversionCode _ _ = c'COLOR_YUV2RGB_NV12+instance ColorConversion 'YUV      'BGR_NV12  where colorConversionCode _ _ = c'COLOR_YUV2BGR_NV12+instance ColorConversion 'YUV      'RGB_NV21  where colorConversionCode _ _ = c'COLOR_YUV2RGB_NV21+instance ColorConversion 'YUV      'BGR_NV21  where colorConversionCode _ _ = c'COLOR_YUV2BGR_NV21+instance ColorConversion 'YUV420sp 'RGB       where colorConversionCode _ _ = c'COLOR_YUV420sp2RGB+instance ColorConversion 'YUV420sp 'BGR       where colorConversionCode _ _ = c'COLOR_YUV420sp2BGR+instance ColorConversion 'YUV      'RGBA_NV12 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_NV12+instance ColorConversion 'YUV      'BGRA_NV12 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_NV12+instance ColorConversion 'YUV      'RGBA_NV21 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_NV21+instance ColorConversion 'YUV      'BGRA_NV21 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_NV21+instance ColorConversion 'YUV420sp 'RGBA      where colorConversionCode _ _ = c'COLOR_YUV420sp2RGBA+instance ColorConversion 'YUV420sp 'BGRA      where colorConversionCode _ _ = c'COLOR_YUV420sp2BGRA+instance ColorConversion 'YUV      'RGB_YV12  where colorConversionCode _ _ = c'COLOR_YUV2RGB_YV12+instance ColorConversion 'YUV      'BGR_YV12  where colorConversionCode _ _ = c'COLOR_YUV2BGR_YV12+instance ColorConversion 'YUV      'RGB_IYUV  where colorConversionCode _ _ = c'COLOR_YUV2RGB_IYUV+instance ColorConversion 'YUV      'BGR_IYUV  where colorConversionCode _ _ = c'COLOR_YUV2BGR_IYUV+instance ColorConversion 'YUV      'RGB_I420  where colorConversionCode _ _ = c'COLOR_YUV2RGB_I420+instance ColorConversion 'YUV      'BGR_I420  where colorConversionCode _ _ = c'COLOR_YUV2BGR_I420+instance ColorConversion 'YUV420p  'RGB       where colorConversionCode _ _ = c'COLOR_YUV420p2RGB+instance ColorConversion 'YUV420p  'BGR       where colorConversionCode _ _ = c'COLOR_YUV420p2BGR+instance ColorConversion 'YUV      'RGBA_YV12 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_YV12+instance ColorConversion 'YUV      'BGRA_YV12 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_YV12+instance ColorConversion 'YUV      'RGBA_IYUV where colorConversionCode _ _ = c'COLOR_YUV2RGBA_IYUV+instance ColorConversion 'YUV      'BGRA_IYUV where colorConversionCode _ _ = c'COLOR_YUV2BGRA_IYUV+instance ColorConversion 'YUV      'RGBA_I420 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_I420+instance ColorConversion 'YUV      'BGRA_I420 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_I420+instance ColorConversion 'YUV420p  'RGBA      where colorConversionCode _ _ = c'COLOR_YUV420p2RGBA+instance ColorConversion 'YUV420p  'BGRA      where colorConversionCode _ _ = c'COLOR_YUV420p2BGRA+instance ColorConversion 'YUV      'GRAY_420  where colorConversionCode _ _ = c'COLOR_YUV2GRAY_420+instance ColorConversion 'YUV      'GRAY_NV21 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_NV21+instance ColorConversion 'YUV      'GRAY_NV12 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_NV12+instance ColorConversion 'YUV      'GRAY_YV12 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_YV12+instance ColorConversion 'YUV      'GRAY_IYUV where colorConversionCode _ _ = c'COLOR_YUV2GRAY_IYUV+instance ColorConversion 'YUV      'GRAY_I420 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_I420+instance ColorConversion 'YUV420sp 'GRAY      where colorConversionCode _ _ = c'COLOR_YUV420sp2GRAY+instance ColorConversion 'YUV420p  'GRAY      where colorConversionCode _ _ = c'COLOR_YUV420p2GRAY+instance ColorConversion 'YUV      'RGB_UYVY  where colorConversionCode _ _ = c'COLOR_YUV2RGB_UYVY+instance ColorConversion 'YUV      'BGR_UYVY  where colorConversionCode _ _ = c'COLOR_YUV2BGR_UYVY+instance ColorConversion 'YUV      'RGB_Y422  where colorConversionCode _ _ = c'COLOR_YUV2RGB_Y422+instance ColorConversion 'YUV      'BGR_Y422  where colorConversionCode _ _ = c'COLOR_YUV2BGR_Y422+instance ColorConversion 'YUV      'RGB_UYNV  where colorConversionCode _ _ = c'COLOR_YUV2RGB_UYNV+instance ColorConversion 'YUV      'BGR_UYNV  where colorConversionCode _ _ = c'COLOR_YUV2BGR_UYNV+instance ColorConversion 'YUV      'RGBA_UYVY where colorConversionCode _ _ = c'COLOR_YUV2RGBA_UYVY+instance ColorConversion 'YUV      'BGRA_UYVY where colorConversionCode _ _ = c'COLOR_YUV2BGRA_UYVY+instance ColorConversion 'YUV      'RGBA_Y422 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_Y422+instance ColorConversion 'YUV      'BGRA_Y422 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_Y422+instance ColorConversion 'YUV      'RGBA_UYNV where colorConversionCode _ _ = c'COLOR_YUV2RGBA_UYNV+instance ColorConversion 'YUV      'BGRA_UYNV where colorConversionCode _ _ = c'COLOR_YUV2BGRA_UYNV+instance ColorConversion 'YUV      'RGB_YUY2  where colorConversionCode _ _ = c'COLOR_YUV2RGB_YUY2+instance ColorConversion 'YUV      'BGR_YUY2  where colorConversionCode _ _ = c'COLOR_YUV2BGR_YUY2+instance ColorConversion 'YUV      'RGB_YVYU  where colorConversionCode _ _ = c'COLOR_YUV2RGB_YVYU+instance ColorConversion 'YUV      'BGR_YVYU  where colorConversionCode _ _ = c'COLOR_YUV2BGR_YVYU+instance ColorConversion 'YUV      'RGB_YUYV  where colorConversionCode _ _ = c'COLOR_YUV2RGB_YUYV+instance ColorConversion 'YUV      'BGR_YUYV  where colorConversionCode _ _ = c'COLOR_YUV2BGR_YUYV+instance ColorConversion 'YUV      'RGB_YUNV  where colorConversionCode _ _ = c'COLOR_YUV2RGB_YUNV+instance ColorConversion 'YUV      'BGR_YUNV  where colorConversionCode _ _ = c'COLOR_YUV2BGR_YUNV+instance ColorConversion 'YUV      'RGBA_YUY2 where colorConversionCode _ _ = c'COLOR_YUV2RGBA_YUY2+instance ColorConversion 'YUV      'BGRA_YUY2 where colorConversionCode _ _ = c'COLOR_YUV2BGRA_YUY2+instance ColorConversion 'YUV      'RGBA_YVYU where colorConversionCode _ _ = c'COLOR_YUV2RGBA_YVYU+instance ColorConversion 'YUV      'BGRA_YVYU where colorConversionCode _ _ = c'COLOR_YUV2BGRA_YVYU+instance ColorConversion 'YUV      'RGBA_YUYV where colorConversionCode _ _ = c'COLOR_YUV2RGBA_YUYV+instance ColorConversion 'YUV      'BGRA_YUYV where colorConversionCode _ _ = c'COLOR_YUV2BGRA_YUYV+instance ColorConversion 'YUV      'RGBA_YUNV where colorConversionCode _ _ = c'COLOR_YUV2RGBA_YUNV+instance ColorConversion 'YUV      'BGRA_YUNV where colorConversionCode _ _ = c'COLOR_YUV2BGRA_YUNV+instance ColorConversion 'YUV      'GRAY_UYVY where colorConversionCode _ _ = c'COLOR_YUV2GRAY_UYVY+instance ColorConversion 'YUV      'GRAY_YUY2 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_YUY2+instance ColorConversion 'YUV      'GRAY_Y422 where colorConversionCode _ _ = c'COLOR_YUV2GRAY_Y422+instance ColorConversion 'YUV      'GRAY_UYNV where colorConversionCode _ _ = c'COLOR_YUV2GRAY_UYNV+instance ColorConversion 'YUV      'GRAY_YVYU where colorConversionCode _ _ = c'COLOR_YUV2GRAY_YVYU+instance ColorConversion 'YUV      'GRAY_YUYV where colorConversionCode _ _ = c'COLOR_YUV2GRAY_YUYV+instance ColorConversion 'YUV      'GRAY_YUNV where colorConversionCode _ _ = c'COLOR_YUV2GRAY_YUNV+instance ColorConversion 'RGBA     'MRGBA     where colorConversionCode _ _ = c'COLOR_RGBA2mRGBA+instance ColorConversion 'MRGBA    'RGBA      where colorConversionCode _ _ = c'COLOR_mRGBA2RGBA+instance ColorConversion 'RGB      'YUV_I420  where colorConversionCode _ _ = c'COLOR_RGB2YUV_I420+instance ColorConversion 'BGR      'YUV_I420  where colorConversionCode _ _ = c'COLOR_BGR2YUV_I420+instance ColorConversion 'RGB      'YUV_IYUV  where colorConversionCode _ _ = c'COLOR_RGB2YUV_IYUV+instance ColorConversion 'BGR      'YUV_IYUV  where colorConversionCode _ _ = c'COLOR_BGR2YUV_IYUV+instance ColorConversion 'RGBA     'YUV_I420  where colorConversionCode _ _ = c'COLOR_RGBA2YUV_I420+instance ColorConversion 'BGRA     'YUV_I420  where colorConversionCode _ _ = c'COLOR_BGRA2YUV_I420+instance ColorConversion 'RGBA     'YUV_IYUV  where colorConversionCode _ _ = c'COLOR_RGBA2YUV_IYUV+instance ColorConversion 'BGRA     'YUV_IYUV  where colorConversionCode _ _ = c'COLOR_BGRA2YUV_IYUV+instance ColorConversion 'RGB      'YUV_YV12  where colorConversionCode _ _ = c'COLOR_RGB2YUV_YV12+instance ColorConversion 'BGR      'YUV_YV12  where colorConversionCode _ _ = c'COLOR_BGR2YUV_YV12+instance ColorConversion 'RGBA     'YUV_YV12  where colorConversionCode _ _ = c'COLOR_RGBA2YUV_YV12+instance ColorConversion 'BGRA     'YUV_YV12  where colorConversionCode _ _ = c'COLOR_BGRA2YUV_YV12+instance ColorConversion 'BayerBG  'BGR       where colorConversionCode _ _ = c'COLOR_BayerBG2BGR+instance ColorConversion 'BayerGB  'BGR       where colorConversionCode _ _ = c'COLOR_BayerGB2BGR+instance ColorConversion 'BayerRG  'BGR       where colorConversionCode _ _ = c'COLOR_BayerRG2BGR+instance ColorConversion 'BayerGR  'BGR       where colorConversionCode _ _ = c'COLOR_BayerGR2BGR+instance ColorConversion 'BayerBG  'RGB       where colorConversionCode _ _ = c'COLOR_BayerBG2RGB+instance ColorConversion 'BayerGB  'RGB       where colorConversionCode _ _ = c'COLOR_BayerGB2RGB+instance ColorConversion 'BayerRG  'RGB       where colorConversionCode _ _ = c'COLOR_BayerRG2RGB+instance ColorConversion 'BayerGR  'RGB       where colorConversionCode _ _ = c'COLOR_BayerGR2RGB+instance ColorConversion 'BayerBG  'GRAY      where colorConversionCode _ _ = c'COLOR_BayerBG2GRAY+instance ColorConversion 'BayerGB  'GRAY      where colorConversionCode _ _ = c'COLOR_BayerGB2GRAY+instance ColorConversion 'BayerRG  'GRAY      where colorConversionCode _ _ = c'COLOR_BayerRG2GRAY+instance ColorConversion 'BayerGR  'GRAY      where colorConversionCode _ _ = c'COLOR_BayerGR2GRAY+instance ColorConversion 'BayerBG  'BGR_VNG   where colorConversionCode _ _ = c'COLOR_BayerBG2BGR_VNG+instance ColorConversion 'BayerGB  'BGR_VNG   where colorConversionCode _ _ = c'COLOR_BayerGB2BGR_VNG+instance ColorConversion 'BayerRG  'BGR_VNG   where colorConversionCode _ _ = c'COLOR_BayerRG2BGR_VNG+instance ColorConversion 'BayerGR  'BGR_VNG   where colorConversionCode _ _ = c'COLOR_BayerGR2BGR_VNG+instance ColorConversion 'BayerBG  'RGB_VNG   where colorConversionCode _ _ = c'COLOR_BayerBG2RGB_VNG+instance ColorConversion 'BayerGB  'RGB_VNG   where colorConversionCode _ _ = c'COLOR_BayerGB2RGB_VNG+instance ColorConversion 'BayerRG  'RGB_VNG   where colorConversionCode _ _ = c'COLOR_BayerRG2RGB_VNG+instance ColorConversion 'BayerGR  'RGB_VNG   where colorConversionCode _ _ = c'COLOR_BayerGR2RGB_VNG+instance ColorConversion 'BayerBG  'BGR_EA    where colorConversionCode _ _ = c'COLOR_BayerBG2BGR_EA+instance ColorConversion 'BayerGB  'BGR_EA    where colorConversionCode _ _ = c'COLOR_BayerGB2BGR_EA+instance ColorConversion 'BayerRG  'BGR_EA    where colorConversionCode _ _ = c'COLOR_BayerRG2BGR_EA+instance ColorConversion 'BayerGR  'BGR_EA    where colorConversionCode _ _ = c'COLOR_BayerGR2BGR_EA+instance ColorConversion 'BayerBG  'RGB_EA    where colorConversionCode _ _ = c'COLOR_BayerBG2RGB_EA+instance ColorConversion 'BayerGB  'RGB_EA    where colorConversionCode _ _ = c'COLOR_BayerGB2RGB_EA+instance ColorConversion 'BayerRG  'RGB_EA    where colorConversionCode _ _ = c'COLOR_BayerRG2RGB_EA+instance ColorConversion 'BayerGR  'RGB_EA    where colorConversionCode _ _ = c'COLOR_BayerGR2RGB_EA++-- | Gives the number of channels associated with a particular color encoding+type family ColorCodeChannels (cc :: ColorCode) :: Nat where+  ColorCodeChannels 'BayerBG   = 1+  ColorCodeChannels 'BayerGB   = 1+  ColorCodeChannels 'BayerGR   = 1+  ColorCodeChannels 'BayerRG   = 1+  ColorCodeChannels 'BGR       = 3+  ColorCodeChannels 'BGR555    = 2+  ColorCodeChannels 'BGR565    = 2+  ColorCodeChannels 'BGRA      = 4+  ColorCodeChannels 'BGRA_I420 = 4+  ColorCodeChannels 'BGRA_IYUV = 4+  ColorCodeChannels 'BGRA_NV12 = 4+  ColorCodeChannels 'BGRA_NV21 = 4+  ColorCodeChannels 'BGRA_UYNV = 4+  ColorCodeChannels 'BGRA_UYVY = 4+  ColorCodeChannels 'BGRA_Y422 = 4+  ColorCodeChannels 'BGRA_YUNV = 4+  ColorCodeChannels 'BGRA_YUY2 = 4+  ColorCodeChannels 'BGRA_YUYV = 4+  ColorCodeChannels 'BGRA_YV12 = 4+  ColorCodeChannels 'BGRA_YVYU = 4+  ColorCodeChannels 'BGR_EA    = 3+  ColorCodeChannels 'BGR_FULL  = 3+  ColorCodeChannels 'BGR_I420  = 3+  ColorCodeChannels 'BGR_IYUV  = 3+  ColorCodeChannels 'BGR_NV12  = 3+  ColorCodeChannels 'BGR_NV21  = 3+  ColorCodeChannels 'BGR_UYNV  = 3+  ColorCodeChannels 'BGR_UYVY  = 3+  ColorCodeChannels 'BGR_VNG   = 3+  ColorCodeChannels 'BGR_Y422  = 3+  ColorCodeChannels 'BGR_YUNV  = 3+  ColorCodeChannels 'BGR_YUY2  = 3+  ColorCodeChannels 'BGR_YUYV  = 3+  ColorCodeChannels 'BGR_YV12  = 3+  ColorCodeChannels 'BGR_YVYU  = 3+  ColorCodeChannels 'GRAY      = 1+  ColorCodeChannels 'GRAY_420  = 1+  ColorCodeChannels 'GRAY_I420 = 1+  ColorCodeChannels 'GRAY_IYUV = 1+  ColorCodeChannels 'GRAY_NV12 = 1+  ColorCodeChannels 'GRAY_NV21 = 1+  ColorCodeChannels 'GRAY_UYNV = 1+  ColorCodeChannels 'GRAY_UYVY = 1+  ColorCodeChannels 'GRAY_Y422 = 1+  ColorCodeChannels 'GRAY_YUNV = 1+  ColorCodeChannels 'GRAY_YUY2 = 1+  ColorCodeChannels 'GRAY_YUYV = 1+  ColorCodeChannels 'GRAY_YV12 = 1+  ColorCodeChannels 'GRAY_YVYU = 1+  ColorCodeChannels 'HLS       = 3+  ColorCodeChannels 'HLS_FULL  = 3+  ColorCodeChannels 'HSV       = 3+  ColorCodeChannels 'HSV_FULL  = 3+  ColorCodeChannels 'Lab       = 3+  ColorCodeChannels 'LBGR      = 3+  ColorCodeChannels 'LRGB      = 3+  ColorCodeChannels 'Luv       = 3+  ColorCodeChannels 'MRGBA     = 4+  ColorCodeChannels 'RGB       = 3+  ColorCodeChannels 'RGBA      = 4+  ColorCodeChannels 'RGBA_I420 = 4+  ColorCodeChannels 'RGBA_IYUV = 4+  ColorCodeChannels 'RGBA_NV12 = 4+  ColorCodeChannels 'RGBA_NV21 = 4+  ColorCodeChannels 'RGBA_UYNV = 4+  ColorCodeChannels 'RGBA_UYVY = 4+  ColorCodeChannels 'RGBA_Y422 = 4+  ColorCodeChannels 'RGBA_YUNV = 4+  ColorCodeChannels 'RGBA_YUY2 = 4+  ColorCodeChannels 'RGBA_YUYV = 4+  ColorCodeChannels 'RGBA_YV12 = 4+  ColorCodeChannels 'RGBA_YVYU = 4+  ColorCodeChannels 'RGB_EA    = 3+  ColorCodeChannels 'RGB_FULL  = 3+  ColorCodeChannels 'RGB_I420  = 3+  ColorCodeChannels 'RGB_IYUV  = 3+  ColorCodeChannels 'RGB_NV12  = 3+  ColorCodeChannels 'RGB_NV21  = 3+  ColorCodeChannels 'RGB_UYNV  = 3+  ColorCodeChannels 'RGB_UYVY  = 3+  ColorCodeChannels 'RGB_VNG   = 3+  ColorCodeChannels 'RGB_Y422  = 3+  ColorCodeChannels 'RGB_YUNV  = 3+  ColorCodeChannels 'RGB_YUY2  = 3+  ColorCodeChannels 'RGB_YUYV  = 3+  ColorCodeChannels 'RGB_YV12  = 3+  ColorCodeChannels 'RGB_YVYU  = 3+  ColorCodeChannels 'XYZ       = 3+  ColorCodeChannels 'YCrCb     = 3+  ColorCodeChannels 'YUV       = 3+  ColorCodeChannels 'YUV420p   = 3+  ColorCodeChannels 'YUV420sp  = 3+  ColorCodeChannels 'YUV_I420  = 1+  ColorCodeChannels 'YUV_IYUV  = 1+  ColorCodeChannels 'YUV_YV12  = 1++class ColorCodeMatchesChannels (code :: ColorCode) (channels :: DS Nat)++instance ColorCodeMatchesChannels code 'D+instance (ColorCodeChannels code ~ channels) => ColorCodeMatchesChannels code ('S channels)++type family ColorCodeDepth (srcCode :: ColorCode) (dstCode :: ColorCode) (srcDepth :: DS *) :: DS * where+  ColorCodeDepth 'BGR     'BGRA       ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'BGRA       ('S depth)  = 'S depth+  ColorCodeDepth 'BGRA    'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'RGBA    'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'BGR     'RGB        ('S depth)  = 'S depth+  ColorCodeDepth 'BGRA    'RGBA       ('S depth)  = 'S depth+  ColorCodeDepth 'BGRA    'RGB        ('S depth)  = 'S depth++  ColorCodeDepth 'BGR     'BGR565     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'BGR555     ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'BGR565     ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'BGR555     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGRA    'BGR565     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGRA    'BGR555     ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGBA    'BGR565     ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGBA    'BGR555     ('S Word8)  = 'S Word8++  ColorCodeDepth 'BGR565  'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR555  'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR565  'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR555  'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR565  'BGRA       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR555  'BGRA       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR565  'RGBA       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR555  'RGBA       ('S Word8)  = 'S Word8++  ColorCodeDepth 'BGR     'GRAY       ('S depth)  = 'S depth+  ColorCodeDepth 'BGRA    'GRAY       ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'GRAY       ('S depth)  = 'S depth+  ColorCodeDepth 'RGBA    'GRAY       ('S depth)  = 'S depth++  ColorCodeDepth 'BGR565  'GRAY       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR555  'GRAY       ('S Word8)  = 'S Word8++  ColorCodeDepth 'GRAY    'RGB        ('S depth)  = 'S depth+  ColorCodeDepth 'GRAY    'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'GRAY    'BGRA       ('S depth)  = 'S depth++  ColorCodeDepth 'GRAY    'BGR565     ('S Word8)  = 'S Word8+  ColorCodeDepth 'GRAY    'BGR555     ('S Word8)  = 'S Word8++  ColorCodeDepth 'BGR     'YCrCb      ('S depth)  = 'S depth+  ColorCodeDepth 'BGR     'YUV        ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'YCrCb      ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'YUV        ('S depth)  = 'S depth++  ColorCodeDepth 'YCrCb   'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'YCrCb   'RGB        ('S depth)  = 'S depth+  ColorCodeDepth 'YUV     'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'YUV     'RGB        ('S depth)  = 'S depth++  ColorCodeDepth 'BGR     'XYZ        ('S depth)  = 'S depth+  ColorCodeDepth 'RGB     'XYZ        ('S depth)  = 'S depth++  ColorCodeDepth 'XYZ     'BGR        ('S depth)  = 'S depth+  ColorCodeDepth 'XYZ     'RGB        ('S depth)  = 'S depth++  ColorCodeDepth 'BGR     'HSV        ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'HSV        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'HSV_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'HSV_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'HLS        ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'HLS        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'HLS_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'HLS_FULL   ('S Word8)  = 'S Word8++  ColorCodeDepth 'BGR     'HSV        ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'HSV        ('S Float)  = 'S Float+  ColorCodeDepth 'BGR     'HSV_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'HSV_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'BGR     'HLS        ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'HLS        ('S Float)  = 'S Float+  ColorCodeDepth 'BGR     'HLS_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'HLS_FULL   ('S Float)  = 'S Float++  ColorCodeDepth 'HSV     'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'HSV     'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'HSV     'BGR_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'HSV     'RGB_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'HLS     'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'HLS     'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'HLS     'BGR_FULL   ('S Word8)  = 'S Word8+  ColorCodeDepth 'HLS     'RGB_FULL   ('S Word8)  = 'S Word8++  ColorCodeDepth 'HSV     'BGR        ('S Float)  = 'S Float+  ColorCodeDepth 'HSV     'RGB        ('S Float)  = 'S Float+  ColorCodeDepth 'HSV     'BGR_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'HSV     'RGB_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'HLS     'BGR        ('S Float)  = 'S Float+  ColorCodeDepth 'HLS     'RGB        ('S Float)  = 'S Float+  ColorCodeDepth 'HLS     'BGR_FULL   ('S Float)  = 'S Float+  ColorCodeDepth 'HLS     'RGB_FULL   ('S Float)  = 'S Float++  ColorCodeDepth 'BGR     'Lab        ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'Lab        ('S Word8)  = 'S Word8+  ColorCodeDepth 'LBGR    'Lab        ('S Word8)  = 'S Word8+  ColorCodeDepth 'LRGB    'Lab        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'Luv        ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'Luv        ('S Word8)  = 'S Word8+  ColorCodeDepth 'LBGR    'Luv        ('S Word8)  = 'S Word8+  ColorCodeDepth 'LRGB    'Luv        ('S Word8)  = 'S Word8++  ColorCodeDepth 'BGR     'Lab        ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'Lab        ('S Float)  = 'S Float+  ColorCodeDepth 'LBGR    'Lab        ('S Float)  = 'S Float+  ColorCodeDepth 'LRGB    'Lab        ('S Float)  = 'S Float+  ColorCodeDepth 'BGR     'Luv        ('S Float)  = 'S Float+  ColorCodeDepth 'RGB     'Luv        ('S Float)  = 'S Float+  ColorCodeDepth 'LBGR    'Luv        ('S Float)  = 'S Float+  ColorCodeDepth 'LRGB    'Luv        ('S Float)  = 'S Float++  ColorCodeDepth 'Lab     'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'Lab     'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'Lab     'LBGR       ('S Word8)  = 'S Word8+  ColorCodeDepth 'Lab     'LRGB       ('S Word8)  = 'S Word8+  ColorCodeDepth 'Luv     'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'Luv     'RGB        ('S Word8)  = 'S Word8+  ColorCodeDepth 'Luv     'LBGR       ('S Word8)  = 'S Word8+  ColorCodeDepth 'Luv     'LRGB       ('S Word8)  = 'S Word8++  ColorCodeDepth 'Lab     'BGR        ('S Float)  = 'S Float+  ColorCodeDepth 'Lab     'RGB        ('S Float)  = 'S Float+  ColorCodeDepth 'Lab     'LBGR       ('S Float)  = 'S Float+  ColorCodeDepth 'Lab     'LRGB       ('S Float)  = 'S Float+  ColorCodeDepth 'Luv     'BGR        ('S Float)  = 'S Float+  ColorCodeDepth 'Luv     'RGB        ('S Float)  = 'S Float+  ColorCodeDepth 'Luv     'LBGR       ('S Float)  = 'S Float+  ColorCodeDepth 'Luv     'LRGB       ('S Float)  = 'S Float++  ColorCodeDepth 'BayerBG 'GRAY       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerBG 'GRAY       ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGB 'GRAY       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGB 'GRAY       ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGR 'GRAY       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGR 'GRAY       ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerRG 'GRAY       ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerRG 'GRAY       ('S Word16) = 'S Word16++  ColorCodeDepth 'BayerBG 'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerBG 'BGR        ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGB 'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGB 'BGR        ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGR 'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGR 'BGR        ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerRG 'BGR        ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerRG 'BGR        ('S Word16) = 'S Word16++  ColorCodeDepth 'BayerBG 'BGR_VNG    ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerBG 'BGR_VNG    ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGB 'BGR_VNG    ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGB 'BGR_VNG    ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGR 'BGR_VNG    ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGR 'BGR_VNG    ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerRG 'BGR_VNG    ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerRG 'BGR_VNG    ('S Word16) = 'S Word16++  ColorCodeDepth 'BayerBG 'BGR_EA     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerBG 'BGR_EA     ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGB 'BGR_EA     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGB 'BGR_EA     ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerGR 'BGR_EA     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerGR 'BGR_EA     ('S Word16) = 'S Word16+  ColorCodeDepth 'BayerRG 'BGR_EA     ('S Word8)  = 'S Word8+  ColorCodeDepth 'BayerRG 'BGR_EA     ('S Word16) = 'S Word16++  ColorCodeDepth 'YUV     'BGR_NV21   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_NV21   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGR_NV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_NV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_NV21  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_NV21  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_NV12  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_NV12  ('S Word8)  = 'S Word8++  ColorCodeDepth 'YUV     'BGR_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_YV12  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_YV12  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGR_IYUV   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_IYUV   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_IYUV  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_IYUV  ('S Word8)  = 'S Word8++  ColorCodeDepth 'YUV     'GRAY_420   ('S Word8)  = 'S Word8++  ColorCodeDepth 'RGB     'YUV_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'YUV_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGBA    'YUV_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGRA    'YUV_YV12   ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGB     'YUV_IYUV   ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGR     'YUV_IYUV   ('S Word8)  = 'S Word8+  ColorCodeDepth 'RGBA    'YUV_IYUV   ('S Word8)  = 'S Word8+  ColorCodeDepth 'BGRA    'YUV_IYUV   ('S Word8)  = 'S Word8++  ColorCodeDepth 'YUV     'RGB_UYVY   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGR_UYVY   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_UYVY  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_UYVY  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_YUY2   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGR_YUY2   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGB_YVYU   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGR_YVYU   ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_YUY2  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_YUY2  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'RGBA_YVYU  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'BGRA_YVYU  ('S Word8)  = 'S Word8++  ColorCodeDepth 'YUV     'GRAY_UYVY  ('S Word8)  = 'S Word8+  ColorCodeDepth 'YUV     'GRAY_YUY2  ('S Word8)  = 'S Word8++  ColorCodeDepth 'RGBA    'MRGBA      ('S Word8)  = 'S Word8+  ColorCodeDepth 'MRGBA   'RGBA       ('S Word8)  = 'S Word8++  ColorCodeDepth srcCode  dstCode      'D         = 'D
+ src/OpenCV/Internal/ImgProc/MiscImgTransform/TypeLevel.hs view
@@ -0,0 +1,22 @@+{-# language UndecidableInstances #-}+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.ImgProc.MiscImgTransform.TypeLevel+    ( WidthAndHeightPlusTwo+    , PlusTwo+    ) where++import "base" GHC.TypeLits+import "this" OpenCV.TypeLevel++type family WidthAndHeightPlusTwo (dims :: DS [DS Nat]) :: DS [DS Nat] where+    WidthAndHeightPlusTwo 'D = 'D+    WidthAndHeightPlusTwo ('S '[w, h]) = 'S [PlusTwo w, PlusTwo h]++type family PlusTwo (n :: DS Nat) :: DS Nat where+    PlusTwo 'D = 'D+    PlusTwo ('S n) = 'S (2 + n)
+ src/OpenCV/Internal/ImgProc/Types.hsc view
@@ -0,0 +1,57 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.ImgProc.Types where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.Types ( CDouble )+import "linear" Linear.V4 ( V4(..) )+import "linear" Linear.Vector ( zero )+import "this" OpenCV.Core.Types ( Scalar, toScalar )+import "this" OpenCV.ImgProc.Types++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/imgproc.hpp"++#include "namespace.hpp"++#num INTER_NEAREST+#num INTER_LINEAR+#num INTER_CUBIC+#num INTER_AREA+#num INTER_LANCZOS4++marshalInterpolationMethod :: InterpolationMethod -> Int32+marshalInterpolationMethod = \case+   InterNearest  -> c'INTER_NEAREST+   InterLinear   -> c'INTER_LINEAR+   InterCubic    -> c'INTER_CUBIC+   InterArea     -> c'INTER_AREA+   InterLanczos4 -> c'INTER_LANCZOS4++#num BORDER_CONSTANT+#num BORDER_REPLICATE+#num BORDER_REFLECT+#num BORDER_WRAP+#num BORDER_REFLECT_101+#num BORDER_TRANSPARENT+#num BORDER_ISOLATED++marshalBorderMode :: BorderMode -> (Int32, Scalar)+marshalBorderMode = \case+    BorderConstant s  -> (c'BORDER_CONSTANT    , s         )+    BorderReplicate   -> (c'BORDER_REPLICATE   , zeroScalar)+    BorderReflect     -> (c'BORDER_REFLECT     , zeroScalar)+    BorderWrap        -> (c'BORDER_WRAP        , zeroScalar)+    BorderReflect101  -> (c'BORDER_REFLECT_101 , zeroScalar)+    BorderTransparent -> (c'BORDER_TRANSPARENT , zeroScalar)+    BorderIsolated    -> (c'BORDER_ISOLATED    , zeroScalar)+  where+    zeroScalar :: Scalar+    zeroScalar = toScalar (zero :: V4 CDouble)
+ src/OpenCV/Internal/Mutable.hs view
@@ -0,0 +1,25 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Mutable+  ( Mut(..)+  , Mutable+  , FreezeThaw(..)+  ) where++import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState )++-- | Wrapper for mutable values+newtype Mut a s = Mut { unMut :: a }++type family Mutable (a :: *) :: * -> *++class FreezeThaw a where+    freeze :: (PrimMonad m) => Mutable a (PrimState m) -> m a+    thaw   :: (PrimMonad m) => a -> m (Mutable a (PrimState m))++    unsafeFreeze :: (PrimMonad m) => Mutable a (PrimState m) -> m a+    unsafeThaw   :: (PrimMonad m) => a -> m (Mutable a (PrimState m))
+ src/OpenCV/Internal/Photo/Constants.hsc view
@@ -0,0 +1,21 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.Photo.Constants where++#include <bindings.dsl.h>+#include "opencv2/photo.hpp"+#include "namespace.hpp"++#num INPAINT_NS+#num INPAINT_TELEA++#num NORMAL_CLONE+#num MIXED_CLONE+#num MONOCHROME_TRANSFER++#num RECURS_FILTER+#num NORMCONV_FILTER
+ src/OpenCV/Internal/VideoIO/Constants.hsc view
@@ -0,0 +1,84 @@+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.VideoIO.Constants where++--------------------------------------------------------------------------------++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/videoio.hpp"++#include "namespace.hpp"++#num CAP_PROP_POS_MSEC+#num CAP_PROP_POS_FRAMES+#num CAP_PROP_POS_AVI_RATIO+#num CAP_PROP_FRAME_WIDTH+#num CAP_PROP_FRAME_HEIGHT+#num CAP_PROP_FPS+#num CAP_PROP_FOURCC+#num CAP_PROP_FRAME_COUNT+#num CAP_PROP_FORMAT+#num CAP_PROP_MODE+#num CAP_PROP_BRIGHTNESS+#num CAP_PROP_CONTRAST+#num CAP_PROP_SATURATION+#num CAP_PROP_HUE+#num CAP_PROP_GAIN+#num CAP_PROP_EXPOSURE+#num CAP_PROP_CONVERT_RGB+#num CAP_PROP_WHITE_BALANCE_BLUE_U+#num CAP_PROP_RECTIFICATION+#num CAP_PROP_MONOCHROME+#num CAP_PROP_SHARPNESS+#num CAP_PROP_AUTO_EXPOSURE+#num CAP_PROP_GAMMA+#num CAP_PROP_TEMPERATURE+#num CAP_PROP_TRIGGER+#num CAP_PROP_TRIGGER_DELAY+#num CAP_PROP_WHITE_BALANCE_RED_V+#num CAP_PROP_ZOOM+#num CAP_PROP_FOCUS+#num CAP_PROP_GUID+#num CAP_PROP_ISO_SPEED+#num CAP_PROP_BACKLIGHT+#num CAP_PROP_PAN+#num CAP_PROP_TILT+#num CAP_PROP_ROLL+#num CAP_PROP_IRIS+#num CAP_PROP_SETTINGS+#num CAP_PROP_BUFFERSIZE+#num CAP_PROP_AUTOFOCUS++#num CAP_ANY+#num CAP_VFW+#num CAP_V4L+#num CAP_V4L2+#num CAP_FIREWIRE+#num CAP_FIREWARE+#num CAP_IEEE1394+#num CAP_DC1394+#num CAP_CMU1394+#num CAP_QT+#num CAP_UNICAP+#num CAP_DSHOW+#num CAP_PVAPI+#num CAP_OPENNI+#num CAP_OPENNI_ASUS+#num CAP_ANDROID+#num CAP_XIAPI+#num CAP_AVFOUNDATION+#num CAP_GIGANETIX+#num CAP_MSMF+#num CAP_WINRT+#num CAP_INTELPERC+#num CAP_OPENNI2+#num CAP_OPENNI2_ASUS+#num CAP_GPHOTO2+#num CAP_GSTREAMER+#num CAP_FFMPEG+#num CAP_IMAGES
+ src/OpenCV/Internal/VideoIO/Types.hs view
@@ -0,0 +1,215 @@+{-# language GeneralizedNewtypeDeriving #-}+{-# language CPP #-}++#ifndef ENABLE_INTERNAL_DOCUMENTATION+{-# OPTIONS_HADDOCK hide #-}+#endif++module OpenCV.Internal.VideoIO.Types+    ( -- * VideoCodecs+      FourCC(..)+    , VideoCaptureProperties(..)+    , marshalCaptureProperties+    , VideoCaptureAPI(..)+    , marshalVideoCaptureAPI+    ) where++import "base" Data.Char ( ord )+import "base" Data.Int ( Int32 )+import "base" Data.Word ( Word32 )+import "base" Data.String ( IsString (..) )+import "base" Data.List( unfoldr )+import "this" OpenCV.Internal.VideoIO.Constants++--------------------------------------------------------------------------------+-- FourCC+--------------------------------------------------------------------------------++newtype FourCC = FourCC { unFourCC :: Int32 }++instance IsString FourCC where+  fromString "ask" = FourCC (-1)+  fromString fcc =+      FourCC $ foldr (\x acc -> acc * 256 + fromIntegral (ord x))+                     0+                     (take 4 fcc)++instance Show FourCC where+  show (FourCC (-1)) = "ask"+  show (FourCC fcc) = take 4 $ unfoldr worker (fromIntegral fcc :: Word32)+    where+      worker 0 = Nothing+      worker b = Just (toEnum . fromEnum $ b `mod` 256, b `div` 256)++--------------------------------------------------------------------------------+-- VideoCaptureProperties+-- more at https://github.com/opencv/opencv/blob/master/modules/videoio/include/opencv2/videoio.hpp+--------------------------------------------------------------------------------++data VideoCaptureProperties+   = VideoCapPropPosMsec+          -- ^ Current position of the video file in milliseconds.+   | VideoCapPropPosFrames+          -- ^ 0-based index of the frame to be decoded/captured next.+   | VideoCapPropPosAviRatio+          -- ^ Relative position of the video file: 0=start of the film,+          --   1=end of the film.+   | VideoCapPropFrameWidth     -- ^ Width of the frames in the video stream.+   | VideoCapPropFrameHeight    -- ^ Height of the frames in the video stream.+   | VideoCapPropFps            -- ^ Frame rate.+   | VideoCapPropFourCc         -- ^ 4-character code of codec.+   | VideoCapPropFrameCount     -- ^ Number of frames in the video file.+   | VideoCapPropFormat+          -- ^ Format of the Mat objects returned by VideoCapture::retrieve().+   | VideoCapPropMode+          -- ^ Backend-specific value indicating the current capture mode.+   | VideoCapPropBrightness     -- ^ Brightness of the image (only for cameras).+   | VideoCapPropContrast       -- ^ Contrast of the image (only for cameras).+   | VideoCapPropSaturation     -- ^ Saturation of the image (only for cameras).+   | VideoCapPropHue            -- ^ Hue of the image (only for cameras).+   | VideoCapPropGain           -- ^ Gain of the image (only for cameras).+   | VideoCapPropExposure       -- ^ Exposure (only for cameras).+   | VideoCapPropConvertRgb+        -- ^ Boolean flags indicating whether images should be converted to RGB.+   | VideoCapPropWhiteBalanceBlueU -- ^ Currently unsupported.+   | VideoCapPropRectification+        -- ^ Rectification flag for stereo cameras+        --  (note: only supported by DC1394 v 2.x backend currently).+   | VideoCapPropMonochrome        -- ^+   | VideoCapPropSharpness         -- ^+   | VideoCapPropAutoExposure+        -- ^ DC1394: exposure control done by camera, user can adjust reference+        -- level using this feature.+   | VideoCapPropGamma             -- ^+   | VideoCapPropTemperature       -- ^+   | VideoCapPropTrigger           -- ^+   | VideoCapPropTriggerDelay      -- ^+   | VideoCapPropWhiteBalanceRedV  -- ^+   | VideoCapPropZoom              -- ^+   | VideoCapPropFocus             -- ^+   | VideoCapPropGuid              -- ^+   | VideoCapPropIsoSpeed          -- ^+   | VideoCapPropBacklight         -- ^+   | VideoCapPropPan               -- ^+   | VideoCapPropTilt              -- ^+   | VideoCapPropRoll              -- ^+   | VideoCapPropIris              -- ^+   | VideoCapPropSettings+        -- ^ Pop up video/camera filter dialog (note: only supported by DSHOW+        --  backend currently. Property value is ignored)+   | VideoCapPropBuffersize        -- ^+   | VideoCapPropAutofocus         -- ^+   | VideoCapPropInt !Int32+       -- ^ Any property we need. Meaning of this property depends on+       -- the backend.++marshalCaptureProperties :: VideoCaptureProperties -> Int32+marshalCaptureProperties = \case+   VideoCapPropPosMsec           -> c'CAP_PROP_POS_MSEC+   VideoCapPropPosFrames         -> c'CAP_PROP_POS_FRAMES+   VideoCapPropPosAviRatio       -> c'CAP_PROP_POS_AVI_RATIO+   VideoCapPropFrameWidth        -> c'CAP_PROP_FRAME_WIDTH+   VideoCapPropFrameHeight       -> c'CAP_PROP_FRAME_HEIGHT+   VideoCapPropFps               -> c'CAP_PROP_FPS+   VideoCapPropFourCc            -> c'CAP_PROP_FOURCC+   VideoCapPropFrameCount        -> c'CAP_PROP_FRAME_COUNT+   VideoCapPropFormat            -> c'CAP_PROP_FORMAT+   VideoCapPropMode              -> c'CAP_PROP_MODE+   VideoCapPropBrightness        -> c'CAP_PROP_BRIGHTNESS+   VideoCapPropContrast          -> c'CAP_PROP_CONTRAST+   VideoCapPropSaturation        -> c'CAP_PROP_SATURATION+   VideoCapPropHue               -> c'CAP_PROP_HUE+   VideoCapPropGain              -> c'CAP_PROP_GAIN+   VideoCapPropExposure          -> c'CAP_PROP_EXPOSURE+   VideoCapPropConvertRgb        -> c'CAP_PROP_CONVERT_RGB+   VideoCapPropWhiteBalanceBlueU -> c'CAP_PROP_WHITE_BALANCE_BLUE_U+   VideoCapPropRectification     -> c'CAP_PROP_RECTIFICATION+   VideoCapPropMonochrome        -> c'CAP_PROP_MONOCHROME+   VideoCapPropSharpness         -> c'CAP_PROP_SHARPNESS+   VideoCapPropAutoExposure      -> c'CAP_PROP_AUTO_EXPOSURE+   VideoCapPropGamma             -> c'CAP_PROP_GAMMA+   VideoCapPropTemperature       -> c'CAP_PROP_TEMPERATURE+   VideoCapPropTrigger           -> c'CAP_PROP_TRIGGER+   VideoCapPropTriggerDelay      -> c'CAP_PROP_TRIGGER_DELAY+   VideoCapPropWhiteBalanceRedV  -> c'CAP_PROP_WHITE_BALANCE_RED_V+   VideoCapPropZoom              -> c'CAP_PROP_ZOOM+   VideoCapPropFocus             -> c'CAP_PROP_FOCUS+   VideoCapPropGuid              -> c'CAP_PROP_GUID+   VideoCapPropIsoSpeed          -> c'CAP_PROP_ISO_SPEED+   VideoCapPropBacklight         -> c'CAP_PROP_BACKLIGHT+   VideoCapPropPan               -> c'CAP_PROP_PAN+   VideoCapPropTilt              -> c'CAP_PROP_TILT+   VideoCapPropRoll              -> c'CAP_PROP_ROLL+   VideoCapPropIris              -> c'CAP_PROP_IRIS+   VideoCapPropSettings          -> c'CAP_PROP_SETTINGS+   VideoCapPropBuffersize        -> c'CAP_PROP_BUFFERSIZE+   VideoCapPropAutofocus         -> c'CAP_PROP_AUTOFOCUS+   VideoCapPropInt a             -> a++--------------------------------------------------------------------------------+-- VideoCaptureProperties+-- more at https://github.com/opencv/opencv/blob/master/modules/videoio/include/opencv2/videoio.hpp+--------------------------------------------------------------------------------+data VideoCaptureAPI+   = VideoCapAny          -- ^ Auto detect == 0+   | VideoCapVfw          -- ^ Video For Windows (platform native)+   | VideoCapV4l          -- ^ V4L/V4L2 capturing support via libv4l+   | VideoCapV4l2         -- ^ Same as CAP_V4L+   | VideoCapFirewire     -- ^ IEEE 1394 drivers+   | VideoCapFireware     -- ^ Same as CAP_FIREWIRE+   | VideoCapIeee1394     -- ^ Same as CAP_FIREWIRE+   | VideoCapDc1394       -- ^ Same as CAP_FIREWIRE+   | VideoCapCmu1394      -- ^ Same as CAP_FIREWIRE+   | VideoCapQt           -- ^ QuickTime+   | VideoCapUnicap       -- ^ Unicap drivers+   | VideoCapDshow        -- ^ DirectShow (via videoInput)+   | VideoCapPvapi        -- ^ PvAPI, Prosilica GigE SDK+   | VideoCapOpenni       -- ^ OpenNI (for Kinect)+   | VideoCapOpenniAsus   -- ^ OpenNI (for Asus Xtion)+   | VideoCapAndroid      -- ^ Android - not used+   | VideoCapXiapi        -- ^ XIMEA Camera API+   | VideoCapAvfoundation+        -- ^ AVFoundation framework for iOS (OS X Lion will have the same API)+   | VideoCapGiganetix    -- ^ Smartek Giganetix GigEVisionSDK+   | VideoCapMsmf         -- ^ Microsoft Media Foundation (via videoInput)+   | VideoCapWinrt        -- ^ Microsoft Windows Runtime using Media Foundation+   | VideoCapIntelperc    -- ^ Intel Perceptual Computing SDK+   | VideoCapOpenni2      -- ^ OpenNI2 (for Kinect)+   | VideoCapOpenni2Asus+        -- ^ OpenNI2 (for Asus Xtion and Occipital Structure sensors)+   | VideoCapGphoto2      -- ^ gPhoto2 connection+   | VideoCapGstreamer    -- ^ GStreamer+   | VideoCapFfmpeg+        -- ^ Open and record video file or stream using the FFMPEG library+   | VideoCapImages       -- ^ Image Sequence (e.g. img_%02d.jpg)++marshalVideoCaptureAPI :: VideoCaptureAPI -> Int32+marshalVideoCaptureAPI = \case+   VideoCapAny           -> c'CAP_ANY+   VideoCapVfw           -> c'CAP_VFW+   VideoCapV4l           -> c'CAP_V4L+   VideoCapV4l2          -> c'CAP_V4L2+   VideoCapFirewire      -> c'CAP_FIREWIRE+   VideoCapFireware      -> c'CAP_FIREWARE+   VideoCapIeee1394      -> c'CAP_IEEE1394+   VideoCapDc1394        -> c'CAP_DC1394+   VideoCapCmu1394       -> c'CAP_CMU1394+   VideoCapQt            -> c'CAP_QT+   VideoCapUnicap        -> c'CAP_UNICAP+   VideoCapDshow         -> c'CAP_DSHOW+   VideoCapPvapi         -> c'CAP_PVAPI+   VideoCapOpenni        -> c'CAP_OPENNI+   VideoCapOpenniAsus    -> c'CAP_OPENNI_ASUS+   VideoCapAndroid       -> c'CAP_ANDROID+   VideoCapXiapi         -> c'CAP_XIAPI+   VideoCapAvfoundation  -> c'CAP_AVFOUNDATION+   VideoCapGiganetix     -> c'CAP_GIGANETIX+   VideoCapMsmf          -> c'CAP_MSMF+   VideoCapWinrt         -> c'CAP_WINRT+   VideoCapIntelperc     -> c'CAP_INTELPERC+   VideoCapOpenni2       -> c'CAP_OPENNI2+   VideoCapOpenni2Asus   -> c'CAP_OPENNI2_ASUS+   VideoCapGphoto2       -> c'CAP_GPHOTO2+   VideoCapGstreamer     -> c'CAP_GSTREAMER+   VideoCapFfmpeg        -> c'CAP_FFMPEG+   VideoCapImages        -> c'CAP_IMAGES
+ src/OpenCV/JSON.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++module OpenCV.JSON ( ) where++import "aeson" Data.Aeson+import "aeson" Data.Aeson.Types ( Parser )+import "aeson" Data.Aeson.TH+import "base" Data.Int ( Int32 )+import "base" Data.Monoid ( (<>) )+import "base" Data.Proxy ( Proxy(..) )+import qualified "base64-bytestring" Data.ByteString.Base64 as B64 ( encode, decode )+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.V3 ( V3(..) )+import qualified "text" Data.Text.Encoding as TE ( encodeUtf8, decodeUtf8 )+import "text" Data.Text ( Text )+import qualified "text" Data.Text as T ( unpack )+import "this" OpenCV.Core.Types+import "this" OpenCV.Core.Types.Mat.HMat+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except++--------------------------------------------------------------------------------++newtype J a = J {unJ :: a}++instance (ToJSON a) => ToJSON (J (V2 a)) where+    toJSON (J (V2 x y)) = toJSON (x, y)++instance (ToJSON a) => ToJSON (J (V3 a)) where+    toJSON (J (V3 x y z)) = toJSON (x, y, z)++instance (FromJSON a) => FromJSON (J (V2 a)) where+    parseJSON = fmap (\(x, y) -> J $ V2 x y) . parseJSON++instance (FromJSON a) => FromJSON (J (V3 a)) where+    parseJSON = fmap (\(x, y, z) -> J $ V3 x y z) . parseJSON+++--------------------------------------------------------------------------------++#define IsoJSON(A, B, A_to_B, B_to_A)                \+instance ToJSON A where {                            \+    toJSON = toJSON . (A_to_B :: A -> B);            \+};                                                   \+instance FromJSON A where {                          \+    parseJSON = fmap (B_to_A :: B -> A) . parseJSON; \+}++--------------------------------------------------------------------------------+IsoJSON(Point2i, J (V2 Int32 ), J .                   fromPoint, toPoint                   . unJ)+IsoJSON(Point2f, J (V2 Float ), J . fmap realToFrac . fromPoint, toPoint . fmap realToFrac . unJ)+IsoJSON(Point2d, J (V2 Double), J . fmap realToFrac . fromPoint, toPoint . fmap realToFrac . unJ)+IsoJSON(Point3i, J (V3 Int32 ), J .                   fromPoint, toPoint                   . unJ)+IsoJSON(Point3f, J (V3 Float ), J . fmap realToFrac . fromPoint, toPoint . fmap realToFrac . unJ)+IsoJSON(Point3d, J (V3 Double), J . fmap realToFrac . fromPoint, toPoint . fmap realToFrac . unJ)+IsoJSON(Size2i , J (V2 Int32 ), J .                   fromSize , toSize                    . unJ)+IsoJSON(Size2f , J (V2 Float ), J . fmap realToFrac . fromSize , toSize  . fmap realToFrac . unJ)++instance ToJSON (Mat shape channels depth) where+    toJSON = toJSON . matToHMat++instance ( ToShapeDS    (Proxy shape)+         , ToChannelsDS (Proxy channels)+         , ToDepthDS    (Proxy depth)+         )+      => FromJSON (Mat shape channels depth) where+    parseJSON value = do+      matDyn <- hMatToMat <$> parseJSON value+      case runExcept $ coerceMat (matDyn :: Mat 'D 'D 'D) of+        Left err -> fail $ show err+        Right mat -> pure mat+++--------------------------------------------------------------------------------++instance ToJSON HElems where+    toJSON = \case+        HElems_8U       v -> f "8U"  v+        HElems_8S       v -> f "8S"  v+        HElems_16U      v -> f "16U" v+        HElems_16S      v -> f "16S" v+        HElems_32S      v -> f "32S" v+        HElems_32F      v -> f "32F" v+        HElems_64F      v -> f "64F" v+        HElems_USRTYPE1 v -> f "USR" $ fmap (TE.decodeUtf8 . B64.encode) v+      where+        f :: (ToJSON a) => Text -> a -> Value+        f typ v = object [ "type"  .= typ+                         , "elems" .= v+                         ]++instance FromJSON HElems where+    parseJSON = withObject "HElems" $ \obj -> do+                  typ <- obj .: "type"+                  let elems :: (FromJSON a) => Parser a+                      elems = obj .: "elems"+                  case typ of+                    "8U"  -> HElems_8U       <$> elems+                    "8S"  -> HElems_8S       <$> elems+                    "16U" -> HElems_16U      <$> elems+                    "16S" -> HElems_16S      <$> elems+                    "32S" -> HElems_32S      <$> elems+                    "32F" -> HElems_32F      <$> elems+                    "64F" -> HElems_64F      <$> elems+                    "USR" -> HElems_USRTYPE1 <$> (mapM (either fail pure . B64.decode . TE.encodeUtf8) =<< elems)+                    _ -> fail $ "Unknown Helems type " <> T.unpack typ++--------------------------------------------------------------------------------++deriveJSON defaultOptions {fieldLabelModifier = drop 2} ''HMat
+ src/OpenCV/Juicy.hs view
@@ -0,0 +1,243 @@+{-# language DataKinds #-}+{-# language Rank2Types #-}+{-# language TypeFamilies #-}+{-# language ScopedTypeVariables #-}+{-# language FlexibleContexts #-}+{-# language ViewPatterns #-}+{-# language ExistentialQuantification #-}++-- TODO (basvandijk): upstream the Storable instances to JuicyPixels!+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | A thin JuicyPixels layer.+module OpenCV.Juicy+  ( -- * Types+    Mat2D+  , Filter+  , PixelChannels+  , PixelDepth++    -- * Low level API+  , fromImage+  , toImage++    -- * High level API+  , isoJuicy+  ) where++import "base" GHC.TypeLits (Nat,KnownNat)+import "base" Data.Proxy (Proxy (Proxy))+import "base" Foreign.Storable (Storable (..))+import "base" Foreign.Ptr (Ptr, plusPtr)+import "base" System.IO.Unsafe (unsafePerformIO)+import "base" Data.Word (Word8,Word16)+import "base" Data.Int (Int32)+import "base" Control.Monad (forM_)+import "primitive" Control.Monad.Primitive (PrimMonad)+import "linear" Linear.V4 (V4)+import "this" OpenCV+import "this" OpenCV.Unsafe (unsafeRead, unsafeWrite)+import "JuicyPixels" Codec.Picture.Types++-- list of pointers at a given byte distance from a base one+plusPtrS :: Ptr a -> Int -> [Ptr b]+plusPtrS p n = map (plusPtr p) [0..n-1]++-- multiple peek+peekS :: Storable b => Ptr a -> Int -> IO [b]+peekS p n = mapM peek (plusPtrS p n)++-- multiple poke+pokeS :: Storable a => Ptr a1 -> Int -> [a] -> IO ()+pokeS p n xs = sequence_ (zipWith poke (plusPtrS p n) xs)++instance Storable PixelRGB8 where+    peek p =  peekS p 3 >>= \[b,r,g] -> return (PixelRGB8 r g b)+    poke p (PixelRGB8 r g b) = pokeS p 3 [b,g,r]+    sizeOf _ = 3+    alignment _ = 0++instance Storable PixelRGB16 where+    peek p =  peekS p 3 >>= \[b,r,g] -> return (PixelRGB16 r g b)+    poke p (PixelRGB16 r g b) = pokeS p 3 [b,g,r]+    sizeOf _ = 3+    alignment _ = 0++instance Storable PixelRGBF where+    peek p =  peekS p 3 >>= \[b,r,g] -> return (PixelRGBF r g b)+    poke p (PixelRGBF r g b) = pokeS p 3 [b,g,r]+    sizeOf _ = 3+    alignment _ = 0++instance Storable PixelRGBA8 where+    peek p =  peekS p 4 >>= \[b,r,g,a] -> return (PixelRGBA8 r g b a)+    poke p (PixelRGBA8 r g b a) = pokeS p 4 [b,g,r,a]+    sizeOf _ = 4+    alignment _ = 0++instance Storable PixelRGBA16 where+    peek p =  peekS p 4 >>= \[b,r,g,a] -> return (PixelRGBA16 r g b a)+    poke p (PixelRGBA16 r g b a) = pokeS p 4 [b,g,r,a]+    sizeOf _ = 4+    alignment _ = 0++instance Storable PixelYA8 where+    peek p =  peekS p 2 >>= \[b,g] -> return (PixelYA8 b g)+    poke p (PixelYA8 b g) = pokeS p 2 [b,g]+    sizeOf _ = 2+    alignment _ = 0++instance Storable PixelYA16 where+    peek p =  peekS p 2 >>= \[b,g] -> return (PixelYA16 b g)+    poke p (PixelYA16 b g) = pokeS p 2 [b,g]+    sizeOf _ = 2+    alignment _ = 0++-- | map Pixel types to a depth+type family PixelDepth a++-- | map Pixel types to a number of channels+type family PixelChannels a :: Nat++type instance PixelDepth Pixel8      = Word8+type instance PixelDepth Pixel16     = Word16+type instance PixelDepth PixelF      = Float+type instance PixelDepth PixelYA8    = Word8+type instance PixelDepth PixelYA16   = Word16+type instance PixelDepth PixelRGB8   = Word8+type instance PixelDepth PixelRGB16  = Word16+type instance PixelDepth PixelRGBF   = Float+type instance PixelDepth PixelRGBA8  = Word8+type instance PixelDepth PixelRGBA16 = Word16+type instance PixelDepth PixelYCbCr8 = Word8+type instance PixelDepth PixelCMYK8  = Word8+type instance PixelDepth PixelCMYK16 = Word16++type instance PixelChannels Pixel8      = 1+type instance PixelChannels Pixel16     = 1+type instance PixelChannels PixelF      = 1+type instance PixelChannels PixelYA8    = 2+type instance PixelChannels PixelYA16   = 2+type instance PixelChannels PixelRGB8   = 3+type instance PixelChannels PixelRGB16  = 3+type instance PixelChannels PixelRGBF   = 3+type instance PixelChannels PixelRGBA8  = 4+type instance PixelChannels PixelRGBA16 = 4+type instance PixelChannels PixelYCbCr8 = 3+type instance PixelChannels PixelCMYK8  = 4+type instance PixelChannels PixelCMYK16 = 4++-- | An OpenCV bidimensional matrix+type Mat2D h w channels depth = Mat ('S '[h,w]) channels depth++{- | Compute an OpenCV 2D-matrix from a JuicyPixels image.++Example:++@+fromImageImg :: IO (Mat ('S '[ 'D, 'D]) ('S 3) ('S Word8))+fromImageImg = do+    r <- Codec.Picture.readImage "data/Lenna.png"+    case r of+      Left err -> error err+      Right (Codec.Picture.ImageRGB8 img) -> pure $ OpenCV.Juicy.fromImage img+      Right _ -> error "Unhandled JuicyPixels format!"+@++<<doc/generated/examples/fromImageImg.png fromImageImg>>+-}+fromImage+    :: forall a c d+     . ( ToDepth (Proxy d)+       , KnownNat c+       , Pixel a+       , Storable a+       , c ~ PixelChannels a+       , d ~ PixelDepth a+       )+    => Image a -- ^ JuicyPixels image+    -> Mat2D 'D 'D ('S c) ('S d)+fromImage i@(Image w h _data) = exceptError $ withMatM+    (fi h ::: fi w ::: Z)+    (Proxy :: Proxy c)+    (Proxy :: Proxy d)+    (pure 0 :: V4 Double) $ \m ->+      forM_ ((,) <$> [0 .. h - 1] <*> [0 .. w - 1]) $ \(x,y) ->+        unsafeWrite m [y,x] 0 (pixelAt i x y)+  where+    fi :: Int -> Int32+    fi = fromIntegral++{- | Compute a JuicyPixels image from an OpenCV 2D-matrix++FIXME: There's a bug in the colour conversions in the example:++Example:++@+toImageImg :: IO (Mat ('S '[ 'D, 'D]) ('S 3) ('S Word8))+toImageImg = exceptError . cvtColor rgb bgr . from . to . exceptError . cvtColor bgr rgb \<$> fromImageImg+  where+    to :: OpenCV.Juicy.Mat2D 'D 'D ('S 3) ('S Word8) -> Codec.Picture.Image Codec.Picture.PixelRGB8+    to = OpenCV.Juicy.toImage++    from :: Codec.Picture.Image Codec.Picture.PixelRGB8 -> OpenCV.Juicy.Mat2D 'D 'D ('S 3) ('S Word8)+    from = OpenCV.Juicy.fromImage+@++<<doc/generated/examples/toImageImg.png toImageImg>>+-}+toImage+    :: forall a c d h w.+       ( KnownNat c+       , Pixel a+       , Storable a+       , c ~ PixelChannels a+       , d ~ PixelDepth a+       )+    => Mat2D h w ('S c) ('S d)  -- ^ OpenCV 2D-matrix+    -> Image a+toImage m  = unsafePerformIO $ do+    mat <- unsafeThaw m+    withImage w h $ \x y -> unsafeRead mat [y, x] 0+  where+    MatInfo [fromIntegral -> h, fromIntegral -> w] _ _  = matInfo m++-- | An OpenCV 2D-filter preserving the matrix type+type Filter m h w c d = Mat2D h w c d -> CvExceptT m (Mat2D h w c d)++-- | Apply an OpenCV 2D-filter to a JuicyPixels dynamic matrix,+-- preserving the Juicy pixel encoding+isoJuicy+    :: forall m. (PrimMonad m)+    => (forall c d h w. Filter m h w c d) -- ^ OpenCV 2D-filter+    -> DynamicImage -- ^ JuicyPixels dynamic image+    -> CvExceptT m DynamicImage+isoJuicy f (ImageRGB8 i)    =  ImageRGB8    <$> isoApply f i+isoJuicy f (ImageRGB16 i)   =  ImageRGB16   <$> isoApply f i+isoJuicy f (ImageRGBF i)    =  ImageRGBF    <$> isoApply f i+isoJuicy f (ImageY8 i)      =  ImageY8      <$> isoApply f i+isoJuicy f (ImageY16 i)     =  ImageY16     <$> isoApply f i+isoJuicy f (ImageRGBA8 i)   =  ImageRGBA8   <$> isoApply f i+isoJuicy f (ImageRGBA16 i)  =  ImageRGBA16  <$> isoApply f i+isoJuicy _ _                =  error+    "Unhandled conversion from DynamicImage to Mat"++isoApply+    :: forall f inPixel outPixel+    . ( Functor f+      , KnownNat (PixelChannels inPixel)+      , KnownNat (PixelChannels outPixel)+      , Storable inPixel+      , Storable outPixel+      , ToDepth (Proxy (PixelDepth inPixel))+      , Pixel inPixel+      , Pixel outPixel+      )+    => (     Mat2D 'D 'D ('S (PixelChannels inPixel))  ('S (PixelDepth inPixel))+       -> f (Mat2D 'D 'D ('S (PixelChannels outPixel)) ('S (PixelDepth outPixel)))+       )+    -> (     Image inPixel+       -> f (Image outPixel)+       )+isoApply f = fmap toImage . f . fromImage
+ src/OpenCV/Photo.cpp view
@@ -0,0 +1,126 @@++#include "opencv2/core.hpp"++#include "opencv2/photo.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_Photo_0_dac42d1fe6129176553b190f2c1ab4ea3868b5ce(Mat * srcPtr_inline_c_0, Mat * inpaintMaskPtr_inline_c_1, Mat * dstPtr_inline_c_2, double cinpaintRadius_27_inline_c_3, int32_t cmethod_27_inline_c_4) {++  try+  {   +        cv::inpaint( *srcPtr_inline_c_0+                   , *inpaintMaskPtr_inline_c_1+                   , *dstPtr_inline_c_2+                   , cinpaintRadius_27_inline_c_3+                   , cmethod_27_inline_c_4+                   );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Photo_1_cdc017d1b83f0af3b77acfa9c323650631d4108c(Mat * srcPtr_inline_c_0, Mat * dstPtr_inline_c_1, double ch_27_inline_c_2, double chColor_27_inline_c_3, int32_t templateWindowSize_inline_c_4, int32_t searchWindowSize_inline_c_5) {++  try+  {   +        cv::fastNlMeansDenoisingColored( *srcPtr_inline_c_0+                                       , *dstPtr_inline_c_1+                                       , ch_27_inline_c_2+                                       , chColor_27_inline_c_3+                                       , templateWindowSize_inline_c_4+                                       , searchWindowSize_inline_c_5+                                       );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Photo_2_21eb93edb3c09c34ee63f35f5649016ca5df8b0b(Mat * srcVecPtr_inline_c_0, Mat * srcVecPtr_inline_c_1, int32_t ctemporalWindowSize_27_inline_c_2, Mat * dstPtr_inline_c_3, int32_t cimgToDenoiseIndex_27_inline_c_4, int32_t ctemporalWindowSize_27_inline_c_5, double ch_27_inline_c_6, double chColor_27_inline_c_7, int32_t templateWindowSize_inline_c_8, int32_t searchWindowSize_inline_c_9) {++  try+  {   +        std::vector<Mat> buffer( srcVecPtr_inline_c_0+                    , srcVecPtr_inline_c_1 + ctemporalWindowSize_27_inline_c_2 );+        cv::fastNlMeansDenoisingColoredMulti( buffer+                                            , *dstPtr_inline_c_3+                                            , cimgToDenoiseIndex_27_inline_c_4+                                            , ctemporalWindowSize_27_inline_c_5+                                            , ch_27_inline_c_6+                                            , chColor_27_inline_c_7+                                            , templateWindowSize_inline_c_8+                                            , searchWindowSize_inline_c_9+                                            );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Photo_3_1c316b2af4a9f9c007f326e4f4a13fc675613477(Mat * srcVecPtr_inline_c_0, Mat * srcVecPtr_inline_c_1, int32_t csrcVecLength_27_inline_c_2, Mat * dstPtr_inline_c_3, double clambda_27_inline_c_4, int32_t niters_inline_c_5) {++  try+  {   +        std::vector<Mat> buffer( srcVecPtr_inline_c_0+                           , srcVecPtr_inline_c_1 + csrcVecLength_27_inline_c_2 );+        cv::denoise_TVL1( buffer+                        , *dstPtr_inline_c_3+                        , clambda_27_inline_c_4+                        , niters_inline_c_5+                        );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_Photo_4_fe1aedf09e63d5faa9a1c3ef9ba438b9c607a8fb(Mat * srcPtr_inline_c_0, Mat * grayPtr_inline_c_1, Mat * boostPtr_inline_c_2) {++  try+  {   +        cv::decolor( *srcPtr_inline_c_0+                   , *grayPtr_inline_c_1+                   , *boostPtr_inline_c_2+                   );+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/Photo.hs view
@@ -0,0 +1,369 @@+{-# language CPP #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}++#if __GLASGOW_HASKELL__ >= 800+{-# options_ghc -Wno-redundant-constraints #-}+#endif++module OpenCV.Photo+  ( InpaintingMethod(..)+  , decolor+  , inpaint+  , denoise_TVL1+  , fastNlMeansDenoisingColored+  , fastNlMeansDenoisingColoredMulti+  ) where++import "base" Data.Int ( Int32 )+import "base" Data.Word ( Word8 )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types ( withPtr )+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.Photo.Constants+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Core.Types ( withArrayPtr )+import "this" OpenCV.TypeLevel++import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/photo.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------++data InpaintingMethod+   = InpaintNavierStokes+     -- ^ Navier-Stokes based method.+   | InpaintTelea+     -- ^ Method by Alexandru Telea.+     deriving Show++marshalInpaintingMethod :: InpaintingMethod -> Int32+marshalInpaintingMethod = \case+  InpaintNavierStokes -> c'INPAINT_NS+  InpaintTelea        -> c'INPAINT_TELEA++{- | Restores the selected region in an image using the region neighborhood.++Example:++@+inpaintImg+    :: forall h h2 w w2 c d+     . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Bikes_512x341+       , h2 ~ ((*) h 2)+       , w2 ~ ((*) w 2)+       )+    => Mat ('S ['S h2, 'S w2]) ('S c) ('S d)+inpaintImg = exceptError $ do+    maskInv <- bitwiseNot mask+    maskBgr <- cvtColor gray bgr maskInv+    damaged <- bitwiseAnd bikes_512x341 maskBgr+    repairedNS <- inpaint 3 InpaintNavierStokes damaged mask+    repairedT  <- inpaint 3 InpaintTelea        damaged mask+    withMatM+      (Proxy :: Proxy [h2, w2])+      (Proxy :: Proxy c)+      (Proxy :: Proxy d)+      black $ \\imgM -> do+        matCopyToM imgM (V2 0 0) damaged Nothing+        matCopyToM imgM (V2 w 0) maskBgr Nothing+        matCopyToM imgM (V2 0 h) repairedNS Nothing+        matCopyToM imgM (V2 w h) repairedT  Nothing+  where+    mask = damageMask++    w = fromInteger $ natVal (Proxy :: Proxy w)+    h = fromInteger $ natVal (Proxy :: Proxy h)+@++<<doc/generated/examples/inpaintImg.png inpaintImg>>+-}+inpaint+   :: (channels `In` [1, 3])+   => Double+      -- ^ inpaintRadius - Radius of a circular neighborhood of each+      -- point inpainted that is considered by the algorithm.+   -> InpaintingMethod+   -> Mat ('S [h, w]) ('S channels) ('S Word8) -- ^ Input image.+   -> Mat ('S [h, w]) ('S 1) ('S Word8) -- ^ Inpainting mask.+   -> CvExcept (Mat ('S [h, w]) ('S channels) ('S Word8)) -- ^ Output image.+inpaint inpaintRadius method src inpaintMask = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src         $ \srcPtr         ->+      withPtr inpaintMask $ \inpaintMaskPtr ->+      withPtr dst         $ \dstPtr         ->+      [cvExcept|+        cv::inpaint( *$(Mat * srcPtr)+                   , *$(Mat * inpaintMaskPtr)+                   , *$(Mat * dstPtr)+                   , $(double c'inpaintRadius)+                   , $(int32_t c'method)+                   );+      |]+  where+    c'method = marshalInpaintingMethod method+    c'inpaintRadius = realToFrac inpaintRadius++{- | Perform fastNlMeansDenoising function for colored images. Denoising is not+     per channel but in a different colour space++Example:++@+fastNlMeansDenoisingColoredImg+    :: forall h w w2 c d+     . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Lenna_512x512+       , w2 ~ ((*) w 2)+       )+    => Mat ('S ['S h, 'S w2]) ('S c) ('S d)+fastNlMeansDenoisingColoredImg = exceptError $ do+    denoised <- fastNlMeansDenoisingColored 3 10 7 21 lenna_512x512+    withMatM+      (Proxy :: Proxy [h, w2])+      (Proxy :: Proxy c)+      (Proxy :: Proxy d)+      black $ \\imgM -> do+        matCopyToM imgM (V2 0 0) lenna_512x512 Nothing+        matCopyToM imgM (V2 w 0) denoised Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy w)+@++<<doc/generated/examples/fastNlMeansDenoisingColoredImg.png fastNlMeansDenoisingColoredImg>>+-}++fastNlMeansDenoisingColored+   :: Double -- ^ Parameter regulating filter strength for luminance component.+             -- Bigger h value perfectly removes noise but also removes image+             -- details, smaller h value preserves details but also preserves+             -- some noise+   -> Double -- ^ The same as h but for color components. For most images value+             -- equals 10 will be enough to remove colored noise and do not+             -- distort colors+   -> Int32  -- ^ templateWindowSize Size in pixels of the template patch that+             -- is used to compute weights.+             -- Should be odd. Recommended value 7 pixels+   -> Int32  -- ^ searchWindowSize. Size in pixels of the window that is used+             -- to compute weighted average for given pixel. Should be odd.+             -- Affect performance linearly: greater searchWindowsSize+             -- - greater denoising time. Recommended value 21 pixels+   -> Mat ('S [h, w]) ('S 3) ('S Word8) -- ^ Input image 8-bit 3-channel image.+   -> CvExcept (Mat ('S [h, w]) ('S 3) ('S Word8))+             -- ^ Output image same size and type as input.+fastNlMeansDenoisingColored h hColor templateWindowSize searchWindowSize src =+  unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withPtr src         $ \srcPtr         ->+      withPtr dst         $ \dstPtr         ->+      [cvExcept|+        cv::fastNlMeansDenoisingColored( *$(Mat * srcPtr)+                                       , *$(Mat * dstPtr)+                                       , $(double c'h)+                                       , $(double c'hColor)+                                       , $(int32_t templateWindowSize)+                                       , $(int32_t searchWindowSize)+                                       );+      |]+  where+    c'h = realToFrac h+    c'hColor = realToFrac hColor++{- | Perform fastNlMeansDenoisingColoredMulti function for colored images.+     Denoising is not pre channel but in a different colour space.+     This wrapper differs from the original OpenCV version by using all input+     images and denoising the middle one. The original version would allow+     to have some arbitrary length vector and slide window over it. As we have+     to copy the haskell vector before we can use it as `std::vector` on the cpp+     side it is easier to trim the vector before sending and use all frames.++Example:++@+fastNlMeansDenoisingColoredMultiImg+    :: forall h w w2 c d+     . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Lenna_512x512+       , w2 ~ ((*) w 2)+       )+    => Mat ('S ['S h, 'S w2]) ('S c) ('S d)+fastNlMeansDenoisingColoredMultiImg = exceptError $ do+    denoised <- fastNlMeansDenoisingColoredMulti 3 10 7 21 (V.singleton lenna_512x512)+    withMatM+      (Proxy :: Proxy [h, w2])+      (Proxy :: Proxy c)+      (Proxy :: Proxy d)+      black $ \\imgM -> do+        matCopyToM imgM (V2 0 0) lenna_512x512 Nothing+        matCopyToM imgM (V2 w 0) denoised Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy w)+@++<<doc/generated/examples/fastNlMeansDenoisingColoredMultiImg.png fastNlMeansDenoisingColoredMultiImg>>+-}++fastNlMeansDenoisingColoredMulti+   :: Double -- ^ Parameter regulating filter strength for luminance component.+             -- Bigger h value perfectly removes noise but also removes image+             -- details, smaller h value preserves details but also preserves+             -- some noise+   -> Double -- ^ The same as h but for color components. For most images value+             -- equals 10 will be enough to remove colored noise and do not+             -- distort colors+   -> Int32  -- ^ templateWindowSize Size in pixels of the template patch that+             -- is used to compute weights. Should be odd.+             -- Recommended value 7 pixels+   -> Int32  -- ^ searchWindowSize. Size in pixels of the window that is used to+             -- compute weighted average for given pixel. Should be odd.+             -- Affect performance linearly: greater searchWindowsSize -+             -- greater denoising time. Recommended value 21 pixels+   -> V.Vector (Mat ('S [h, w]) ('S 3) ('S Word8))+             -- ^ Vector of odd number of input 8-bit 3-channel images.+   -> CvExcept (Mat ('S [h, w]) ('S 3) ('S Word8))+             -- ^ Output image same size and type as input.++fastNlMeansDenoisingColoredMulti h hColor templateWindowSize searchWindowSize srcVec =+  unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withArrayPtr srcVec $ \srcVecPtr      ->+      withPtr dst         $ \dstPtr         ->+      [cvExcept|+        std::vector<Mat> buffer( $(Mat * srcVecPtr)+                    , $(Mat * srcVecPtr) + $(int32_t c'temporalWindowSize) );+        cv::fastNlMeansDenoisingColoredMulti( buffer+                                            , *$(Mat * dstPtr)+                                            , $(int32_t c'imgToDenoiseIndex)+                                            , $(int32_t c'temporalWindowSize)+                                            , $(double c'h)+                                            , $(double c'hColor)+                                            , $(int32_t templateWindowSize)+                                            , $(int32_t searchWindowSize)+                                            );+      |]+  where+    c'h = realToFrac h+    c'hColor = realToFrac hColor+    c'srcVecLength = fromIntegral $ V.length srcVec+    -- if it is not odd we drop the last image+    c'temporalWindowSize+        | c'srcVecLength `mod` 2 == 1 = c'srcVecLength+        | otherwise                   = c'srcVecLength - 1+    c'imgToDenoiseIndex = (c'temporalWindowSize - 1) `div` 2++{- | Perform denoise_TVL1++Example:++@++denoise_TVL1Img+    :: forall h w w2 c d+     . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Lenna_512x512+       , w2 ~ ((*) w 2)+       )+    => Mat ('S ['S h, 'S w2]) ('S c) ('S d)+denoise_TVL1Img = exceptError $ do+    denoised <- matChannelMapM (denoise_TVL1 2 50 . V.singleton) lenna_512x512+    withMatM+      (Proxy :: Proxy [h, w2])+      (Proxy :: Proxy c)+      (Proxy :: Proxy d)+      black $ \\imgM -> do+        matCopyToM imgM (V2 0 0) lenna_512x512 Nothing+        matCopyToM imgM (V2 w 0) denoised Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy w)+@++<<doc/generated/examples/denoise_TVL1Img.png denoise_TVL1Img>>+-}++denoise_TVL1+   :: Double -- ^ details more is more 2+   -> Int32  -- ^ Number of iterations that the algorithm will run+   -> V.Vector (Mat ('S [h, w]) ('S 1) ('S Word8))+             -- ^ Vector of odd number of input 8-bit 3-channel images.+   -> CvExcept (Mat ('S [h, w]) ('S 1) ('S Word8))+             -- ^ Output image same size and type as input.++denoise_TVL1 lambda niters srcVec = unsafeWrapException $ do+    dst <- newEmptyMat+    handleCvException (pure $ unsafeCoerceMat dst) $+      withArrayPtr srcVec $ \srcVecPtr      ->+      withPtr dst         $ \dstPtr         ->+      [cvExcept|+        std::vector<Mat> buffer( $(Mat * srcVecPtr)+                           , $(Mat * srcVecPtr) + $(int32_t c'srcVecLength) );+        cv::denoise_TVL1( buffer+                        , *$(Mat * dstPtr)+                        , $(double c'lambda)+                        , $(int32_t niters)+                        );+      |]+  where+    c'lambda = realToFrac lambda+    c'srcVecLength = fromIntegral $ V.length srcVec+++{- | Perform decolor++Decolor a color image to a grayscale (1 channel) and a color boosted image (3 channel)++Example:++@+decolorImg+    :: forall h h2 w w2 c d+     . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Bikes_512x341+       , h2 ~ ((*) h 2)+       , w2 ~ ((*) w 2)+       )+    => Mat ('S ['S h2, 'S w2]) ('S c) ('S d)+decolorImg = exceptError $ do+    (bikesGray, boost) <- decolor bikes_512x341+    colorGray <- cvtColor gray bgr bikesGray+    withMatM+      (Proxy :: Proxy [h2, w2])+      (Proxy :: Proxy c)+      (Proxy :: Proxy d)+      white $ \\imgM -> do+        matCopyToM imgM (V2 0 0) bikes_512x341 Nothing+        matCopyToM imgM (V2 0 h) colorGray Nothing+        matCopyToM imgM (V2 w h) boost  Nothing+  where+    w = fromInteger $ natVal (Proxy :: Proxy w)+    h = fromInteger $ natVal (Proxy :: Proxy h)+@++<<doc/generated/examples/decolorImg.png decolorImg>>+-}++decolor+   :: Mat ('S [h, w]) ('S 3) ('S Word8) -- ^ Input image.+   -> CvExcept (Mat ('S [h, w]) ('S 1) ('S Word8), Mat ('S [h, w]) ('S 3) ('S Word8)) -- ^ Output images.++decolor src = unsafeWrapException $ do+    gray <- newEmptyMat+    boost <- newEmptyMat++    handleCvException (pure (unsafeCoerceMat gray, unsafeCoerceMat boost)) $+      withPtr src         $ \srcPtr         ->+      withPtr gray        $ \grayPtr        ->+      withPtr boost       $ \boostPtr       ->+      [cvExcept|+        cv::decolor( *$(Mat * srcPtr)+                   , *$(Mat * grayPtr)+                   , *$(Mat * boostPtr)+                   );+      |]
+ src/OpenCV/TypeLevel.hs view
@@ -0,0 +1,185 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}++{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}++module OpenCV.TypeLevel+    ( -- * Kinds and types+      DS(D, S), dsToMaybe+    , Z(Z)+    , (:::)((:::))++      -- * Type level to value level conversions+    , ToInt32(toInt32)+    , ToNatDS(toNatDS)+    , ToNatListDS(toNatListDS)++      -- * Type functions+    , Length+    , Elem+    , Relax++      -- ** Predicates (constraints)+    , In+    , MayRelax+    , All+    , IsStatic++      -- ** Type conversions+    , DSNat+    , DSNats+    ) where++import "base" Data.Int+import "base" Data.Proxy+import "base" Data.Type.Bool+import "base" GHC.Exts ( Constraint )+import "base" GHC.TypeLits++--------------------------------------------------------------------------------+-- Kinds and types+--------------------------------------------------------------------------------++-- | 'D'ynamically or 'S'tatically known values+--+-- Mainly used as a promoted type.+--+-- Operationally exactly the 'Maybe' type+data DS a+   = D   -- ^ Something is dynamically known+   | S a -- ^ Something is statically known, in particular: @a@+     deriving (Show, Eq, Functor)++-- | Converts a DS value to the corresponding Maybe value+dsToMaybe :: DS a -> Maybe a+dsToMaybe D     = Nothing+dsToMaybe (S a) = Just a++-- | End of list+data Z = Z++-- | Heterogeneous lists+--+-- Implemented as nested 2-tuples.+--+-- > f :: Int ::: Bool ::: Char ::: Z+-- > f = 3 ::: False ::: 'X' ::: Z+data a ::: b = a ::: b++infixr 5 :::+++--------------------------------------------------------------------------------+-- Type level to value level conversions+--------------------------------------------------------------------------------++class ToInt32 a where+    toInt32 :: a -> Int32++-- | value level: identity+instance ToInt32 Int32 where+    toInt32 = id++-- | type level: reify the known natural number @n@+instance (KnownNat n) => ToInt32 (proxy n) where+    toInt32 = fromInteger . natVal++--------------------------------------------------------------------------------++-- | Type level to value level conversion of numbers that are either+-- 'D'ynamically or 'S'tatically known.+--+-- > toNatDS (Proxy ('S 42)) == S 42+-- > toNatDS (Proxy 'D) == D+class ToNatDS a where+    toNatDS :: a -> DS Int32++-- | value level numbers are dynamically known+instance ToNatDS (proxy 'D) where+    toNatDS _proxy = D++-- | type level numbers are statically known+instance (ToInt32 (Proxy n)) => ToNatDS (Proxy ('S n)) where+    toNatDS _proxy = S $ toInt32 (Proxy :: Proxy n)++--------------------------------------------------------------------------------++class ToNatListDS a where+    toNatListDS :: a -> [DS Int32]++instance ToNatListDS (proxy '[]) where+    toNatListDS _proxy = []++instance (ToNatDS (Proxy a), ToNatListDS (Proxy as))+      => ToNatListDS (Proxy (a ': as)) where+    toNatListDS _proxy = (toNatDS     (Proxy :: Proxy a ))+                       : (toNatListDS (Proxy :: Proxy as))++--------------------------------------------------------------------------------+-- Type functions+--------------------------------------------------------------------------------++type family Length (xs :: [a]) :: Nat where+    Length '[]        = 0+    Length (_x ': xs) = 1 + Length xs++type family Elem (e :: a) (xs :: [a]) :: Bool where+    Elem _e '[]         = 'False+    Elem  e (e  ': _xs) = 'True+    Elem  e (_x ':  xs) = Elem e xs++type In e xs = Elem e xs ~ 'True++type family DSNat (a :: ka) :: DS Nat where+    DSNat Integer    = 'D+    DSNat Int32      = 'D+    DSNat (Proxy n)  = 'S n+    DSNat (n :: Nat) = 'S n++type family DSNats (a :: ka) :: [DS Nat] where+    DSNats Z          = '[]+    DSNats (x ::: xs) = DSNat x ': DSNats xs++    DSNats ('[] :: [Nat]) = '[]+    DSNats (x ': xs)      = DSNat x ': DSNats xs++type family Relax (a :: DS ka) (b :: DS kb) :: Bool where+    Relax x      'D     = 'True+    Relax ('S (x ': xs)) ('S (y ': ys)) = Relax x y && Relax ('S xs) ('S ys)+    Relax ('S x) ('S y) = Relax x y+    Relax x      x      = 'True+    Relax x      y      = 'False++type MayRelax a b = Relax a b ~ 'True++-- type family LeDS_F (a :: Nat) (b :: DS Nat) :: Bool where+--     LeDS_F _a 'D     = 'True+--     LeDS_F  a ('S b) = a <=? b++-- type (.<=?) a b = LeDS_F a b ~ 'True++-- type LE a b = a <=? b ~ True+-- type GT a b = b <=? a ~ True+++-- type family LengthDS (as :: DS [k]) :: DS Nat where+--     LengthDS 'D = 'D+--     LengthDS ('S xs) = 'S (Length xs)++-- type family MinLengthDS_F (a :: Nat) (bs :: DS [k]) :: Bool where+--     MinLengthDS_F _a 'D = 'True+--     MinLengthDS_F  a bs = LeDS_F a (LengthDS bs)++-- type MinLengthDS a bs = MinLengthDS_F a bs ~ 'True++class PrivateIsStatic (ds :: DS a)+instance PrivateIsStatic ('S a)++class All (p :: k -> Constraint) (xs :: [k])+instance All p '[]+instance (p x, All p xs) => All p (x ': xs)++class (PrivateIsStatic ds) => IsStatic (ds :: DS a)+instance IsStatic ('S a)
+ src/OpenCV/Unsafe.hs view
@@ -0,0 +1,43 @@+module OpenCV.Unsafe+    ( unsafeCoerceMat+    , unsafeCoerceMatM+      -- * Mutable Matrix+    , unsafeFreeze+    , unsafeThaw+    , unsafeRead+    , unsafeWrite+    ) where++import "base" Foreign.Ptr ( plusPtr )+import "base" Foreign.Storable ( Storable, peek, poke, sizeOf )+import "primitive" Control.Monad.Primitive+    ( PrimMonad, PrimState, unsafePrimToPrim )+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Mutable++unsafeRead+    :: forall m shape channels depth value+     . (PrimMonad m, Storable value)+    => Mut (Mat shape channels depth) (PrimState m)+    -> [Int] -- ^ position+    -> Int -- ^ channel+    -> m value+unsafeRead matM pos channel =+    unsafePrimToPrim $ withMatData (unMut matM) $ \step dataPtr ->+      let elemPtr = matElemAddress dataPtr (fromIntegral <$> step) pos+      in peek (elemPtr `plusPtr` (channel * sizeOf dummyValue))+  where+    dummyValue :: value+    dummyValue = error "dummy"++unsafeWrite+    :: (PrimMonad m, Storable value)+    => Mut (Mat shape channels depth) (PrimState m)+    -> [Int] -- ^ position+    -> Int -- ^ channel+    -> value+    -> m ()+unsafeWrite matM pos channel value =+    unsafePrimToPrim $ withMatData (unMut matM) $ \step dataPtr ->+      let elemPtr = matElemAddress dataPtr (fromIntegral <$> step) pos+      in poke (elemPtr `plusPtr` (channel * sizeOf value)) value
+ src/OpenCV/Video.cpp view
@@ -0,0 +1,30 @@++#include "opencv2/core.hpp"++#include "opencv2/video.hpp"++using namespace cv;++extern "C" {+Exception * inline_c_OpenCV_Video_0_c7a068d39e7de16608cca36fb2c18a26ebc396dd(Mat * matOutPtr_inline_c_0, Point2i * srcPtr_inline_c_1, int32_t csrcLen_27_inline_c_2, Point2i * dstPtr_inline_c_3, int32_t cdstLen_27_inline_c_4, bool cfullAffine_27_inline_c_5) {++  try+  {   +            Mat * matOutPtr = matOutPtr_inline_c_0;+            *matOutPtr =+               cv::estimateRigidTransform+               ( cv::_InputArray(srcPtr_inline_c_1, csrcLen_27_inline_c_2)+               , cv::_InputArray(dstPtr_inline_c_3, cdstLen_27_inline_c_4)+               , cfullAffine_27_inline_c_5+               );+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}
+ src/OpenCV/Video.hsc view
@@ -0,0 +1,77 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.Video+    ( -- * Motion Analysis and Object Tracking+      estimateRigidTransform+    ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.Marshal.Utils ( fromBool )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Core.Types.Point+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.Exception+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/video.hpp"+C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/video.hpp"++--------------------------------------------------------------------------------++-- | Computes an optimal affine transformation between two 2D point sets+--+-- <http://docs.opencv.org/3.0-last-rst/modules/video/doc/motion_analysis_and_object_tracking.html#estimaterigidtransform OpenCV Sphinx doc>+estimateRigidTransform+    :: ( IsPoint2 srcPoint2 Int32+       , IsPoint2 dstPoint2 Int32+       )+    => V.Vector (srcPoint2 Int32) -- ^ Source+    -> V.Vector (dstPoint2 Int32) -- ^ Destination+    -> Bool -- ^ Full affine+    -> CvExcept (Maybe (Mat (ShapeT [2, 3]) ('S 1) ('S Double)))+estimateRigidTransform src dst fullAffine = do+    result <- c'estimateRigidTransform+    -- If the c++ function can't estimate a rigid transform it will+    -- return an empty matrix. We check for this case by trying to+    -- coerce the result to the desired type.+    catchE (Just <$> coerceMat result)+           (\case CoerceMatError _msgs -> pure Nothing+                  otherError -> throwE otherError+           )+  where+    c'estimateRigidTransform = unsafeWrapException $ do+      matOut <- newEmptyMat+      handleCvException (pure matOut) $+        withArrayPtr (V.map toPoint src) $ \srcPtr ->+        withArrayPtr (V.map toPoint dst) $ \dstPtr ->+        withPtr matOut $ \matOutPtr ->+          [cvExcept|+            Mat * matOutPtr = $(Mat * matOutPtr);+            *matOutPtr =+               cv::estimateRigidTransform+               ( cv::_InputArray($(Point2i * srcPtr), $(int32_t c'srcLen))+               , cv::_InputArray($(Point2i * dstPtr), $(int32_t c'dstLen))+               , $(bool c'fullAffine)+               );+          |]++    c'srcLen     = fromIntegral $ V.length src+    c'dstLen     = fromIntegral $ V.length dst+    c'fullAffine = fromBool fullAffine
+ src/OpenCV/Video/MotionAnalysis.cpp view
@@ -0,0 +1,150 @@++#include "opencv2/core.hpp"++#include "opencv2/video.hpp"++#include "video_motion_analysis.hpp"++using namespace cv;++extern "C" {+Ptr_BackgroundSubtractorKNN * inline_c_OpenCV_Video_MotionAnalysis_0_0a0b275740813683c1bfed73969c25c494b46b98(int32_t chistory_27_inline_c_0, double cdist2Threshold_27_inline_c_1, bool cdetectShadows_27_inline_c_2) {++      cv::Ptr<cv::BackgroundSubtractorKNN> knnPtr =+        cv::createBackgroundSubtractorKNN+        ( chistory_27_inline_c_0+        , cdist2Threshold_27_inline_c_1+        , cdetectShadows_27_inline_c_2+        );+      return new cv::Ptr<cv::BackgroundSubtractorKNN>(knnPtr);+    +}++}++extern "C" {+Ptr_BackgroundSubtractorMOG2 * inline_c_OpenCV_Video_MotionAnalysis_1_6bd1934e204ea96bb8aa587f6a5548311105c7e1(int32_t chistory_27_inline_c_0, double cvarThreshold_27_inline_c_1, bool cdetectShadows_27_inline_c_2) {++      cv::Ptr<cv::BackgroundSubtractorMOG2> mog2Ptr =+        cv::createBackgroundSubtractorMOG2+        ( chistory_27_inline_c_0+        , cvarThreshold_27_inline_c_1+        , cdetectShadows_27_inline_c_2+        );+      return new cv::Ptr<cv::BackgroundSubtractorMOG2>(mog2Ptr);+    +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_2_4a6f75be46ee9ae7f66ce94ff11f820f90a0920e(Ptr_BackgroundSubtractorMOG2 * mog2Ptr_inline_c_0, Mat * imgPtr_inline_c_1, Mat * fgMaskPtr_inline_c_2, double clearningRate_27_inline_c_3) {++              cv::BackgroundSubtractorMOG2 * mog2 = *mog2Ptr_inline_c_0;+              mog2->apply+              ( *imgPtr_inline_c_1+              , *fgMaskPtr_inline_c_2+              , clearningRate_27_inline_c_3+              );+            +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_3_dd637d33bcb924803904d88fe7ac6404770cb2c2(Ptr_BackgroundSubtractorMOG2 * mog2Ptr_inline_c_0, Mat * imgPtr_inline_c_1) {++              cv::BackgroundSubtractorMOG2 * mog2 = *mog2Ptr_inline_c_0;+              mog2->getBackgroundImage(*imgPtr_inline_c_1);+            +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_4_e309b886cafe1283f14b5556398e8236e0b09791(Ptr_BackgroundSubtractorKNN * knnPtr_inline_c_0, Mat * imgPtr_inline_c_1, Mat * fgMaskPtr_inline_c_2, double clearningRate_27_inline_c_3) {++              cv::BackgroundSubtractorKNN * knn = *knnPtr_inline_c_0;+              knn->apply+              ( *imgPtr_inline_c_1+              , *fgMaskPtr_inline_c_2+              , clearningRate_27_inline_c_3+              );+            +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_5_acc3fe34d3592ae448faa1c398acf9aefbe9cdbf(Ptr_BackgroundSubtractorKNN * knnPtr_inline_c_0, Mat * imgPtr_inline_c_1) {++              cv::BackgroundSubtractorKNN * knn = *knnPtr_inline_c_0;+              knn->getBackgroundImage(*imgPtr_inline_c_1);+            +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_6_31db6e29933a955292a26fc8a2f21656f0264fc0(Ptr_BackgroundSubtractorMOG2 * mog2Ptr_inline_c_0) {++              cv::BackgroundSubtractorMOG2 * mog2 = *mog2Ptr_inline_c_0;+              mog2->clear();+          +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_7_778ae04bc23f9731f5715891f6c00c2e233cfae3(Ptr_BackgroundSubtractorMOG2 * mog2Ptr_inline_c_0, bool * emptyPtr_inline_c_1) {++              cv::BackgroundSubtractorMOG2 * mog2 = *mog2Ptr_inline_c_0;+              *emptyPtr_inline_c_1 = mog2->empty();+          +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_8_6d32d18fa950d5c3ad83fd26ae6d6fb09e7a8372(Ptr_BackgroundSubtractorKNN * knnPtr_inline_c_0) {++              cv::BackgroundSubtractorKNN * knn = *knnPtr_inline_c_0;+              knn->clear();+          +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_9_7be48f700e60c4da4e297a30717dc1fb9252896c(Ptr_BackgroundSubtractorKNN * knnPtr_inline_c_0, bool * emptyPtr_inline_c_1) {++              cv::BackgroundSubtractorKNN * knn = *knnPtr_inline_c_0;+              *emptyPtr_inline_c_1 = knn->empty();+          +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_10_c5f690e42d74da8f96ffec2e1798eec5b52382be(Ptr_BackgroundSubtractorMOG2 * ptr_inline_c_0) {++                  cv::Ptr<cv::BackgroundSubtractorMOG2> * mog2_ptr_ptr =+                    ptr_inline_c_0;+                  mog2_ptr_ptr->release();+                  delete mog2_ptr_ptr;+                +}++}++extern "C" {+void inline_c_OpenCV_Video_MotionAnalysis_11_27d85d129e9b7f1552b33141a9a7575fe19563bc(Ptr_BackgroundSubtractorKNN * ptr_inline_c_0) {++                  cv::Ptr<cv::BackgroundSubtractorKNN> * knn_ptr_ptr =+                    ptr_inline_c_0;+                  knn_ptr_ptr->release();+                  delete knn_ptr_ptr;+                +}++}
+ src/OpenCV/Video/MotionAnalysis.hsc view
@@ -0,0 +1,287 @@+{-# language TemplateHaskell #-}+{-# language QuasiQuotes #-}++module OpenCV.Video.MotionAnalysis+    ( -- * BackgroundSubtractor+      BackgroundSubtractor(..)+      -- * Background subtractors+    , BackgroundSubtractorMOG2+    , BackgroundSubtractorKNN+    , newBackgroundSubtractorKNN+    , newBackgroundSubtractorMOG2+    ) where++import "base" Control.Exception ( mask_ )+import "base" Data.Int+import "base" Data.Maybe+import "base" Data.Word+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Marshal.Alloc ( alloca )+import "base" Foreign.Marshal.Utils ( fromBool, toBool )+import "base" Foreign.Storable ( peek )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "primitive" Control.Monad.Primitive+import "this" OpenCV.Core.Types+import "this" OpenCV.Internal+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.TypeLevel++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/video.hpp"+C.include "video_motion_analysis.hpp"++C.using "namespace cv"++#include <bindings.dsl.h>+#include "opencv2/core.hpp"+#include "opencv2/video.hpp"++#include "namespace.hpp"+#include "video_motion_analysis.hpp"++--------------------------------------------------------------------------------+-- BackgroundSubtractor+--------------------------------------------------------------------------------++class BackgroundSubtractor a where+    bgSubApply+        :: (PrimMonad m)+        => a (PrimState m)+        -> Double+           -- ^ The value between 0 and 1 that indicates how fast the background+           -- model is learnt. Negative parameter value makes the algorithm to+           -- use some automatically chosen learning rate. 0 means that the+           -- background model is not updated at all, 1 means that the+           -- background model is completely reinitialized from the last frame.+        -> Mat ('S [h, w]) channels depth+           -- ^ Next video frame.+        -> m (Mat ('S [h, w]) ('S 1) ('S Word8))+           -- ^ The output foreground mask as an 8-bit binary image.++    getBackgroundImage+        :: (PrimMonad m)+        => a (PrimState m)+        -> m (Mat ('S [h, w]) channels depth)+           -- ^ The output background image.++{- |++Example:++@+carAnim :: Animation (ShapeT [240, 320]) ('S 3) ('S Word8)+carAnim = carOverhead++mog2Anim :: IO (Animation (ShapeT [240, 320]) ('S 3) ('S Word8))+mog2Anim = do+    mog2 <- newBackgroundSubtractorMOG2 Nothing Nothing Nothing+    forM carOverhead $ \(delay, img) -> do+      fg <- bgSubApply mog2 0.1 img+      fgBgr <- exceptErrorIO $ pureExcept $ cvtColor gray bgr fg+      pure (delay, fgBgr)+@++Original:+<<doc/generated/examples/car.gif carAnim>>++Foreground:+<<doc/generated/examples/mog2.gif mog2Anim>>+-}++--------------------------------------------------------------------------------+-- Background subtractors+--------------------------------------------------------------------------------++newtype BackgroundSubtractorKNN s+      = BackgroundSubtractorKNN+        { unBackgroundSubtractorKNN :: ForeignPtr C'Ptr_BackgroundSubtractorKNN }++newtype BackgroundSubtractorMOG2 s+      = BackgroundSubtractorMOG2+        { unBackgroundSubtractorMOG2 :: ForeignPtr C'Ptr_BackgroundSubtractorMOG2 }++type instance C (BackgroundSubtractorKNN  s) = C'Ptr_BackgroundSubtractorKNN+type instance C (BackgroundSubtractorMOG2 s) = C'Ptr_BackgroundSubtractorMOG2++instance WithPtr (BackgroundSubtractorKNN s) where+    withPtr = withForeignPtr . unBackgroundSubtractorKNN++instance WithPtr (BackgroundSubtractorMOG2 s) where+    withPtr = withForeignPtr . unBackgroundSubtractorMOG2++instance FromPtr (BackgroundSubtractorKNN s) where+    fromPtr = objFromPtr BackgroundSubtractorKNN $ \ptr ->+                [CU.block| void {+                  cv::Ptr<cv::BackgroundSubtractorKNN> * knn_ptr_ptr =+                    $(Ptr_BackgroundSubtractorKNN * ptr);+                  knn_ptr_ptr->release();+                  delete knn_ptr_ptr;+                }|]++instance FromPtr (BackgroundSubtractorMOG2 s) where+    fromPtr = objFromPtr BackgroundSubtractorMOG2 $ \ptr ->+                [CU.block| void {+                  cv::Ptr<cv::BackgroundSubtractorMOG2> * mog2_ptr_ptr =+                    $(Ptr_BackgroundSubtractorMOG2 * ptr);+                  mog2_ptr_ptr->release();+                  delete mog2_ptr_ptr;+                }|]++--------------------------------------------------------------------------------++newBackgroundSubtractorKNN+    :: (PrimMonad m)+    => Maybe Int32+       -- ^ Length of the history.+    -> Maybe Double+       -- ^ Threshold on the squared distance between the pixel and the sample+       -- to decide whether a pixel is close to that sample. This parameter does+       -- not affect the background update.+    -> Maybe Bool+       -- ^ If 'True', the algorithm will detect shadows and mark them. It+       -- decreases the speed a bit, so if you do not need this feature, set the+       -- parameter to 'False'.+    -> m (BackgroundSubtractorKNN (PrimState m))+newBackgroundSubtractorKNN mbHistory mbDist2Threshold mbDetectShadows = unsafePrimToPrim $ fromPtr+    [CU.block|Ptr_BackgroundSubtractorKNN * {+      cv::Ptr<cv::BackgroundSubtractorKNN> knnPtr =+        cv::createBackgroundSubtractorKNN+        ( $(int32_t c'history       )+        , $(double  c'dist2Threshold)+        , $(bool    c'detectShadows )+        );+      return new cv::Ptr<cv::BackgroundSubtractorKNN>(knnPtr);+    }|]+  where+    c'history        = fromMaybe 500 mbHistory+    c'dist2Threshold = maybe 400 realToFrac mbDist2Threshold+    c'detectShadows  = fromBool $ fromMaybe True mbDetectShadows++newBackgroundSubtractorMOG2+    :: (PrimMonad m)+    => Maybe Int32+       -- ^ Length of the history.+    -> Maybe Double+       -- ^ Threshold on the squared Mahalanobis distance between the pixel and+       -- the model to decide whether a pixel is well described by the+       -- background model. This parameter does not affect the background+       -- update.+    -> Maybe Bool+       -- ^ If 'True', the algorithm will detect shadows and mark them. It+       -- decreases the speed a bit, so if you do not need this feature, set the+       -- parameter to 'False'.+    -> m (BackgroundSubtractorMOG2 (PrimState m))+newBackgroundSubtractorMOG2 mbHistory mbVarThreshold mbDetectShadows = unsafePrimToPrim $ fromPtr+    [CU.block|Ptr_BackgroundSubtractorMOG2 * {+      cv::Ptr<cv::BackgroundSubtractorMOG2> mog2Ptr =+        cv::createBackgroundSubtractorMOG2+        ( $(int32_t c'history      )+        , $(double  c'varThreshold )+        , $(bool    c'detectShadows)+        );+      return new cv::Ptr<cv::BackgroundSubtractorMOG2>(mog2Ptr);+    }|]+  where+    c'history       = fromMaybe 500 mbHistory+    c'varThreshold  = maybe 16 realToFrac mbVarThreshold+    c'detectShadows = fromBool $ fromMaybe True mbDetectShadows++--------------------------------------------------------------------------------++instance Algorithm BackgroundSubtractorKNN where+    algorithmClearState knn = unsafePrimToPrim $+        withPtr knn $ \knnPtr ->+          [C.block|void {+              cv::BackgroundSubtractorKNN * knn = *$(Ptr_BackgroundSubtractorKNN * knnPtr);+              knn->clear();+          }|]++    algorithmIsEmpty knn = unsafePrimToPrim $+        withPtr knn $ \knnPtr ->+        alloca $ \emptyPtr -> do+          [C.block|void {+              cv::BackgroundSubtractorKNN * knn = *$(Ptr_BackgroundSubtractorKNN * knnPtr);+              *$(bool * emptyPtr) = knn->empty();+          }|]+          toBool <$> peek emptyPtr++instance Algorithm BackgroundSubtractorMOG2 where+    algorithmClearState mog2 = unsafePrimToPrim $+        withPtr mog2 $ \mog2Ptr ->+          [C.block|void {+              cv::BackgroundSubtractorMOG2 * mog2 = *$(Ptr_BackgroundSubtractorMOG2 * mog2Ptr);+              mog2->clear();+          }|]++    algorithmIsEmpty mog2 = unsafePrimToPrim $+        withPtr mog2 $ \mog2Ptr ->+        alloca $ \emptyPtr -> do+          [C.block|void {+              cv::BackgroundSubtractorMOG2 * mog2 = *$(Ptr_BackgroundSubtractorMOG2 * mog2Ptr);+              *$(bool * emptyPtr) = mog2->empty();+          }|]+          toBool <$> peek emptyPtr++instance BackgroundSubtractor BackgroundSubtractorKNN where+    bgSubApply knn learningRate img = unsafePrimToPrim $ do+        fgMask <- newEmptyMat+        withPtr knn $ \knnPtr ->+          withPtr img $ \imgPtr ->+          withPtr fgMask $ \fgMaskPtr -> mask_ $ do+            [C.block| void {+              cv::BackgroundSubtractorKNN * knn = *$(Ptr_BackgroundSubtractorKNN * knnPtr);+              knn->apply+              ( *$(Mat * imgPtr)+              , *$(Mat * fgMaskPtr)+              , $(double c'learningRate)+              );+            }|]+        pure $ unsafeCoerceMat fgMask+      where+        c'learningRate = realToFrac learningRate++    getBackgroundImage knn = unsafePrimToPrim $ do+        img <- newEmptyMat+        withPtr knn $ \knnPtr ->+          withPtr img $ \imgPtr -> mask_ $ do+            [C.block| void {+              cv::BackgroundSubtractorKNN * knn = *$(Ptr_BackgroundSubtractorKNN * knnPtr);+              knn->getBackgroundImage(*$(Mat * imgPtr));+            }|]+            pure $ unsafeCoerceMat img++instance BackgroundSubtractor BackgroundSubtractorMOG2 where+    bgSubApply mog2 learningRate img = unsafePrimToPrim $ do+        fgMask <- newEmptyMat+        withPtr mog2 $ \mog2Ptr ->+          withPtr img $ \imgPtr ->+          withPtr fgMask $ \fgMaskPtr -> mask_ $ do+            [C.block| void {+              cv::BackgroundSubtractorMOG2 * mog2 = *$(Ptr_BackgroundSubtractorMOG2 * mog2Ptr);+              mog2->apply+              ( *$(Mat * imgPtr)+              , *$(Mat * fgMaskPtr)+              , $(double c'learningRate)+              );+            }|]+        pure $ unsafeCoerceMat fgMask+      where+        c'learningRate = realToFrac learningRate++    getBackgroundImage mog2 = unsafePrimToPrim $ do+        img <- newEmptyMat+        withPtr mog2 $ \mog2Ptr ->+          withPtr img $ \imgPtr -> mask_ $ do+            [C.block| void {+              cv::BackgroundSubtractorMOG2 * mog2 = *$(Ptr_BackgroundSubtractorMOG2 * mog2Ptr);+              mog2->getBackgroundImage(*$(Mat * imgPtr));+            }|]+            pure $ unsafeCoerceMat img
+ src/OpenCV/VideoIO/Types.hs view
@@ -0,0 +1,8 @@+module OpenCV.VideoIO.Types+    ( -- * VideoCodecs+      FourCC (..)+    , VideoCaptureProperties (..)+    , VideoCaptureAPI (..)+    ) where++import "this" OpenCV.Internal.VideoIO.Types
+ src/OpenCV/VideoIO/VideoCapture.cpp view
@@ -0,0 +1,143 @@++#include "opencv2/core.hpp"++#include "opencv2/videoio.hpp"++using namespace cv;++extern "C" {+VideoCapture * inline_c_OpenCV_VideoIO_VideoCapture_0_ab9ed265db29f4cf2a2777e8ca5cb16998f7ac71() {+return (+      new cv::VideoCapture()+    );+}++}++extern "C" {+Exception * inline_c_OpenCV_VideoIO_VideoCapture_1_f37094426ee7b6109652e57363ff24948f8b3740(VideoCapture * videoCapturePtr_inline_c_0, const char * cfilePath_27_inline_c_1, int32_t capi_27_inline_c_2) {++  try+  {   +              videoCapturePtr_inline_c_0->open(cv::String(cfilePath_27_inline_c_1), capi_27_inline_c_2);+            +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_VideoIO_VideoCapture_2_431a33a1d2563009e4ba8552b79f9019adbf7d6c(VideoCapture * videoCapturePtr_inline_c_0, int32_t cdevice_27_inline_c_1) {++  try+  {   +            videoCapturePtr_inline_c_0->open(cdevice_27_inline_c_1);+          +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+Exception * inline_c_OpenCV_VideoIO_VideoCapture_3_1882f853a76cc5f0bc18c4d9f5f2075126512391(VideoCapture * videoCapturePtr_inline_c_0) {++  try+  {   +        videoCapturePtr_inline_c_0->release();+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoCapture_4_3c98054f960c952ed632d3d0a95d6f46f0f1b559(VideoCapture * videoCapturePtr_inline_c_0) {+return (+        videoCapturePtr_inline_c_0->isOpened()+      );+}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoCapture_5_6c2ca3ac7eb301e8870a46d2eab31ba7bbfe1c17(VideoCapture * videoCapturePtr_inline_c_0) {+return (+        videoCapturePtr_inline_c_0->grab()+      );+}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoCapture_6_254460c041760fe3eb8f3e5e05438f91d2a82ce5(VideoCapture * videoCapturePtr_inline_c_0, Mat * framePtr_inline_c_1) {+return (+          videoCapturePtr_inline_c_0->retrieve(*framePtr_inline_c_1, 0)+        );+}++}++extern "C" {+double inline_c_OpenCV_VideoIO_VideoCapture_7_407526323012c89432561c3320a753a4fcdd1521(VideoCapture * videoCapturePtr_inline_c_0, int32_t cprop_27_inline_c_1) {+return (+        videoCapturePtr_inline_c_0->get( cprop_27_inline_c_1 )+      );+}++}++extern "C" {+int32_t inline_c_OpenCV_VideoIO_VideoCapture_8_c923566cc51e3c1649dbf96f60f8c5d6ecb9d10b(VideoCapture * videoCapturePtr_inline_c_0, int32_t cprop_27_inline_c_1) {+return (+        videoCapturePtr_inline_c_0->get( cprop_27_inline_c_1 )+      );+}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoCapture_9_8a3e42766b51dc8a22277104ce93cd0e01023d66(VideoCapture * videoCapturePtr_inline_c_0, int32_t cprop_27_inline_c_1, double cval_27_inline_c_2) {+return (+        videoCapturePtr_inline_c_0->set( cprop_27_inline_c_1+                                              , cval_27_inline_c_2+                                              )+      );+}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoCapture_10_ddb51d8b9125e643559ae784160d563071bed3db(VideoCapture * videoCapturePtr_inline_c_0, int32_t cprop_27_inline_c_1, int32_t val_inline_c_2) {+return (+        videoCapturePtr_inline_c_0->set( cprop_27_inline_c_1+                                              , val_inline_c_2+                                              )+      );+}++}++extern "C" {+void inline_c_OpenCV_VideoIO_VideoCapture_11_525579f48382e876139050af6413f576695c80b7(VideoCapture * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/VideoIO/VideoCapture.hs view
@@ -0,0 +1,169 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.VideoIO.VideoCapture+  ( VideoCapture+  , VideoCaptureSource(..)++  , newVideoCapture+  , videoCaptureOpen+  , videoCaptureRelease+  , videoCaptureIsOpened+  , videoCaptureGrab+  , videoCaptureRetrieve+  , videoCaptureGetD+  , videoCaptureGetI+  , videoCaptureSetD+  , videoCaptureSetI+  ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.String ( withCString )+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Marshal.Utils ( toBool )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types.Mat+import "this" OpenCV.Internal+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.Internal.Core.Types.Mat+import "this" OpenCV.Internal.VideoIO.Types+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except ( ExceptT(ExceptT) )++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/videoio.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------++newtype VideoCapture = VideoCapture {unVideoCapture :: ForeignPtr (C VideoCapture)}++type instance C VideoCapture = C'VideoCapture++instance WithPtr VideoCapture where withPtr = withForeignPtr . unVideoCapture++instance FromPtr VideoCapture where+    fromPtr = objFromPtr VideoCapture $ \ptr ->+                [CU.exp| void { delete $(VideoCapture * ptr) }|]++data VideoCaptureSource+   = VideoFileSource      !FilePath !(Maybe VideoCaptureAPI)+        -- ^ VideoFile and backend+   | VideoDeviceSource    !Int32    !(Maybe VideoCaptureAPI)+        -- ^ VideoDevice and backend++newVideoCapture :: IO VideoCapture+newVideoCapture = fromPtr $+    [CU.exp|VideoCapture * {+      new cv::VideoCapture()+    }|]++videoCaptureOpen :: VideoCapture -> VideoCaptureSource -> CvExceptT IO ()+videoCaptureOpen videoCapture src =+    ExceptT $+    handleCvException (pure ()) $+    withPtr videoCapture $ \videoCapturePtr ->+      case src of+        VideoFileSource filePath api ->+          withCString filePath $ \c'filePath ->+            [cvExcept|+              $(VideoCapture * videoCapturePtr)->open(cv::String($(const char * c'filePath)), $(int32_t c'api));+            |]+           where+             c'api = maybe 0 marshalVideoCaptureAPI api+        VideoDeviceSource device api ->+          [cvExcept|+            $(VideoCapture * videoCapturePtr)->open($(int32_t c'device ));+          |]+            where+              c'device = device + maybe 0 marshalVideoCaptureAPI api++videoCaptureRelease :: VideoCapture -> CvExceptT IO ()+videoCaptureRelease videoCapture =+    ExceptT $+    handleCvException (pure ()) $+    withPtr videoCapture $ \videoCapturePtr ->+      [cvExcept|+        $(VideoCapture * videoCapturePtr)->release();+      |]++videoCaptureIsOpened :: VideoCapture -> IO Bool+videoCaptureIsOpened videoCapture =+    fmap toBool $+    withPtr videoCapture $ \videoCapturePtr ->+      [CU.exp| bool {+        $(VideoCapture * videoCapturePtr)->isOpened()+      }|]++videoCaptureGrab :: VideoCapture -> IO Bool+videoCaptureGrab videoCapture =+    fmap toBool $+    withPtr videoCapture $ \videoCapturePtr ->+      [C.exp| bool {+        $(VideoCapture * videoCapturePtr)->grab()+      }|]++videoCaptureRetrieve :: VideoCapture -> IO (Maybe (Mat ('S ['D, 'D]) 'D 'D))+videoCaptureRetrieve videoCapture = do+    frame <- newEmptyMat+    ok <- withPtr frame $ \framePtr ->+      withPtr videoCapture $ \videoCapturePtr ->+        [C.exp| bool {+          $(VideoCapture * videoCapturePtr)->retrieve(*$(Mat * framePtr), 0)+        }|]+    pure $ case toBool ok of+      False -> Nothing+      True  -> Just $ unsafeCoerceMat frame++videoCaptureGetD :: VideoCapture -> VideoCaptureProperties -> IO Double+videoCaptureGetD videoCapture prop =+    fmap realToFrac $+    withPtr videoCapture $ \videoCapturePtr ->+      [CU.exp| double {+        $(VideoCapture * videoCapturePtr)->get( $(int32_t c'prop) )+      }|]+   where+     c'prop = marshalCaptureProperties prop++videoCaptureGetI :: VideoCapture -> VideoCaptureProperties -> IO Int32+videoCaptureGetI videoCapture prop =+    withPtr videoCapture $ \videoCapturePtr ->+      [CU.exp| int32_t {+        $(VideoCapture * videoCapturePtr)->get( $(int32_t c'prop) )+      }|]+   where+     c'prop = marshalCaptureProperties prop++videoCaptureSetD :: VideoCapture -> VideoCaptureProperties -> Double -> IO Bool+videoCaptureSetD videoCapture prop val =+    fmap toBool $+    withPtr videoCapture $ \videoCapturePtr ->+      [CU.exp| bool {+        $(VideoCapture * videoCapturePtr)->set( $(int32_t c'prop)+                                              , $(double c'val)+                                              )+      }|]+   where+     c'prop = marshalCaptureProperties prop+     c'val = realToFrac val+++videoCaptureSetI :: VideoCapture -> VideoCaptureProperties -> Int32 -> IO Bool+videoCaptureSetI videoCapture prop val =+    fmap toBool $+    withPtr videoCapture $ \videoCapturePtr ->+      [CU.exp| bool {+        $(VideoCapture * videoCapturePtr)->set( $(int32_t c'prop)+                                              , $(int32_t val)+                                              )+      }|]+   where+     c'prop = marshalCaptureProperties prop
+ src/OpenCV/VideoIO/VideoWriter.cpp view
@@ -0,0 +1,71 @@++#include "opencv2/core.hpp"++#include "opencv2/videoio.hpp"++using namespace cv;++extern "C" {+VideoWriter * inline_c_OpenCV_VideoIO_VideoWriter_0_63dd3b8b2445d3abd57d4874d4c4971d404cd27b(const char * cfilePath_27_inline_c_0, int32_t cfourCC_27_inline_c_1, double cfps_27_inline_c_2, Size2i * frameDimsPtr_inline_c_3) {+return (+              new cv::VideoWriter( cv::String(cfilePath_27_inline_c_0)+                                 , cfourCC_27_inline_c_1+                                 , cfps_27_inline_c_2+                                 , *frameDimsPtr_inline_c_3+                                 )+            );+}++}++extern "C" {+Exception * inline_c_OpenCV_VideoIO_VideoWriter_1_22f2391373836933935aaf9c1eb3ad3542bdf277(VideoWriter * videoWriterPtr_inline_c_0) {++  try+  {   +        videoWriterPtr_inline_c_0->release();+      +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+bool inline_c_OpenCV_VideoIO_VideoWriter_2_5b2c7490b5a9614bcf2aca28f612292eeab436fc(VideoWriter * videoWriterPtr_inline_c_0) {+return (+        videoWriterPtr_inline_c_0->isOpened()+      );+}++}++extern "C" {+Exception * inline_c_OpenCV_VideoIO_VideoWriter_3_47a0f544e1d36145156061e7d8494b8fe5fce91f(VideoWriter * videoWriterPtr_inline_c_0, Mat * framePtr_inline_c_1) {++  try+  {   +          videoWriterPtr_inline_c_0->write(*framePtr_inline_c_1);+        +    return NULL;+  }+  catch (const cv::Exception & e)+  {+    return new cv::Exception(e);+  }++}++}++extern "C" {+void inline_c_OpenCV_VideoIO_VideoWriter_4_f06942315b8f072b23a70879094d8ade94144525(VideoWriter * ptr_inline_c_0) {+ delete ptr_inline_c_0 ;+}++}
+ src/OpenCV/VideoIO/VideoWriter.hs view
@@ -0,0 +1,136 @@+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TemplateHaskell #-}++module OpenCV.VideoIO.VideoWriter+  ( VideoWriter+  , VideoWriterSink(..)+  , VideoFileSink(..)++  , videoWriterOpen+  , videoWriterRelease+  , videoWriterIsOpened+  , videoWriterWrite+  ) where++import "base" Data.Int ( Int32 )+import "base" Foreign.C.String ( withCString )+import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr )+import "base" Foreign.Marshal.Utils ( toBool )+import "linear" Linear.V2 ( V2(..) )+import qualified "inline-c" Language.C.Inline as C+import qualified "inline-c" Language.C.Inline.Unsafe as CU+import qualified "inline-c-cpp" Language.C.Inline.Cpp as C+import "this" OpenCV.Core.Types+import "this" OpenCV.VideoIO.Types+import "this" OpenCV.Internal+import "this" OpenCV.Internal.Exception+import "this" OpenCV.Internal.C.Inline ( openCvCtx )+import "this" OpenCV.Internal.C.Types+import "this" OpenCV.TypeLevel+import "transformers" Control.Monad.Trans.Except ( ExceptT(ExceptT) )++--------------------------------------------------------------------------------++C.context openCvCtx++C.include "opencv2/core.hpp"+C.include "opencv2/videoio.hpp"+C.using "namespace cv"++--------------------------------------------------------------------------------++newtype VideoWriter = VideoWriter {unVideoWriter :: ForeignPtr (C VideoWriter)}++type instance C VideoWriter = C'VideoWriter++instance WithPtr VideoWriter where+    withPtr = withForeignPtr . unVideoWriter++instance FromPtr VideoWriter where+    fromPtr = objFromPtr VideoWriter $ \ptr ->+                [CU.exp| void { delete $(VideoWriter * ptr) }|]++data VideoWriterSink+   = VideoFileSink' !VideoFileSink++data VideoFileSink+   = VideoFileSink+     { vfsFilePath  :: !FilePath+     , vfsFourCC    :: !FourCC+     , vfsFps       :: !Double+     , vfsFrameDims :: !(Int32, Int32)+     }++{- |+The API might change in the future, but currently we can:++Open/create a new file:++@+  wr <- 'videoWriterOpen' $ 'VideoFileSink''+     ('VideoFileSink'+        "tst.MOV"+        "avc1"+        30+        (3840, 2160)+     )+@++Now, we can write some frames, but they need to have exactly the same size+ as the one we have opened with:++@+  'exceptErrorIO' $ 'videoWriterWrite' wr img+@++We need to close at the end or it will not finalize the file:++@+  'exceptErrorIO' $ 'videoWriterRelease' wr+@+-}++videoWriterOpen :: VideoWriterSink -> IO VideoWriter+videoWriterOpen sink =+    fromPtr $+      case sink of+        VideoFileSink' vfs ->+          withCString (vfsFilePath vfs) $ \c'filePath ->+          withPtr (toSize $ uncurry V2 $ vfsFrameDims vfs) $ \frameDimsPtr ->+            [CU.exp|VideoWriter * {+              new cv::VideoWriter( cv::String($(const char * c'filePath))+                                 , $(int32_t c'fourCC)+                                 , $(double c'fps)+                                 , *$(Size2i * frameDimsPtr)+                                 )+            }|]+          where+            c'fps = realToFrac (vfsFps vfs)+            c'fourCC = unFourCC (vfsFourCC vfs)++videoWriterRelease :: VideoWriter -> CvExceptT IO ()+videoWriterRelease videoWriter =+    ExceptT $+    handleCvException (pure ()) $+    withPtr videoWriter $ \videoWriterPtr ->+      [cvExcept|+        $(VideoWriter * videoWriterPtr)->release();+      |]++videoWriterIsOpened :: VideoWriter -> IO Bool+videoWriterIsOpened videoWriter =+    fmap toBool $+    withPtr videoWriter $ \videoWriterPtr ->+      [CU.exp| bool {+        $(VideoWriter * videoWriterPtr)->isOpened()+      }|]++videoWriterWrite :: VideoWriter -> Mat ('S ['D, 'D]) 'D 'D -> CvExceptT IO ()+videoWriterWrite videoWriter frame =+    ExceptT $+    handleCvException (pure ()) $+    withPtr frame $ \framePtr ->+    withPtr videoWriter $ \videoWriterPtr ->+        [cvExcept|+          $(VideoWriter * videoWriterPtr)->write(*$(Mat *framePtr));+        |]
+ test/test.hs view
@@ -0,0 +1,424 @@+{-# language FlexibleInstances #-}+{-# language TypeSynonymInstances #-}+{-# options_ghc -fno-warn-orphans #-}++module Main where++import "base" Data.Int+import "base" Data.Monoid+import "base" Data.Proxy+import "base" Data.Word+import "base" Data.Foldable ( forM_ )+import "base" Foreign.C.Types ( CFloat(..), CDouble(..) )+import "base" Foreign.Storable ( Storable )+import qualified "bytestring" Data.ByteString as B+import "linear" Linear.Matrix ( M23, M33 )+import "linear" Linear.Vector ( (^+^), zero )+import "linear" Linear.V2 ( V2(..) )+import "linear" Linear.V3 ( V3(..) )+import "linear" Linear.V4 ( V4(..) )+import "opencv" OpenCV+import "opencv" OpenCV.Unsafe+import "opencv" OpenCV.Internal.Core.Types.Mat.Marshal ( marshalDepth, unmarshalDepth )+import qualified "repa" Data.Array.Repa as Repa+import "repa" Data.Array.Repa.Index ((:.)((:.)))+import "tasty" Test.Tasty+import "tasty-hunit" Test.Tasty.HUnit as HU+import qualified "tasty-quickcheck" Test.Tasty.QuickCheck as QC (testProperty)+import qualified "QuickCheck" Test.QuickCheck as QC+import           "QuickCheck" Test.QuickCheck ( (==>) )+import "transformers" Control.Monad.Trans.Except+import qualified "vector" Data.Vector as V++main :: IO ()+main = defaultMain $ testGroup "opencv"+    [ testGroup "Calib3d"+      [ HU.testCase "findFundamentalMat - no points" testFindFundamentalMat_noPoints+      , HU.testCase "findFundamentalMat" testFindFundamentalMat+      , HU.testCase "computeCorrespondEpilines" testComputeCorrespondEpilines+      ]+    , testGroup "Core"+      [ testGroup "Iso"+        [ testIso "isoPoint2iV2" (toPoint  :: V2 Int32   -> Point2i) fromPoint+        , testIso "isoPoint2fV2" (toPoint  :: V2 CFloat  -> Point2f) fromPoint+        , testIso "isoPoint2dV2" (toPoint  :: V2 CDouble -> Point2d) fromPoint+        , testIso "isoPoint3iV3" (toPoint  :: V3 Int32   -> Point3i) fromPoint+        , testIso "isoPoint3fV3" (toPoint  :: V3 CFloat  -> Point3f) fromPoint+        , testIso "isoPoint3dV3" (toPoint  :: V3 CDouble -> Point3d) fromPoint+        , testIso "isoVec3fV3"   (toVec    :: V3 CFloat  -> Vec3f  ) fromVec+        , testIso "isoVec4iV4"   (toVec    :: V4 Int32   -> Vec4i  ) fromVec+        , testIso "isoSize2iV2"  (toSize   :: V2 Int32   -> Size2i ) fromSize+        , testIso "isoSize2fV2"  (toSize   :: V2 CFloat  -> Size2f ) fromSize+        , testIso "isoScalarV4"  (toScalar :: V4 CDouble -> Scalar ) fromScalar+        ]+      , testGroup "Rect"+        [ QC.testProperty "basic-properties" rectBasicProperties+        , QC.testProperty "rectContains" rectContainsProperty+        ]+      , testGroup "RotatedRect"+        [+        ]+      , testGroup "Scalar"+        [+        ]+      , testGroup "Types"+        [ testGroup "Depth"+          [ HU.testCase "marshal unmarshal" depthMarshalUnmarshal+          , QC.testProperty "unmarshal unknown" depthUnmarshalUnknown+          ]+        , testGroup "Mat"+          [ HU.testCase "emptyMat" $ testMatType emptyMat+          , testGroup "matInfo"+            [ matHasInfoFP "Lenna.png"  $ MatInfo [512, 512] Depth_8U 3+            , matHasInfoFP "kikker.jpg" $ MatInfo [390, 500] Depth_8U 3+            ]+          , testGroup "HMat"+            [ HU.testCase "hElemsSize" $ hmatElemSize "Lenna.png" (512 * 512 * 3)+            -- , HU.testCase "eye 33" $ assertEqual "" (HMat [3,3] 1 $ HElems_8U $ VU.fromList [1,0,0, 0,1,0, 0,0,1]) $ eye33_c1 ^. hmat+            , testGroup "mat -> hmat -> mat -> hmat"+              [ HU.testCase "eye 33 - 1 channel"  $ hMatEncodeDecode eye33_8u_1c+              , HU.testCase "eye 22 - 3 channels" $ hMatEncodeDecode eye22_8u_3c+              , hMatEncodeDecodeFP "Lenna.png"+              , hMatEncodeDecodeFP "kikker.jpg"+              ]+            ]+          , testGroup "Repa"+            [ HU.testCase "imgToRepa" imgToRepa ]+          , testGroup "fixed size matrices"+            [ HU.testCase "M23 eye" $ testMatToM23 eye23_8u_1c (eye_m23 :: M23 Word8)+            , HU.testCase "M33 eye" $ testMatToM33 eye33_8u_1c (eye_m33 :: M33 Word8)+            ]+          ]+        ]+      ]+    , testGroup "ImgProc"+      [ testGroup "GeometricImgTransform"+        [ HU.testCase "getRotationMatrix2D" testGetRotationMatrix2D+        ]+      , testGroup "Structural Analysis and Shape Descriptors"+        [ HU.testCase "findContours" testFindContours+        ]+      , testGroup "Feature Detection"+        [ HU.testCase "houghLinesP"   testHoughLinesP+        ]+      , testGroup "Cascade Classifier"+        [ HU.testCase "newCascadeClassifier algorithm" testNewCascadeClassifierAlgorithm+        , HU.testCase "cascadeClassifierDetectMultiScale Arnold" testCascadeClassifierDetectMultiScaleArnold+        ]+      ]+    , testGroup "ImgCodecs"+      [ testGroup "imencode . imdecode"+        [ HU.testCase "OutputBmp"      $ encodeDecode OutputBmp+-- !?!?!, HU.testCase "OutputExr"      $ encodeDecode OutputExr+        , HU.testCase "OutputHdr"      $ encodeDecode (OutputHdr True)+-- !?!?!, HU.testCase "OutputJpeg"     $ encodeDecode (OutputJpeg defaultJpegParams)+        , HU.testCase "OutputJpeg2000" $ encodeDecode OutputJpeg2000+        , HU.testCase "OutputPng"      $ encodeDecode (OutputPng defaultPngParams)+        , HU.testCase "OutputPxm"      $ encodeDecode (OutputPxm True)+        , HU.testCase "OutputSunras"   $ encodeDecode OutputSunras+        , HU.testCase "OutputTiff"     $ encodeDecode OutputTiff+-- !?!?!, HU.testCase "OutputWebP"     $ encodeDecode (OutputWebP 100)+        ]+      ]+    , testGroup "Features2d"+      [ HU.testCase "orbDetectAndCompute" testOrbDetectAndCompute+      ]+    , testGroup "HighGui"+      [+      ]+    , testGroup "Video"+      [+      ]+    ]++testFindFundamentalMat_noPoints :: HU.Assertion+testFindFundamentalMat_noPoints =+    case runExcept $ findFundamentalMat points points (FM_Ransac Nothing Nothing) of+      Left err -> assertFailure (show err)+      Right Nothing -> pure ()+      Right (Just _) -> assertFailure "result despite lack of data"+  where+    points :: V.Vector (V2 CDouble)+    points = V.empty++testFindFundamentalMat :: HU.Assertion+testFindFundamentalMat =+    case runExcept $ findFundamentalMat points1 points2 (FM_Ransac Nothing Nothing) of+      Left err -> assertFailure (show err)+      Right Nothing -> assertFailure "couldn't find fundamental matrix"+      Right (Just (fm, pointsMask)) -> do+          assertNull (typeCheckMat fm        ) (("fm: "         <>) . show)+          assertNull (typeCheckMat pointsMask) (("pointsMask: " <>) . show)+  where+    points1, points2 :: V.Vector (V2 CDouble)+    points1 = V.fromList [V2 x y | x <- [0..9], y <- [0..9]]+    points2 = V.map (^+^ (V2 3 2)) points1++testComputeCorrespondEpilines :: HU.Assertion+testComputeCorrespondEpilines =+    case runExcept $ findFundamentalMat points1 points2 (FM_Ransac Nothing Nothing) of+      Right (Just (fm, _pointsMask)) ->+          let fm' = unsafeCoerceMat fm+          in case runExcept $ computeCorrespondEpilines points1 Image1 fm' of+               Left err1 -> assertFailure (show err1)+               Right epilines1 -> do+                 assertNull (typeCheckMat epilines1) (("epilines1: " <>) . show)+                 case runExcept $ computeCorrespondEpilines points2 Image2 fm' of+                   Left err2 -> assertFailure (show err2)+                   Right epilines2 ->+                       assertNull (typeCheckMat epilines2) (("epilines2: " <>) . show)+      _ -> assertFailure "couldn't find fundamental matrix"+  where+    points1, points2 :: V.Vector (V2 CDouble)+    points1 = V.fromList [V2 x y | x <- [0..9], y <- [0..9]]+    points2 = V.map (^+^ (V2 3 2)) points1++testIso :: (QC.Arbitrary a, Eq a, Show a) => String -> (a -> b) -> (b -> a) -> TestTree+testIso name a_to_b b_to_a = QC.testProperty name $ \a -> a QC.=== (b_to_a . a_to_b) a++rectBasicProperties+    :: V2 Int32 -- ^ tl+    -> V2 Int32 -- ^ size+    -> Bool+rectBasicProperties tl size@(V2 w h) = and+      [ fromPoint (rectTopLeft     rect) == tl+      , fromPoint (rectBottomRight rect) == tl ^+^ size+      , fromSize  (rectSize        rect) == size+      ,           rectArea         rect  == (w  *  h)+      ]+    where+      rect :: Rect2i+      rect = toRect $ HRect tl size++rectContainsProperty :: Point2i -> Rect2i -> Bool+rectContainsProperty point rect = rectContains point rect == myRectContains point rect++myRectContains :: Point2i -> Rect2i -> Bool+myRectContains point rect =+    and [ rx <= px+        , ry <= py++        , px < rx + w+        , py < ry + h+        ]+  where+    px, py :: Int32+    V2 px py = fromPoint point++    rx, ry :: Int32+    V2 rx ry = fromPoint $ rectTopLeft rect++    w, h :: Int32+    V2 w h = fromSize $ rectSize rect++-- | Roundtrip every 'Depth' through the `Int32` encoding.+depthMarshalUnmarshal :: HU.Assertion+depthMarshalUnmarshal =+    forM_ [minBound .. maxBound] $ \depth ->+      assertEqual "" depth (unmarshalDepth . marshalDepth $ depth)++depthUnmarshalUnknown :: Int32 -> QC.Property+depthUnmarshalUnknown n =+    n `notElem` knownEncodings ==> QC.expectFailure (unmarshalDepth n `seq` True)+  where+    knownEncodings = map marshalDepth [minBound .. maxBound]++testMatType+    :: ( ToShapeDS    (Proxy shape)+       , ToChannelsDS (Proxy channels)+       , ToDepthDS    (Proxy depth)+       )+    => Mat shape channels depth+    -> HU.Assertion+testMatType mat =+    case typeCheckMat mat of+      [] -> pure ()+      errors -> assertFailure $ show errors++matHasInfoFP :: FilePath -> MatInfo -> TestTree+matHasInfoFP fp expectedInfo = HU.testCase fp $ do+    mat <- loadImg ImreadUnchanged fp+    assertEqual "" expectedInfo (matInfo mat)++testGetRotationMatrix2D :: HU.Assertion+testGetRotationMatrix2D = testMatType rot2D+  where+    rot2D = getRotationMatrix2D (zero :: V2 CFloat) 0 0++hMatEncodeDecodeFP :: FilePath -> TestTree+hMatEncodeDecodeFP fp = HU.testCase fp $ do+    mat <- loadImg ImreadUnchanged fp+    hMatEncodeDecode mat++hMatEncodeDecode :: Mat shape channels depth -> HU.Assertion+hMatEncodeDecode m1 =+    assertEqual "" h1 h2+    -- assertBool "mat hmat conversion failure" (h1 == h2)+  where+    h1 = matToHMat m1+    m2 = hMatToMat h1+    h2 = matToHMat m2++hmatElemSize :: FilePath -> Int -> HU.Assertion+hmatElemSize fp expectedElemSize = do+  mat <- loadImg ImreadUnchanged fp+  assertEqual "" expectedElemSize $ hElemsLength $ hmElems $ matToHMat mat++encodeDecode :: OutputFormat -> HU.Assertion+encodeDecode outputFormat = do+    mat1 <- loadImg ImreadUnchanged "Lenna.png"++    let bs2  = exceptError $ imencode outputFormat mat1+        mat2 = imdecode ImreadUnchanged bs2++        bs3  = exceptError $ imencode outputFormat mat2++    assertBool "imencode . imdecode failure"+               (bs2 == bs3)++testOrbDetectAndCompute :: HU.Assertion+testOrbDetectAndCompute = do+    kikker <- loadImg ImreadUnchanged "kikker.jpg"+    let (kpts, descs) = exceptError $ orbDetectAndCompute orb kikker Nothing+        kptsRec  = V.map keyPointAsRec kpts+        kpts2    = V.map mkKeyPoint    kptsRec+        kptsRec2 = V.map keyPointAsRec kpts2+        numDescs = head $ miShape $ matInfo descs+    assertEqual "kpt conversion failure"+                kptsRec+                kptsRec2+    assertEqual "number of kpts /= number of descriptors"+                (fromIntegral $ V.length kpts)+                numDescs+  where+    orb = mkOrb defaultOrbParams {orb_nfeatures = 10}++testFindContours :: HU.Assertion+testFindContours =+  do lambda <- loadLambda+     edges <- unsafeThaw $ exceptError $ canny 30 20 Nothing CannyNormL1 lambda+     contours <- findContours ContourRetrievalExternal+                              ContourApproximationSimple+                              edges+     assertEqual "Unexpected number of contours found"+                 (length contours)+                 1++testHoughLinesP :: HU.Assertion+testHoughLinesP = do+    building <- loadImg ImreadUnchanged "building.jpg"+    let building' :: Mat ('S ['D, 'D]) 'D ('S Word8)+        building' = exceptError $ coerceMat building+    let edgeImg = exceptError $ canny 50 200 Nothing CannyNormL1 building'+    edgeImgM <- thaw edgeImg+    lineSegments <- houghLinesP 1 (pi / 180) 100 Nothing Nothing edgeImgM+    assertBool "no lines found" (V.length lineSegments > 0)++testNewCascadeClassifierAlgorithm :: HU.Assertion+testNewCascadeClassifierAlgorithm = do+  mbCC <- newCascadeClassifier "/this/is/bogus.xml"+  case mbCC of+    Nothing -> return ()+    Just _cc -> fail "expected Nothing from newCascadeClassifier"++testCascadeClassifierDetectMultiScaleArnold :: HU.Assertion+testCascadeClassifierDetectMultiScaleArnold = do+    Just ccFrontal <- newCascadeClassifier "data/haarcascade_frontalface_default.xml"+    Just ccEyes <- newCascadeClassifier "data/haarcascade_eye.xml"+    arnold :: Mat ('S ['D, 'D]) ('S 3) ('S Word8) <-+      exceptError . coerceMat <$> loadImg ImreadUnchanged "arnold-schwarzenegger.jpg"+    let arnoldGray :: Mat ('S ['D, 'D]) ('S 1) ('S Word8) = exceptError (cvtColor bgr gray arnold)+    -- OpenCV detects the left eye twice for this pic.+    let arnoldEyes =+          cascadeClassifierDetectMultiScale ccEyes Nothing Nothing (Nothing :: Maybe (V2 Int32)) (Nothing :: Maybe (V2 Int32)) arnoldGray+    assertBool "unexpected number of eyes detected" (V.length arnoldEyes == 3)+    let arnoldFront =+          cascadeClassifierDetectMultiScale ccFrontal Nothing Nothing (Nothing :: Maybe (V2 Int32)) (Nothing :: Maybe (V2 Int32)) arnoldGray+    assertBool "unexpected number of faces detected" (V.length arnoldFront == 1)++type Lambda = Mat (ShapeT [256, 256]) ('S 1) ('S Word8)++loadLambda :: IO Lambda+loadLambda =+  fmap (exceptError . coerceMat . imdecode ImreadGrayscale)+       (B.readFile "data/lambda.png")++loadImg :: ImreadMode -> FilePath -> IO (Mat ('S ['D, 'D]) 'D 'D)+loadImg readMode fp = imdecode readMode <$> B.readFile ("data/" <> fp)++imgToRepa :: HU.Assertion+imgToRepa = do+    mat <- loadImg ImreadUnchanged "kikker.jpg"+    case runExcept $ coerceMat mat of+      Left err -> assertFailure $ show err+      Right (mat' :: Mat ('S '[ 'D, 'D ]) ('S 3) ('S Word8)) -> do+        let repaArray :: Repa.Array (M '[ 'D, 'D ] 3) Repa.DIM3 Word8+            repaArray = toRepa mat'+        assertEqual "extent" (Repa.Z :. 3 :. 500 :. 390 ) (Repa.extent repaArray)++testMatToM23+    :: (Eq e, Show e, Storable e)+    => Mat (ShapeT [2, 3]) ('S 1) ('S e)+    -> V2 (V3 e)+    -> HU.Assertion+testMatToM23 m v = assertEqual "" v $ fromMat m++testMatToM33+    :: (Eq e, Show e, Storable e)+    => Mat (ShapeT [3, 3]) ('S 1) ('S e)+    -> V3 (V3 e)+    -> HU.Assertion+testMatToM33 m v = assertEqual "" v $ fromMat m++--------------------------------------------------------------------------------++eye23_8u_1c :: Mat (ShapeT [2, 3]) ('S 1) ('S Word8)+eye33_8u_1c :: Mat (ShapeT [3, 3]) ('S 1) ('S Word8)+eye22_8u_3c :: Mat (ShapeT [2, 2]) ('S 3) ('S Word8)++eye23_8u_1c = eyeMat (Proxy :: Proxy 2) (Proxy :: Proxy 3) (Proxy :: Proxy 1) (Proxy :: Proxy Word8)+eye33_8u_1c = eyeMat (Proxy :: Proxy 3) (Proxy :: Proxy 3) (Proxy :: Proxy 1) (Proxy :: Proxy Word8)+eye22_8u_3c = eyeMat (Proxy :: Proxy 2) (Proxy :: Proxy 2) (Proxy :: Proxy 3) (Proxy :: Proxy Word8)++eye_m23 :: (Num e) => M23 e+eye_m33 :: (Num e) => M33 e++eye_m23 = V2 (V3 1 0 0) (V3 0 1 0)+eye_m33 = V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)++--------------------------------------------------------------------------------+-- QuikcCheck Arbitrary Instances+--------------------------------------------------------------------------------++instance QC.Arbitrary CFloat where+    arbitrary = CFloat <$> QC.arbitrary++instance QC.Arbitrary CDouble where+    arbitrary = CDouble <$> QC.arbitrary++instance (QC.Arbitrary a) => QC.Arbitrary (V2 a) where+    arbitrary = V2 <$> QC.arbitrary <*> QC.arbitrary++instance (QC.Arbitrary a) => QC.Arbitrary (V3 a) where+    arbitrary = V3 <$> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary++instance (QC.Arbitrary a) => QC.Arbitrary (V4 a) where+    arbitrary = V4 <$> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary <*> QC.arbitrary++instance (QC.Arbitrary a) => QC.Arbitrary (HRect a) where+    arbitrary = HRect <$> QC.arbitrary <*> QC.arbitrary++instance QC.Arbitrary Rect2i where+    arbitrary = toRect <$> (QC.arbitrary :: QC.Gen (HRect Int32))++instance QC.Arbitrary Point2i where+    arbitrary = toPoint <$> (QC.arbitrary :: QC.Gen (V2 Int32))++--------------------------------------------------------------------------------++assertNull+    :: [a] -- ^ List that should be empty.+    -> ([a] -> String) -- ^ Error when the list is not empty.+    -> IO ()+assertNull [] _showError = pure ()+assertNull xs  showError = assertFailure $ showError xs