1

首先,我对 OpenCV 很陌生。我尝试了大约一周没有成功,似乎我永远不会成功。这就是为什么我不得不向面临同样问题的人寻求帮助。

我想在 VC# 2010 中构建非常简单的应用程序,它基本上会执行以下操作:

  • 读取 JPEG 图像并将其存储到位图变量
  • 将位图变量发送到封装在 VC++ dll 中的函数
  • 在 VC++ dll 中对图像执行一个简单的操作(例如画一个圆圈)
  • 将修改后的图像返回到 VC# 应用程序并显示在 PictureBox 中

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

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

请你好心让我知道我在哪里弄错了吗?或者也许提供一个小示例代码来告诉我如何做到这一点?

更新 如果我在 VC++ dll 中使用 cvImageLoad 从磁盘读取 jpeg 文件,则绘图操作正常,我可以返回修改后的图像。问题只是以正确的方式将图像发送到 dll。任何建议我该怎么做?

我也 像这样更改了VC++中的dll

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

画线操作失败,但是如果我注释线画,我可以得到返回的图像。

这是怎么回事?

4

1 回答 1

1

当您将位图图像提供给将其作为 char* 的 testImage 函数时,可能会出现转换问题。我认为是这样的原因是,当您没有图像数据并尝试访问它时,会出现这种错误。您可以调试它并查看图像中的数据是否可用或使用

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

编辑

我没有在 C# 中使用 Opencv,但通常人们使用opencvsharp、emgu或其他替代方案。但你的方式似乎不合适。在 C# 中使用 opencv dll ;他们说它需要包装器或类似的东西。他们建议将 Emgu 用于 C#。

你还编译你的 dll 并启用 COM 互操作吗?(要在 C# 中使用 c++ dll,他们说它应该编译为 COM)。但我认为它仍然行不通。所有这些 Emgu、opencvdotnet、opencvsharp 等包装器背后一定有一个原因。正确的?

于 2012-09-06T06:58:46.797 回答