【问题标题】:C++ DLL return Mat to C#C++ DLL 将 Mat 返回到 C#
【发布时间】:2012-07-23 14:37:02
【问题描述】:

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

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

代码没问题,但我想阅读灰色的图片。 我会做一些图像处理(例如: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++代码失败,能帮忙吗?


更新数据 http://ppt.cc/h2SI图片失败,我认为原因是记忆。 我将 c# 代码将第三个参数 3*384 修复为 2*384。 C# 运行正常,但图片像这样中断http://ppt.cc/IRfd

-- 更新数据

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

我试了六次,跑起来还行,但是画面坏了。

【问题讨论】:

  • 什么样的失败?请详细说明。
  • 您需要在此处设置不同的图片格式PixelFormat.Format24bppRgb或将您的图片数据转换为该数据类型所描述的格式

标签: c# c++ opencv


【解决方案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)
                       );
}

【讨论】:

  • gcnew 还是新的?如果我使用代码,我需要在 Visual C++ 中使用吗?没有 GCC?
  • @wi yu:gcnew 等 C++/CLI 扩展仅在 Visual C++ 中可用。但是您不是已经在使用 Visual Studio,因为部分代码是 C# 吗?无论如何,C++/CLI 不是必需的,但在 Mat 对象死亡之前创建 Bitmap 很重要。
【解决方案2】:

你检查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;

这是您在编程中最常犯的错误之一,也是最烦人的错误之一

【讨论】:

  • 我确定图片路径没问题。因为 test1 函数返回正确的图片。 ppt.cc/IRfd 像这样。上图为右图。
  • 但是我确信你的编程模型是有缺陷的——即使它在这种情况下有效。没有它,你永远不会知道它实际上是一条错误的道路还是别的什么。
  • 我测试你的想法,c++返回不为NULL。
  • 我将您的想法添加到代码中,谢谢!以及如何修复我的代码,我想正确显示图片!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2018-11-07
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多