OpenCV IplImage AccessViolationException

Прежде всего, я довольно новичок в OpenCV.
Я пытаюсь около недели без успеха, и кажется, что я никогда не смогу это сделать. Вот почему я должен обратиться за помощью к тому, кто столкнулся с той же проблемой.

Я хочу построить очень простое приложение в VC # 2010, которое в основном будет делать следующее:

  • прочитать изображение в формате JPEG и сохранить его в растровой переменной
  • отправить переменную Bitmap в функцию, инкапсулированную в dll VC ++
  • в dll VC ++ выполните простую операцию над изображением (например, нарисуйте круг)
  • вернуть измененное изображение в приложение 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);
}

Код в dll VC ++:

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

Не могли бы вы быть так любезны, дайте мне знать, где я ошибаюсь?
Или, может быть, предоставить небольшой пример кода, чтобы показать мне, как это сделать?

Обновить
Если я использую cvImageLoad внутри dll VC ++ для чтения файла jpeg с диска, операции рисования будут функциональными, и я могу вернуть измененное изображение. Проблема только в отправке изображения правильным способом в dll. Любое предложение Как я могу это сделать?

Также
Я изменил DLL в VC ++, как это

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

Операция рисования линии завершается неудачно, но если я прокомментирую рисование линии, я смогу вернуть изображение.

В чем дело?

1

Решение

Может быть проблема приведения, когда вы передаете свое растровое изображение в функцию testImage, которая принимает его как char *. Причина, по которой я так думаю, заключается в том, что когда у вас нет данных изображения и вы пытаетесь их получить, это приводит к такой ошибке. Можете ли вы отладить его и посмотреть, доступны ли данные в изображении или использовать

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

редактировать

Я не использовал Opencv с C #, но обычно люди используют opencvsharp, emgu или другие альтернативы. Но твой путь кажется неуместным. Использовать opencv dll s с C #; они говорят, что это требует обертки или что-то подобное. Они предлагают Эмгу для C #.

Также вы скомпилировали свою dll с включенным COM-взаимодействием? (Чтобы использовать c ++ dll с C #, говорят, что он должен быть скомпилирован как COM). Но я не думаю, что это все еще будет работать. Должна быть причина всех этих оболочек Emgu, opencvdotnet, opencvsharp и т. Д. Правильно?

1

Другие решения

Других решений пока нет …