没有SWIG和第三方库的Go中的OpenCV

时间:2014-09-23 16:06:31

标签: go wrapper

主要目标:让OpenCV在没有Go的{​​{1}}和第三方lib(使用Go比较linux中的图像的应用程序)中工作

我是所有套件中的新手(OpenCv Go和linux)

  1. 图像检测(feature2d等)只能由C-api完成吗? 没有方便的方法来调用C ++代码并且C-api没有更新(?)

  2. 我跟着How to use C++ in Go?,但我失败了。 当我制作时,我收到以下错误

  3.   

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

    makefile 如下所示

    SWIG

    非常感谢

2 个答案:

答案 0 :(得分:1)

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

您关联的帖子非常过时,无法再使用了。

另一方面,您可以随时开始重写opencv,速度差异不会那么大,特别是如果您学习如何对速度关键部分使用不安全的。

不建议使用不安全的

免责声明 ,因为它不安全。

答案 1 :(得分:0)

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

typedef void* gocv_matrix;

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

因此标题mat.h中的一些Matrix方法可能看起来像

gocv_matrix newMatrix();
void add(gocv_matrix m1, gocv_matrix m2, gocv_matrix dst);
void destroy(gocv_matrix m);

然后您在mat.cxx中的实现看起来像

//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;
}

(免责声明:此处的确切代码未经过正确性验证,这只是要点)。

一些特别说明:

  • 确保您有一个实际调用的destroy方法,否则您将泄漏内存。
  • 由于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 magic。