2016-09-15 203 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 –