【问题标题】:Calling a C opencv function from haskell从haskell调用C opencv函数
【发布时间】:2017-01-23 04:04:28
【问题描述】:

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

现在我正在这样做:

{-# 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_6StringEi。在 2.1.1 中找到被损坏的命名

但是 GHCi 说:

ByteCodeLink:找不到标签 在交互式链接期间,GHCi 找不到以下符号: _ZN2cv6imreadERKNS_6StringEi

在 Python 中我应该“导入 cv2”,但我不知道它在 Haskell 上是如何工作的。

我还阅读了:FFI cook book 但我无法在那里得到我的问题的答案。

有什么想法吗?

【问题讨论】:

  • 你如何告诉 GHCi 在哪些库中搜索这个符号?
  • 这是个好问题。我不知道。我在这里看不到:CPlusPlus from Haskell 他在哪里做的。我想也许在阴谋集团文件中。像这样:library hs-source-dirs: src exposed-modules: Lib build-depends: base &gt;= 4.7 &amp;&amp; &lt; 5 default-language: Haskell2010 带有 ghci 选项,但我不确定。
  • 如果您有 cabal 文件,请尝试使用 cabal repl 而不是 ghci。 Cabal 应该告诉 ghci 使用哪些库。
  • 我尝试了cabal replstack repl,但我仍然遇到同样的错误。我应该在哪里指定库? @n.m.
  • 我建议尝试使用现有的 OpenCV 绑定,例如 github.com/LumiGuide/haskell-opencv

标签: c++ c opencv haskell


【解决方案1】:

我尝试的方法不起作用。 OpenCV api 是用 C++ 编写的。这就是为什么调用它的方式在这里:C++ from haskell。但是当您在“/usr/lib/”中安装 OpenCV 时,您不会得到像 cv2.so 这样的 .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
 - '.'

所以看起来是 cabal 文件的一部分:

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

我希望它对某人有所帮助。

【讨论】:

  • haskell-opencv 不能通过 hackage 获得,是吗?
猜你喜欢
  • 1970-01-01
  • 2017-03-12
  • 2011-06-28
  • 2013-05-13
  • 2013-10-08
  • 1970-01-01
  • 2015-10-21
  • 2013-07-22
  • 1970-01-01
相关资源
最近更新 更多