Search code examples
c#opencvemgucvwinui-3

Convert SoftwareBitmap to Mat for C#


I have a SoftwareBitmap object which I need to process using openCV. I haven't found code for C# to convert SoftwareBitmap to Mat. I tried to use C++ version but I don't have much experience in C++ and I had some issues converting the code. Is there version for C#?


Solution

  • After hours of playing with all these stuff. I've come with the solution. The only thing I don't like about it that it must be executed on the UI thread (sorry if it called different in WinUI 3).

    public static Mat ToMat(SoftwareBitmap source)
    {
        var writable = new WriteableBitmap(source.PixelWidth, source.PixelHeight);
        source.CopyToBuffer(writable.PixelBuffer);
    
        var buffer = writable.PixelBuffer;
        using var reader = DataReader.FromBuffer(buffer);
        var bytes = new byte[buffer.Length];
        reader.ReadBytes(bytes);
    
        var mat = new Mat(source.PixelHeight, source.PixelWidth, DepthType.Cv8U, 4);
        mat.SetTo(bytes);
    
        return mat;
    }
    

    I'm executing this code in the behavior so I run it like this. I'm getting an exception if I run the code in a thread from the thread pool. The application called an interface that was marshalled for a different thread.

    this.DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal,
    () => mat =  ToMat(softwareBitmap));
    

    Updated One more way to do it is to use Emgu.CV.Bitmap library to convert Mat into Bitmap object

    var mat = mat.ToBitmap();
    

    After that Bitmap can be converted into SoftwareBitmap or can be used directly in the app. Bitmap can be showed on the WinUI3 Image control.