首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenCV在Go中不带SWIG和第三方库

OpenCV在Go中不带SWIG和第三方库
EN

Stack Overflow用户
提问于 2014-09-23 16:06:31
回答 2查看 447关注 0票数 0

主要目标:使OpenCV在没有SWIG和第三方库的情况下在Go中工作(一个在linux中使用Go比较映像的应用程序)

我是所有套件中的新成员(OpenCv,Go和linux)

  1. 图像检测(feature2d等)只能由Can完成吗?调用C++代码没有方便的方法,也没有更新call (?)
  2. 我跟踪了How to use C++ in Go?,但失败了。当我做时,我得到以下错误

makefile:5: /usr/local/go/bin/src/make.amd 64:没有这样的文件或目录 makefile:6: /usr/local/go/bin/src/Make.pkg:没有这样的文件或目录 makefile:8:*缺少分隔符。停止播放。

makefile如下所示

代码语言:javascript
运行
复制
GOROOT=/usr/local/go/bin  
   GOARCH=amd64  
   TARG=foo  
   CGOFILES=foo.go  
   include $(GOROOT)/src/Make.$(GOARCH)  
   include $(GOROOT)/src/Make.pkg  
   foo.o:foo.cpp  
   g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $<  
   cfoo.o:cfoo.cpp  
   g++ $(_CGO_CFLAGS_$(GOARCH)) -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $<  
   CGO_LDFLAGS+=-lstdc++  
   $(elem)_foo.so: foo.cgo4.o foo.o cfoo.o  
   gcc $(_CGO_CFLAGS_$(GOARCH)) $(_CGO_LDFLAGS_$(GOOS)) -o $@ $^ $(CGO_LDFLAGS)  

非常感谢

EN

回答 2

Stack Overflow用户

发布于 2014-09-23 16:25:27

如果不自己编写C包装器(+ cgo)或使用SWIG,就不能调用C++代码,这是可悲的。

你链接的那篇文章已经过时了,不能再用了。

另一方面,你可以在纯go中开始重写opencv,速度差异不会太大,特别是如果你学习如何使用不安全的速度关键部件。

不建议使用不安全的免责声明,因为它是不安全的。

票数 1
EN

Stack Overflow用户

发布于 2014-09-24 23:50:41

您可以这样做,为了我自己的目的,我已经将OpenCV的一个非常微不足道的子集移植到Go中。通常,这个过程是分配堆上的所有内容,并将其返回为the‘d void*。例如:

代码语言:javascript
运行
复制
typedef void* gocv_matrix;

从那里开始,你的很多工作都是传递函数。一个非常重要的注意事项是,您的头文件必须是纯C,并且必须(递归地)包含纯C的头文件。这意味着您的头将主要是原型/前向声明。

因此,头mat.h中的一些矩阵方法看起来可能如下所示

代码语言:javascript
运行
复制
gocv_matrix newMatrix();
void add(gocv_matrix m1, gocv_matrix m2, gocv_matrix dst);
void destroy(gocv_matrix m);

然后,您在mat.cxx中的实现将类似于

代码语言:javascript
运行
复制
//include all relevant C++ OpenCV headers directly
gocv_matrix newMatrix() {
    cv::Matrix *mat = new cv::Matrix();
    return (gocv_matrix)mat;
}

void add(gocv_matrix m1, gocv_matrix m2, gocv_matrix dst) {
    cv::Matrix *a = (cv::Matrix *)m1;
    cv::Matrix *b = (cv::Matrix *)m2;
    cv::Matrix *dstMat = (cv::Matrix *)dst;
    (*dstMat) = (*a)+(*b);
}

void destroy(gocv_matrix m) {
    cv::Matrix *a = (cv::Matrix *)(m1);
    delete a;
}

(免责声明:这里的确切代码没有验证正确性,这只是要点)。

几个特别注意事项:

  • 确保您有一个实际调用的破坏方法,否则会泄漏内存。
  • 由于C和C++常量与Go常量不同,所以必须将它们声明为var而不是const
  • OpenCV的一些常量包含在非纯C的标头中,这使得在Go中定义它们非常困难。我在一些图像处理子包中注意到了这一点。
  • 注意缺乏模板化的泛型。通常,您要么完全放弃模板,为每个可能的实例定义不同的类型,要么选择一个(可能是双倍,可能是显示图像的int大小)并坚持使用它。
  • 请注意,不能以这种方式使用重载运算符。所以a+b*c是b.Mul(c).Add(a)。理论上,您可以发明一些表达式解析器,它接受一个字符串,如"a+(b*c)“和一个矩阵列表,然后进行调用批处理,但是如果您在开发的那个阶段,您就不会问这个问题了。
  • 这在cgo中通常是正常的,但是您可能会使用很多不安全的东西,特别是如果您想直接使用矩阵的原始备份数据。您可以通过使Go级别Mytype类型成为包含C.mytype的简单结构而不是实际转换来减少这种情况。

老实说,您可能应该只使用SWIG,因为这基本上已经是它对您所做的,除了额外的细节,比如在大多数情况下为您生成实际的Go常量,而不是粗略的var魔术。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25999768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档