Question

First of all, I'm quite new to OpenCV. I'm trying for about one week without success and it seems like I will never make it. That's why I have to ask for help from someone who faced the same issue.

I want to build very simple application in VC# 2010 which will basically do the following:

  • read a JPEG image and store it to a Bitmap Variable
  • send the Bitmap variable to a function encapsulated in a VC++ dll
  • in the VC++ dll perform a simple operation on the image ( draw a circle for example)
  • return the modified image to the VC# app and display it in a PictureBox

Code in VC#:

[DllImport("CppTestDll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern Bitmap testImage(Bitmap img);

private void button1_Click(object sender, EventArgs e)
    {
        // read the source jpeg from disk via a PictureBox
        Bitmap bmpImage = new Bitmap(pictureBox1.Image);

       //call the function testImage from the VC++ dll
   //  and assign to another PictureBox the modified image returned by the dll
        pictureBox2.Image = (System.Drawing.Image)testImage(bmpImage);
    }

Code in the VC++ dll:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>

#include <stdio.h>

using namespace cv;
using namespace std;

    __declspec(dllexport) char* testImage(char *image)
    {
        //the image is 640x480
        //read the jpeg image into a IplImage structure
       IplImage *inputImg= cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 3); 
       inputImg->imageData = (char *)image;

        // I also tried to copy the IplImage to a Mat structure
        // this way it is copying onl the header
        // if I call Mat imgMat(inputImg, true); to copy also the data, I receive an error for Memory read access
        Mat imgMat(inputImg);

        // no matter which circle drawing method I choose, I keep getting the error
        //  AccessViolationException was unhandled. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

        cvCircle(inputImg,Point(100,100),100,cvScalar(0, 0, 255, 0),1,8,0);
        circle(imgMat,Point(100,100),100,Scalar(0, 0, 255, 0),1,8,0);

        // I tried both ways to return the image
        // If I try to modify the image I receive the above described error
        // If I don't modify the input image, I can send back the original image, but it is useless

        //return (char *)imgMat.data;
        return (char *)inputImg->imageData;
    }

Could you please be so kind to let me know where I am mistaking? Or maybe provide a small sample code to show me how to do it?

Update If I use cvImageLoad inside VC++ dll to read the jpeg file from disk, the drawing operations are functional and I can return the modified image. The problem is just sending the image in the correct way to dll. Any suggestion How I can do this?

Also I changed the dll in VC++ like this

__declspec(dllexport) char* testImage(uchar* image)
{
        uchar *pixels = image;
        Mat  img(480,640,CV_8UC3,pixels);

        if (!img.data)
        {
            ::MessageBox(NULL, L"no data", L"no data in imgMat mat", MB_OK);
        }

        line(img,Point(100,100),Point(200,200),Scalar(0, 0, 255, 0),1,8,0);
        return (char *)img.data;
    }

The line drawing operation fails, but If I comment the line drawing, I can get the image returned.

What's going on?

Was it helpful?

Solution

There can be a casting problem when you give your bitmap image to testImage function which takes it as char* . The reason I think so is when you have no image data and try to reach it it gives this kind of error. Can you debug it and see if data is available in image or use

if(!imgMat.data)
   //error. Print something or break

Edit

I didnt use Opencv with C# but normally people use opencvsharp,emgu or other alternatives. But your way seems inappropriate. To use opencv dll s with C#; they say it require wrappers or something like that. They suggest Emgu for C#.

Also did you compile your dll with COM interop enabled? (To use c++ dlls with C# they say it should be compiled as COM). But I dont think it would still work. There must be a reason behind all these Emgu,opencvdotnet,opencvsharp etc. wrappers. Right?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top