【问题标题】:Creating an C++/CLI OpenCV wrapper to use in C#创建 C++/CLI OpenCV 包装器以在 C# 中使用
【发布时间】:2014-04-04 13:19:05
【问题描述】:

我想创建一个 OpenCV 包装器以在 C# 中使用它。我使用这个链接作为参考http://drthitirat.wordpress.com/2013/06/06/use-opencv-c-codes-in-a-vc-project-solution-of-creating-a-managed-clr-wrapper/ 到目前为止,我已经创建了一个包含我的图像处理代码的 C++ 控制台应用程序。我还创建了一个 C++/CLI 类库,在其中包装了 OpenCV 代码,但是当我尝试构建它时,我得到了很多关于 C++ 代码中使用的 OpenCV 函数的未解决的外部错误,我不知道如何修复它...知道如何解决这个问题吗?有没有更简单的方法在 C# 中使用 C++ OpenCV 代码?我不想使用 Emgu 或任何其他包装器,我的图像处理代码必须在 C++ 中。

【问题讨论】:

  • 为什么不使用现有的 OpenCV .NET 包装器? emgu.com/wiki/index.php/Main_Page
  • 不,很遗憾我的图像处理代码必须用 C++ 编写。
  • 链接器命令中缺少未解析的外部文件。只需填写其他库目录并在输入中填写您的 lib 文件。另一件事是当你需要在 C# 中使用图像时,你必须在 OpenCV 图像结构和位图之间进行转换。
  • 是的,我添加了 Debug 和 Release 的属性表并检查了所有内容,但错误仍然存​​在。我不知道该怎么办...关于Bitmap和Mat之间的转换有什么建议吗?

标签: c# opencv c++-cli


【解决方案1】:

我如何使用 Visual Studio 2012 解决 opencv 的问题:

  1. 我使用 opencv 创建了一个 c++ 图像处理库,并将其编译为静态库 (.lib),如 here 所述。基本上,创建一个控制台应用程序项目并将项目配置 -> 常规 -> 配置类型更改为“静态库 (.lib)”。这会将您的项目编译为 .lib 文件,稍后您应该在 c++/cli 中使用该文件。
  2. 然后我制作了一个 C++/CLI 包装器 - 对于我即将发布到 c# 中的每个 c++ 类,我制作了一个类似 this link 的包装器。我只是通过添加到项目(如添加到项目->现有项目并从项目 1 中选择标头)来使用 c++ 中的现有标头。这也有一个优点,如果您更改 .lib 文件中的某些内容,您将拥有相同的 .h 文件,所以当您重新编译 .lib,您不必更改 c++/cli 中的标头。我从 1 中包含了 .lib。转到项目属性 -> 链接器 -> 输入 -> 附加依赖项并将路径放入 .lib 文件。该项目被编译为 .dll 文件。 (项目配置->常规->配置类型->“动态库(.dll)”)。
  3. 在 c# 项目中,我刚刚添加了对 .dll 的引用,并使用了来自 c++/cli 的类,它们是托管类。这就是魔法的运作方式。

备注 A:我可以保证这个解决方案有效。我在 opencv 2.4.2 中使用了模式检测和 camshift 等功能。

备注 B: 另一个主题是应该如何进行编组。在简单数据类型的情况下,毫无疑问使用 c++/cli 数据类型,如 UInt32 等。但问题是,如果你想传递更复杂的对象,如 cv::Mat,它们在 c++/cli 中没有直接等效的类型.在这种情况下,我在 c++/cli 端制作了此类类的简化版本。

备注 C: 不要在不同的项目中混淆架构。如果您正在使用例如x86,在所有项目中都是结果。

备注 D: 实际上,在 c# 中使用 c++ 代码的问题有两种解决方案:一种是我描述的,另一种是使用动态即时编组从 c# 托管代码直接调用 c++ 非托管代码.有两个主要缺点:动态编组需要时间,而且您并不真正知道如何在复杂数据类型(即与 int 或 string 不同的所有内容)之间准确地做到这一点。所以 c++/cli 它确实是一个不错的选择,因为您可以混合托管和非托管代码。

备注E:这个解决方案是通用的,它不仅仅在opencv中计算。我成功地使用这个制作 c++/cli 包装器到只有 c++ 驱动程序并在 c# 代码中使用该驱动程序的旋转阶段(电机设备)。

关于备注 C:使用像 Depends (http://www.dependencywalker.com/) 这样的依赖遍历器来查看哪些依赖是不一致的。

【讨论】:

  • 我对创建静态库感到困惑。这是msdn.microsoft.com/en-us/library/ms235627.aspx 吗?如何将其包含在包装器中?感谢您的帮助。
  • 没错。我在解决方案中添加了更多细节,享受吧。
  • 非常感谢,您的帮助很大!
  • @marol 我正在尝试使用您的解决方案,但是我收到错误 1 ​​错误 LNK2038:检测到“RuntimeLibrary”不匹配:值“MT_StaticRelease”与 CLRWrapper 中的值“MD_DynamicRelease”不匹配。 obj,这意味着 openCV 静态库不符合与 C++/CLI 项目相同链接的标志。你是如何克服这个问题的?
  • @Gilad 基本上我没有遇到这样的问题。也许这个stackoverflow.com/questions/14714877/… 可能会有所帮助。也许您的调试/发布不匹配?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多