c# - 将 opencv 图像 cv::Mat 格式转换为 C# BitmapImage

标签 c# c++ opencv bitmap

我写了这个示例代码来解释我的问题。我在 VS 2013 中有一个解决方案,包含一个 C# 项目和一个 C++ 项目。我尝试在 C++ (x86) 中使用 OpenCV 读取图像。并希望将 C# x86 项目(使用 CLR 模式)传递给位图对象,然后传递给 BitmapImage 对象以用作 WPF ImageSource。
我的 C++ 代码:

Bitmap^ SomeClass::Test(System::String^ imgFileName)
{
    auto fileName = msclr::interop::marshal_as<string>(imgFileName);
    Mat img = imread(fileName);
    //Do something
    auto bmp = gcnew Bitmap(img.cols, img.rows, img.step, Imaging::PixelFormat::Format24bppRgb, (IntPtr)img.data);
    bmp->Save("InC++Side.png");     
    return bmp;
}

我的 C# 代码:

private void ImageTester(object sender, RoutedEventArgs e)
{
    var image = testClass.Test("test.png");
    image.Save("InC#Side.png");
    bg.Source = ConvertToBitmapImageFromBitmap(image);
}
public static BitmapImage ConvertToBitmapImageFromBitmap(Bitmap image)
{
    using(var ms = new MemoryStream())
    {
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        BitmapImage bImg = new BitmapImage();
        bImg.BeginInit();
        bImg.StreamSource = new MemoryStream(ms.ToArray());
        bImg.EndInit();
        return bImg;
    }
}

问题是C++保存的文件(InC++Side.png)是完美的;但另一个在 C# 中显示的位图对象只是一个带有该图像高度和宽度的灰色矩形。
问题出在哪里?
如何将图像传递到我的 C# 项目?

最佳答案

我现在看到这是一个很老的问题,但我刚刚遇到了类似的任务。我认为与其让非托管资源保持事件状态并在托管代码中使用它,不如将数据复制到托管堆并让 CLR 处理它。这是我的方法:

System::Windows::Media::ImageSource^ ManagedCppClass::GetLatestImage()
{
    cv::Mat frame;
    if (!videoSrc->read(frame))
        return nullptr;

    int totSize = frame.total() * frame.elemSize();
    auto managedArray = gcnew array<System::Byte>(totSize);
    System::Runtime::InteropServices::Marshal::Copy(System::IntPtr((void*)frame.data), 
                                                    managedArray, 0, totSize); //assume isContinuous is always true at this point (?)

    return System::Windows::Media::Imaging::BitmapImage::Create(
                frame.cols, frame.rows, 96, 96, System::Windows::Media::PixelFormats::Bgr24, //Rgb24,
                System::Windows::Media::Imaging::BitmapPalettes::WebPalette, managedArray, frame.step);
}

也许它会对将来偶然发现它的人有所帮助。

关于c# - 将 opencv 图像 cv::Mat 格式转换为 C# BitmapImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31515964/

相关文章:

c# - Asp.net MVC3 C#,StreamWriter 错误

c# - 使用任务返回值时出现 InvalidCastException

c++ - C++20 中是否有assign_or_inserter/insert_or_assigner?

OpenCV显示视频无遗漏无撕裂

c++ - 当画面中没有人脸时,OpenCV 中的人脸检测器变慢

c# - 在机器范围内以编程方式设置环境变量并发送设置更改消息

c# - 来自 IHttpClientFactory 的类型化 HttpClient 实例的生命周期是多长,其中将接收它的类型注册为 "AddScoped"?

c++ - SQLite 在插入项目时崩溃

c++ - 使用 cuBlas 将矩阵与其转置相乘

python - 张开嘴需要Haar Casscade xml