Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an C++/CLI OpenCV wrapper to use in C#

Tags:

c#

opencv

c++-cli

I want to create an OpenCV wrapper to use it in C#. I am using this link as a reference http://drthitirat.wordpress.com/2013/06/06/use-opencv-c-codes-in-a-vc-project-solution-of-creating-a-managed-clr-wrapper/ So far I have created a C++ console application that contains my image processing code. Also I created a C++/CLI class library in which I wrapped the OpenCV code, but when i try to build it I get a lot of unresolved externals errors about OpenCV functions used in the C++ code and I don't know how to fix it... Any idea how to fix the problem? Is there a simpler, easier way of using C++ OpenCV code in C#? I don't want to use Emgu or any other wrapper, my image processing code has to be in C++.

like image 669
DBWhite Avatar asked Mar 03 '14 13:03

DBWhite


1 Answers

How I solved the problem with opencv using visual studio 2012:

  1. I created a c++ image processing library with opencv and compiled it to a static library (.lib) as mentioned here. Basically, create an console application project and change in Project configuration -> General -> Configuration type to a "static library (.lib)". That will compile your project to a .lib file which later you should use in c++/cli.
  2. Then i made a C++/CLI wrapper - for each class in c++ I was about to publish to c# I made a wrapper like in this link. I used existed headers from c++ just by adding to project like Add to project -> Existing Items and choose headers from project 1. This also have an advantage that if you change something in .lib file, you have the same .h files so when you recompile .lib, you don't have to change headers in c++/cli. I included .lib from 1. going to Project properties -> Linker -> Input -> Additional dependencies and put the path to the .lib file. This project was compiled to .dll file. (Project configuration -> General -> Configuration type -> "dynamic library (.dll)").
  3. In c# project I've just add to references the .dll and used classes from c++/cli , which are managed classes. And that is how magic works.

Remark A: I can assure that this solution worked. I used features like pattern detection and camshift with opencv 2.4.2.

Remark B: Another topic is how exactly marshalling should be made. In case of simple data types, there is no doubt in using c++/cli data types like UInt32 etc. But the question is if you want to pass more sophisticated objects like cv::Mat which do not have types direct equivalent in c++/cli. In that case, I made simplified version of such classes on c++/cli side.

Remark C: Don't mess architecture in different projects. If you are using e.g. x86, be consequent in all projects.

Remark D: Practically, the problem using c++ code in c# has two solutions: the one I described and the direct calling to c++ unmanaged code from c# managed code using dynamic on-the-fly marshalling. There are two major disadvantages: on-the-fly marshalling takes time and you do not really know how exactly do this between complex data types (namely, everything what is different than int or string). So c++/cli it is really a good option because you are able to mix managed and unmanaged code.

Remark E: This solution is general, it does not count only in opencv. I successfully used this making c++/cli wrappers to rotation stages (motor devices) which only have c++ drivers and used that drivers in c# code.

Regarding Remark C: Use a dependency walker like Depends (http://www.dependencywalker.com/) to see which dependencies are not consistent.

like image 62
marol Avatar answered Sep 19 '22 20:09

marol