2017-04-07 6 views
1

私はhaskell-opencvライブラリを理解しようとしています。haskell-opencvのcoreceMatMに適切なタイプを定義してください

そして、私、私のイメージのためのポートオーブ検出example

{-# 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、ドキュメントを読むの2時間後に、それは働きます!

しかし、私は私のコードは非常に醜いです、適切にマットのcorecingを書いて、それをtypeingする方法を理解することはできません。

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

私はunMutで解凍し、それをバックパック。

私は(上記のコメント行を参照)Mut (Mat ...)のタイプを指定しよう:

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

しかし、コンパイラは誓う:

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)) 

ので、img'''のための右のタイプを決定する方法?

答えて

0

私はこれを理解しました。それはpureExceptを使用する必要がありますし、型変数をスコープ:

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

だから完全なプログラムは次のとおりです。

{-# 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 
関連する問題