2012-07-23 70 views
2

我有一个C++的DLL构建,并将返回Mat对象。 该图片信息是384 * 384 * 24色。C + + DLL返回到C##

C#代码

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test1()); 
pictureBox0.Image = a; 

C++代码

uchar* DLL_EXPORT test1(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 1); 

    return OriginalImg.data; 
} 

在代码都OK,但我想读在灰色图片。 我会做一些图像处理(例如:Threshod),并转换为颜色, 并返回到C#并显示它!

C++代码

uchar* DLL_EXPORT test0(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU); 
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR); 
    return OriginalImg.data; 
} 

C++代码失败了,你能帮忙吗?


UPDATA http://ppt.cc/h2SI图片是失败,我认为原因是内存。 我修复了c#代码第3个参数3 * 384到2 * 384。 C#运行正常,但画面打破这样http://ppt.cc/IRfd

- UPDATA

Bitmap a = new Bitmap(384, 384, 1 * 384, PixelFormat.Format24bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format24bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, test0()); 

Bitmap a = new Bitmap(384, 384, 2 * 384, PixelFormat.Format32bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format32bppRgb, test0()); 
Bitmap a = new Bitmap(384, 384, 4 * 384, PixelFormat.Format32bppRgb, test0()); 

我尝试六,运行是好的,但图片是休息。

+0

什么样的故障?详细信息,请。 – egrunin 2012-07-23 14:38:32

+0

您需要在此设置不同的图片格式PixelFormat.Format24bppRgb或将图片数据转换为此数据类型描述的格式 – Sam 2012-07-23 14:55:03

回答

0

你检查了imread的成功吗?

Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
if(OriginalImg.empty()) 
    return NULL; 

而在C#(请注意,我写的代码不一定是正确的,但你的想法)

char* imgData = test1; 

if(imgData == Null) 
{ 
// do something smart 
} 

Bitmap a = new Bitmap(384, 384, 3 * 384, PixelFormat.Format24bppRgb, imgData); 
pictureBox0.Image = a; 

这是最常见的错误,你可以在编程做之一 - 最烦人的一个

+0

我确定图片路径正常。 因为test1函数返回右图。 http://ppt.cc/IRfd这样。 上图是右图。 – 2012-07-23 14:51:02

+0

但是我相信你的编程模型是有缺陷的 - 即使它在这种情况下工作。没有它,你永远不会知道它实际上是一个错误的路径或其他东西。 – Sam 2012-07-23 14:52:26

+0

我测试你的想法,并且C++返回不为NULL。 – 2012-07-23 14:58:03

0

另一种选择:有一个C#包装库可以使用,所以你可以直接从托管代码中直接联系DLL。

http://code.google.com/p/opencvdotnet/

+0

thx!但我想要没有任何库的C#客户端! – 2012-07-23 16:36:10

+0

你会考虑使用.NET内置图像功能而不是OpenCV功能吗?我不得不猜测,你在OpenCV中使用了.NET不提供的有价值的东西。 – 2012-07-23 23:31:46

1

你返回一个指向一个已经被释放的局部变量,这将永远是可靠的。

您需要安排Mat对象足够长的时间以便Bitmap构造函数复制其内容。最简单的方法是使用C++/CLI,然后您可以从C++返回.NET位图:

Bitmap^ MyImageProcessor::test0(void) 
{ 
    Mat OriginalImg = imread("c:\\20100812133.jpg", 0); 
    threshold(OriginalImg,OriginalImg,0,255,THRESH_OTSU); 
    cvtColor(OriginalImg,OriginalImg,CV_GRAY2BGR); 
    return gcnew Bitmap(384, 
         384, 
         3 * 384, 
         PixelFormat.Format24bppRgb, 
         IntPtr(OriginalImg.data) 
         ); 
} 
+0

gcnew或新?如果我使用代码,我需要在visual C++中?没有GCC? – 2012-07-23 16:42:10

+0

@wi yu:C++/CLI扩展如'gcnew'只能在Visual C++中使用。但是,您是不是已经在使用Visual Studio,因为部分代码是C#?无论如何,C++/CLI不是必须的,但在Mat对象死亡之前创建'Bitmap'非常重要。 – 2012-07-23 17:47:35