首先,我对 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;
}
画线操作失败,但是如果我注释线画,我可以得到返回的图像。
这是怎么回事?