2017-04-07 3 views
1

Ich versuche zu verstehen Bibliothek.Definieren Sie den richtigen Typ für CoreCeMatM in Haskell-Opencv

Und ich Port orb-Erkennung example für meine Bilder:

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE OverloadedStrings #-} 
import Control.Monad 
import Linear.V4 
import Linear.V2 
import OpenCV as CV 
import OpenCV.Internal.Mutable 
import qualified Data.ByteString as B 


main = do 
    img <- imdecode ImreadColor <$> B.readFile "input.jpg" 
    let orb = mkOrb defaultOrbParams 
    let imgData = exceptError $ do 
      (kpts, _descs) <- orbDetectAndCompute orb img Nothing 
      let mi = matInfo img 
       clr = (toScalar $ V4 (255::Double) 255 255 0)::(Scalar) 
       shape = toShape $ miShape mi 
       chan = toChannels $ miChannels mi 
       depth = toDepth $ miDepth mi 
      resImg <- withMatM shape chan depth clr $ \imgM -> do 
       let img' = exceptError $ coerceMatM imgM 
        img'' = (unMut img'')::CV.Mat ('S ['D, 'D]) 'D 'D 
        img''' = Mut img'' 
       -- let img''' = (exceptError $ coerceMatM imgM)::(CV.Mut (CV.Mat ('S ['D, 'D]) 'D 'D) (PrimState (ST s))) 
       void $ matCopyToM img''' (V2 0 0) img Nothing 
       forM_ kpts $ \kpt -> do 
        let kptRec = keyPointAsRec kpt 
        circle img''' (round <$> kptPoint kptRec) 5 (V4 (255::Double) 0 0 255) 1 LineType_AA 0 
        return() 
      imencode OutputBmp resImg 
    B.writeFile "output.bmp" imgData 

Ufff, nach zwei Stunden der Dokumentation zu lesen, es funktioniert!

Aber ich kann nicht verstehen, wie man richtig corecing von Mat schreiben und typeing es ist mein Code sehr hässlich:

let img' = exceptError $ coerceMatM imgM 
    img'' = (unMut img')::CV.Mat ('S ['D, 'D]) 'D 'D 
    img''' = Mut img' 

Ich packe mit unMut und es dann wieder packen.

Ich versuche Art von Mut (Mat ...) angeben (siehe Zeile oben kommentiert):

let img''' = (exceptError $ coerceMatM imgM) 
    ::(CV.Mut (CV.Mat ('S ['D, 'D]) 'D 'D) (PrimState (ST s))) 

Aber Compiler schwört:

src/exmpl.hs:29:60: error: 
    • Couldn't match type ‘s’ with ‘s2’ 
     ‘s’ is a rigid type variable bound by 
     a type expected by the context: 
      forall s. 
      Mut 
      (Mat 
       (ShapeT (Data.Vector.Vector GHC.Int.Int32)) 
       (ChannelsT GHC.Int.Int32) 
       (DepthT Depth)) 
      (PrimState (ST s)) 
      -> CvExceptT (ST s)() 
     at src/exmpl.hs:23:27 
     ‘s2’ is a rigid type variable bound by 
     an expression type signature: 
      forall s2. Mut (Mat ('S '['D, 'D]) 'D 'D) (PrimState (ST s2)) 
     at src/exmpl.hs:29:67 
     Expected type: Mut (Mat 'D (ChannelsT GHC.Int.Int32) 'D) s2 
     Actual type: Mut 
         (Mat 
          (ShapeT (Data.Vector.Vector GHC.Int.Int32)) 
          (ChannelsT GHC.Int.Int32) 
          (DepthT Depth)) 
         (PrimState (ST s)) 

Also, wie richtige Art für img''' bestimmen ??

Antwort

0

Ich habe das herausgefunden. Es müssen pureExcept verwenden und scoped Variablen vom Typ:

(imgM''':: Mut (Mat (S [D, D]) D D) s) <- pureExcept $ coerceMatM imgM 

So vollständige Programm ist:

{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE RankNTypes #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
import Control.Monad 
import Linear.V2 
import Linear.V4 
import OpenCV as CV 
import qualified Data.ByteString as B 


main = do 
    img <- imdecode ImreadColor <$> B.readFile "input.jpg" 
    let orb = mkOrb defaultOrbParams 
    let imgData = exceptError $ do 
      (kpts, _descs) <- orbDetectAndCompute orb img Nothing 
      let mi = matInfo img 
       clr = (toScalar $ V4 (255::Double) 255 255 0)::(Scalar) 
       shape = toShape $ miShape mi 
       chan = toChannels $ miChannels mi 
       depth = toDepth $ miDepth mi 
      resImg <- withMatM shape chan depth clr $ \imgM -> do 
       (imgM':: Mut (Mat (S [D, D]) D D) s) <- pureExcept $ coerceMatM imgM 
       void $ matCopyToM imgM' (V2 0 0) img Nothing 
       forM_ kpts $ \kpt -> do 
        let kptRec = keyPointAsRec kpt 
        circle imgM' (round <$> kptPoint kptRec) 
           5 
           (V4 (255::Double) 0 0 255) 
           1 
           LineType_AA 
           0 
        return() 
      imencode OutputBmp resImg 
    B.writeFile "output.bmp" imgData 
Verwandte Themen