簡體   English   中英

將opencv圖像cv :: Mat格式轉換為C#BitmapImage

[英]Converting an opencv image cv::Mat Format to a C# BitmapImage

我編寫了此示例代碼來解釋我的問題。 我在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);
}

也許它將對將來偶然發現它的人有所幫助。

看來問題出在共享內存上。
MatBitmapC++中共享內存。 因此,當Mat對象損壞時, Bitmap對象將無法訪問數據。 這就是為什么其數據在C ++方面正確,但在C#方面卻一無所有的原因。
為了解決這個問題,我使用了static Mat 它永遠不會發布,但可以解決我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM