从haskell调用C opencv函数 [英] Calling a C opencv function from haskell
问题描述
我试图使用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屋!