2016-09-15 213 views
1

我正在尝试与Haskell一起使用OpenCV。我的想法是从Haskell调用C++函数。从haskell调用C opencv函数

现在我这样做:

{-# LANGUAGE ForeignFunctionInterface #-} 

module Lib 
    (
     someFunc 
    ) where 

import Foreign.C 
import Foreign.C.String 
import Foreign.C.Types 
import Foreign.Ptr 

data LplROI = LplROI { 
    coi :: CInt, 
    xOffset :: CInt, 
    yOffset :: CInt 
} 

data LpImage = LpImage { 
    align :: CInt, 
    alphaChannel :: CInt, 
    borderConst :: CInt, 
    borderMode :: CInt, 
    channelSeq :: CChar, 
    colorModel :: CChar, 
    dataOrder :: CInt, 
    depth :: CInt, 
    height :: CInt, 
    id :: CInt, 
    imageData :: CChar, 
    mageDataOrigin :: CChar, 
    imageId :: CChar, 
    imageSize :: CInt, 
    maskROI :: LpImage, 
    nChannels :: CInt, 
    nSize :: CInt, 
    origin :: CInt, 
    roi :: LplROI, 
    tileInfo :: CChar, 
    width :: CInt, 
    widthStep :: CInt 
} 

foreign import ccall "_ZN2cv6imreadERKNS_6StringEi" imRead_ImRead :: CString -> CInt -> IO (Ptr LpImage) 

someFunc = do 
    filename <- newCString "/home/chuck/Pictures/such-a-bad-day.jpg" 
    imRead_ImRead filename 1 

我看到这篇文章CPlusPlus from Haskell,所以我把名字_ZN2cv6imreadERKNS_6StringEi2.1.1查找名为的mangled。

但GHCI说:

ByteCodeLink:找不到标签 在交互链接,GHCI找不到以下符号: _ZN2cv6imreadERKNS_6StringEi

在Python我应该“进口CV2 “,但我不知道它如何在Haskell上工作。

我也读过:FFI cook book但我不能在那里得到我的问题的答案。

有什么想法?

+0

你如何告诉GHCi搜索这个符号的库? –

+0

这是一个很好的问题。我不知道。我在这里没有看到:[Haskell的CPlusPlus](https://wiki.haskell.org/CPlusPlus_from_Haskell)他在哪里做的。我想也许在cabal文件中。是这样的:'库 HS-源显示目录:SRC 暴露模块:库 积累取决于:碱> = 4.7 && <5 默认语言:Haskell2010' 随着ghci中选择,但我不当然。 –

+0

如果您有cabal文件,请尝试'cabal repl'而不是'ghci'。 Cabal应该告诉ghci使用哪些库。 –

回答

2

我正在尝试不起作用。 OpenCV API是用C++编写的。这就是为什么要这样称呼它的原因:C++ from haskell。但是当你在“/ usr/lib /”中安装OpenCV时,你不会得到一个.so文件,如cv2.so。这意味着使用foreign import ccall相当困难,因为未建立c-name。 因此,我使用@ReidBarton所说的“haskell-opencv”,它很好地工作。或者至少比其他方式更容易。

下面是一个使用示例:

module Lib 
(someFunc 
) where 

import Control.Monad (void) 
import qualified OpenCV as CV 
import qualified Data.ByteString as B 

someFunc :: IO() 
someFunc = do 
    img <- CV.imdecode CV.ImreadUnchanged <$> B.readFile "/some_pic.jpg" 
    CV.withWindow "test" $ \window -> do 
    CV.imshow window img 
    void $ CV.waitKey 10000 

stack.yaml我加了这一点:

packages:  
- location: 
    git: https://github.com/LumiGuide/haskell-opencv.git 
    commit: 07afde39fa16f7a4282d4a812e70b9ed33d0f3ef 
- '.' 

等看起来小集团文件的一部分:

library 
hs-source-dirs:  src 
    exposed-modules:  Lib 
    build-depends:  base >= 4.7 && < 5 
        , opencv 
        , bytestring 
    default-language: Haskell2010 

executable simple-exe 
    hs-source-dirs:  app 
    main-is:    Main.hs 
-- ghc-options:   -threaded -rtsopts -with-rtsopts=-N 
    build-depends:  base 
        , simple 
        , opencv 
        , bytestring 
    default-language: Haskell2010 

test-suite simple-test 
    type:    exitcode-stdio-1.0 
    hs-source-dirs:  test 
    main-is:    Spec.hs 
    build-depends:  base 
        , simple 
        , opencv 
        , bytestring 
-- ghc-options:   -threaded -rtsopts -with-rtsopts=-N 
    default-language: Haskell2010 

希望它有助于某人。

+0

haskell-opencv不能通过hackage得到,是吗? –

+0

nope,它不是hackage –