2016-09-23 54 views
0

H!haskell-opencv中的GaussianBlurImage(Haskell绑定到OpenCV-3.1)

我正在使用haskell-opencv库。我不知道另一个人是否正在使用它,或者知道这件事。

我试图使用gaussianBlurImage,但有一个我无法识别的错误。

我有这样的:

cropped image = do 
    resized <- resizeImage image 
    gaussianBlurred <- gaussianBlurImage ((M.unsafeCoerceMat . getImageFromEither) resized) 

调整要么CV.Exception(M.Mat形状的通道深度)我从这里((M.unsafeCoerceMat . getImageFromEither) resized)一个Mat shape (S channels) (S depth)作为gaussianBlurImage功能需求得到。

的我定义gaussianBlurImage这样:

gaussianBlurImage image = runExceptT $ CV.pureExcept $ CV.gaussianBlur (V2 13 13 :: V2 Int32) 0 0 image

对我来说,它看起来不错。类似于这里:blur。但是,我得到这个错误:

Couldn't match expected type ‘'True’ with actual type ‘Elem depth0 '[Word8, Word16, Float, Double]’

我注意到,我的gaussianBlurImage具有这种类型:

gaussianBlurImage :: (M.Mat shape0 ('S channels0) ('S depth0)) -> Either CV.CvException (Either CV.CvException (M.Mat shape0 ('S channels0) ('S depth0))) 

而且我很喜欢这一个:

gaussianBlurImage :: (M.Mat shape0 ('S channels0) ('S depth0)) -> Either CV.CvException (M.Mat shape0 ('S channels0) ('S depth0)) 

也许有事情做。

我试着用medianBlur,blur和gaussianBlur。我用了一个没有调整大小的图像,以及一个带有三个通道和另一个带有2个(颜色和灰色)的图像,而且我总是得到相同的错误。我想知道错误是否在M.unsafeCoerceMat image。为什么'True按预期类型?我没有想法

+1

你能提供一个最小的完整例子吗?你提供的片段不是任何人可以粘贴到文件中并尝试编译自己的东西。 –

+0

这里有一个要点:[gist](https://gist.github.com/Chuck-Aguilar/2a4a0506c2924c4d72134a45dc19935c) 我看到问题是与“深度”的类型,并补充说:'(深度'In' '[Word8,Word16,Float],频道'In''[1,3,4])=>'。但是,它仍然无法正常工作。我得到这个错误:'无法匹配类型'IO'与'任一CV.CvException'预期类型:CV.CvException()实际类型:IO()'这很奇怪,因为我应该能够显示图片。 –

回答

1

haskell-opencv是一个很好的库,但有时很难使用,因为有很多文档,但很难理解,并且没有很多示例。

在那里,每个模糊功能需要一个(M.Mat shape ('S channels) ('S depth))矩阵,但矩阵通常是这样的:(M.Mat shape channels depth),其中'S告诉它是静态的。

我用这个函数:

M.coerceMat有这样一个矩阵。

coerceMAt :: (ToShapeDS (Proxy shapeOut), ToChannelsDS (Proxy 
    channelsOut), ToDepthDS (Proxy depthOut))  
    => Mat shapeIn channelsIn depthIn  
    -> CvExcept (Mat shapeOut channelsOut depthOut) 

因为它返回CVExcept,我用exceptError :: CvExcept a -> a得到公正的形象。

但最重要的是函数的定义。我的代码中存在这个问题。 depth不能含糊,这就是为什么我说:

forall height0 width0 channels depth . (depth `In` '[Word8, Word16, Float, Double] , channels `In` '[1, 3, 4]) => M.Mat ('S '[height0, width0]) ('S channels) ('S depth) -> IO (M.Mat ('S '[height0, width0]) ('S channels) ('S depth)) 

这里有一个完整的例子。我得到一张图片,调整它的大小,模糊它并显示出来。

主要:

module Main where 

import Lib 
import qualified OpenCV.Internal.Core.Types.Mat as M 
import Control.Monad (void) 
import qualified OpenCV as CV 
import qualified Data.ByteString as B 

main :: IO() 
main = do 
    test <- controller 
    CV.withWindow "test" $ \window -> do 
     CV.imshow window test 
     void $ CV.waitKey 10000 

库:

{-# LANGUAGE TypeFamilies #-} 

module Lib 
    (controller 
    ) where 

import BlurImage 
import ResizeImage 
import Utils 
import Control.Monad (void) 
import Data.Word 
import qualified OpenCV.Internal.Core.Types.Mat as M 
import qualified OpenCV as CV 
import qualified Data.ByteString as B 

controller :: IO (CV.Mat (CV.S '[CV.D, CV.D]) (CV.S 1) (CV.S Word8)) 
controller = do 
    file <- B.readFile "path/to/image.jpg" 
    img <- return $ CV.imdecode CV.ImreadGrayscale file 
    resized_little_img <- resizeImage img --little image for making a blur in and find the receipt 
    blurImage ((CV.exceptError $ M.coerceMat resized_little_img) :: M.Mat (CV.S '[ CV.D, CV.D]) (CV.S 1) (CV.S Word8)) 

ResizeImage:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE FlexibleContexts #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 

module ResizeImage 
    ( 
    resizeImage 
    ) where 

import Utils 
import Control.Monad (void) 
import Control.Monad.Except 
import Data.Functor.Identity 
import Data.Word 
import Data.Proxy 
import qualified OpenCV as CV 
import Linear.V2 
import OpenCV.TypeLevel 
import qualified OpenCV.Internal.Core.Types.Mat as M 
import qualified OpenCV.Core.Types.Size as S 
import qualified OpenCV.ImgProc.GeometricImgTransform as GIT 
import GHC.Int (Int32) 

resizingImage :: (M.Mat (CV.S [CV.D, CV.D]) CV.D CV.D) -> CV.CvExcept (M.Mat (CV.S [CV.D, CV.D]) CV.D CV.D) 
resizingImage image = GIT.resize (GIT.ResizeAbs $ S.toSize $ (getSize w h Nothing (Just 500))) CV.InterCubic image 
    where 
     [h, w] = getHandW image 

resizeImage :: (M.Mat (S '[CV.D, CV.D]) CV.D CV.D) -> IO(M.Mat (CV.S [CV.D, CV.D]) CV.D CV.D) 
resizeImage image = do   
    resized <- return $ resizingImage image 
    return $ CV.exceptError $ resized 

BlurImage:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE FlexibleContexts #-} 
{-# LANGUAGE AllowAmbiguousTypes #-} 

module BlurImage 
    ( 
    blurImage 
    ) where 

import Utils 
import Control.Monad (void) 
import Control.Monad.Except 
import qualified Data.ByteString as B 
import Data.Word 
import Data.Proxy 
import qualified OpenCV as CV 
import Linear.V2 
import OpenCV.TypeLevel 
import qualified OpenCV.Internal.Core.Types.Mat as M 
import qualified OpenCV.Core.Types.Size as S 
import qualified OpenCV.ImgProc.GeometricImgTransform as GIT 
import GHC.Int (Int32) 


medianBlurImage :: (depth `In` '[Word8, Word16, Float], channels `In` '[1, 3, 4]) => (M.Mat shape ('S channels) ('S depth)) -> CV.CvExcept (M.Mat shape ('S channels) ('S depth)) 
medianBlurImage image = CV.medianBlur image 13 

gaussianBlurImage :: (depth `In` '[Word8, Word16, Float, Double], channels `In` '[1, 3, 4]) => (M.Mat shape ('S channels) ('S depth)) -> CV.CvExcept (M.Mat shape ('S channels) ('S depth)) 
gaussianBlurImage image = CV.gaussianBlur (V2 13 13 :: V2 Int32) 0 0 image 

blurImage :: forall height0 width0 channels depth . (depth `In` '[Word8, Word16, Float, Double] , channels `In` '[1, 3, 4]) => M.Mat ('S '[height0, width0]) ('S channels) ('S depth) -> IO (M.Mat ('S '[height0, width0]) ('S channels) ('S depth)) 
blurImage image = do 
    gaussianBlurred <- return $ gaussianBlurImage image  
    return $ CV.exceptError $ gaussianBlurred 

就是这样。 :)我希望它可以帮助别人。