OpenCV IplImage访问违规异常

OpenCV IplImage AccessViolationException

本文关键字:异常 访问 IplImage OpenCV      更新时间:2023-10-16

首先,我对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;
    }

线条绘制操作失败,但如果我对线条绘制进行注释,我可以返回图像。

怎么回事?

当您将位图图像提供给testImage函数时,可能会出现强制转换问题,该函数将位图图像作为char*。我这么认为的原因是,当你没有图像数据并试图获取它时,会出现这种错误。你能调试它,看看图像中的数据是否可用,或者使用吗

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

编辑

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

您是否在启用COM互操作的情况下编译dll?(要将c++dll与c#一起使用,他们说应该将其编译为COM)。但我认为它仍然不起作用所有这些Emgu、opencvdotnet、opencvsharp等包装背后一定有原因。对吧