从haskell调用C opencv函数 [英] Calling a C opencv function from haskell

查看:229
本文介绍了从haskell调用C opencv函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用OpenCV与Haskell。我的想法是从Haskell调用c ++函数。



现在我这样做:

  { - #LANGUAGE ForeignFunctionInterface# - } 

模块Lib

someFunc
)其中

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
}

ccall_ZN2cv6imreadERKNS_6StringEiimRead_ImRead :: CString - > CInt→> IO(Ptr LpImage)

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

我阅读这篇文章来自Haskell的CPlusPlus ,因此我得到了名称​​ _ZN2cv6imreadERKNS_6StringEi



但是GHCi说:


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


在Python中,我应该import cv2,但我不知道它如何在Haskell上工作。



a href =https://wiki.haskell.org/FFI_cook_book =nofollow> FFI厨师书但我不能得到我的问题的答案。



有什么想法吗?

解决方案


OpenCV api是用C ++编写的。这就是为什么调用它的方式在这里: haskell的C ++ 。但是当你在/ usr / lib /下安装OpenCV时,你不会得到一个.so文件,例如 cv2.so 。这意味着使用 foreign import ccall 很难使用c名称。
所以,我使用@ReidBarton说 haskell-opencv ,它很好地工作。或者至少比另一种方式更容易。



以下是使用示例:

 模块Lib 
(someFunc
)其中

import Control.Monad(void)
导入合格的OpenCV为CV
导入合格的Data.ByteString为B

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

stack.yaml 我添加了这个:

 包:
- 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
默认语言:Haskell2010

可执行文件simple-exe
hs-source-dirs:app
main -is:Main.hs
- ghc-options:-threaded -rtsopts -with-rtsopts = -N
build-depends:base
,simple
,opencv
,bytestring
默认语言: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

有人。


I'm trying to use OpenCV with Haskell. My idea is calling the c++ function from Haskell.

Right now I'm doing this:

{-# 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

I read this post CPlusPlus from Haskell, and so I got the name _ZN2cv6imreadERKNS_6StringEi. In 2.1.1 Finding the mangled named.

But GHCi says:

ByteCodeLink: can't find label During interactive linking, GHCi couldn't find the following symbol: _ZN2cv6imreadERKNS_6StringEi

In Python I should "import cv2", but I don't know how it works on Haskell.

I also read: FFI cook book But I can't get an answer to my question there.

Any idea?

解决方案

What I was trying doesn't work. The OpenCV api is written in C++. That's why the way to call it is here: C++ from haskell. But when you install OpenCV in "/usr/lib/", you don't get a .so file like cv2.so. It means that's quite difficult to use foreign import ccall as the c-name is not built. So, I used what @ReidBarton said "haskell-opencv" and it works nicely. Or at least easier than the other way.

Here is a use example:

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

in the stack.yaml I added this:

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

and so looks a part of the cabal file:

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

I hope it helps someone.

这篇关于从haskell调用C opencv函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆