2016-09-23 50 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 

就是這樣。 :)我希望它可以幫助別人。