Call OpenCV functions from C#.net

OpenCV is a C++ library, .net is different platform. Therefore, how to call Opencv functions from .net or how to call Opencv functions from C# or vb.net. This is possible because remember we are using Visual C++ for our Opencv projects and VC++ also a part of .net platform. This will allow you to wrap our specific opencv functions to be able to call from C#. A wrapper means an intermediate party which act as a communicator between 2 different sides. Simply you can use this technique to keep your front end GUI in C#, vb.net or WPF while keeping opencv as the back end to do image processing.

So now we are going to create this wrapper for our application. Since we are dealing with .net framework, we can use CLR (Common Language Runtime) technique to create this wrapper. First you have to create a CLR project in Visual Studio.

This post will describe, how to call Opencv functions from winfrom/C# and apply an Opencv filter to an image and show the Opencv window from winform.

Step 1 – Create a CLR project

Click on File-->New Project and select CLR under Visual C++ then select Class Library.

Then you will get a sample header file and cpp file for your wrapper class where you have to put all the functions' headers in class definition (in .h file) to be able to call from C#.

Step 2 -Apply OpenCV Configurations to the project.

 You can set all the project properties for Building and Linking a normal Opencv C++ project or you can import all the properties at once from an existing Property sheet as explained in this article.

Step 3 - Create CLR functions to call from C#


Now create a method in CLR class to call from C#. Here we need to keep something in mind, that is, C# deal with pointers (unless you specify as not a pointer/reference). Therefor all the parameters for this method should be pass as a pointer. But for now we will create a method without parameters.

Type following code in your class
    public:
        void ApplyFilter();


Now ApplyFilter is the method that we are going to call from C# using an object created from MyOpenCvWrapper class.

Step 4 - Include Opencv headers

Add all the header files of opencv that you need for this class, Here we just need cv.h and highgui.h. Remember to add include derivatives to your header file

#include <opencv\cv.h>
#include <opencv\highgui.h>


Step 5 - Code for the method

Open your cpp file and enter following code. This is the function that we are going to call from opencv and this is the code to do image processing. you can follow normal way to implement a class in C++.
#include "OpenCvDotNet.h"

using namespace OpenCvDotNet;
using namespace cv;

void MyOpenCvWrapper::ApplyFilter(){
    Mat image = imread("C:\\Pictures\\Hydrangeas.jpg");
    Mat dstImage;

    if (!image.data){
        return;
    }

    //Apply the Filter
    GaussianBlur(image, dstImage, Size(31, 31), 0);

    namedWindow("Image Window", CV_WINDOW_KEEPRATIO);
    imshow("Image Window", dstImage);
}



Code Explanation -
This code will open the image named "Hydrangeas.jpg" from "C:\Pictures" directory and check whether image opened successfully or not. Then it will apply a filter and show the result in an opencv window.

Step 6 - Add reference to C# project

Create and add a new project to your solution by Right click on your solution.

Now you can create either "Windows Form Application" or "WPF Application" or any other project type to use your opencv code. For this article I am using "Windows Form Application". After adding Winform project to your solution, your solution explorer should has 2 projects (CLR project and winform project).


Now you can Right click on Reference on WinFormProject and add reference to CLI project. You can find your project under Solutions/Project.

Step 6 - Call OpenCV from Winform project

Now you have made the link between winform and cli project which includes opencv calls. Note that the architecture (32bit or 64bit) of both projects should be same and the .net framework versions should be same on both projects to build your whole solution.

Use the class that we created from CLI project to create an object in C# and call the method that we created in CLI project from C#. then you should see the success !

I just added a button to my winform and call the method from there.

private void button1_Click(object sender, EventArgs e)
{
   OpenCvDotNet.MyOpenCvWrapper obj = new OpenCvDotNet.MyOpenCvWrapper();
   obj.ApplyFilter();
}

Step 7 - Run and test

Now you can run your winform application. Remember to set the winform project as the "Startup Project"
Then once you clicked on the button, you should see an opencv window showing a blur image.



This is a very simple way to call and get an output from opencv using winform/C#. My next post will describe how to pass a C# System.Drawing.Bitmap to CLI project and get the output image as a System.Drawing.Bitmap from the Opencv CLI.

5 comments:

  1. I keep getting the following error:

    "An unhandled exception of type 'System.IO.FileNotFoundException' occurred in System.Windows.Forms.dll"

    It looks like it cant load: OpenCvDotNet.dll

    Any ideas how to solve this?

    ReplyDelete
    Replies
    1. put *.dll files of OpenCV to the "bin" folder inside the WinFormProject, that may solve the problem.

      Delete
    2. Yes, either you can copy dll files from "YourOpencvDir\build\x86\vc12\bin" to your bin folder OR you can set this directory to system path environment variable. (make sure that you restart visual studio after set the path veriable)

      Delete
    3. Hello Sir,
      I am using same technique and it is working fine.
      The only problem I am facing is that, with multiple calls to the openCV c++ function i am getting memory leak. The memory used by application is increasing with iterations.
      Please suggest some solution

      Delete
  2. hi,
    I am getting Following error:LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in OpenCVWrapper.obj opencv_ts300d.lib(opencv_ts_pch.obj)

    ReplyDelete