将 SoftwareBitmap 转换为 Mat 用于 C#

huangapple go评论67阅读模式
英文:

Convert SoftwareBitmap to Mat for C#

问题

我有一个 SoftwareBitmap 对象,需要使用 openCV 进行处理。我没有找到用于将 SoftwareBitmap 转换为 Mat 的 C# 代码。我尝试使用 C++ 版本,但我在将代码转换时遇到了一些问题。是否有适用于 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#?

答案1

得分: 1

作为可能的解决方案之一 - 您可以将所需的C++编写的库链接到您的C#项目中。

英文:

as one of possible solution - you can link needed C++ written library to your C# project.

答案2

得分: 0

以下是翻译好的部分:

"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)."

经过多个小时的尝试,我找到了解决方案。唯一让我不满意的是它必须在UI线程上执行(如果在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;
}

我在行为中执行这段代码,所以我这样运行它。如果我在线程池中运行代码,就会出现异常。
"应用程序调用了为不同线程进行了封送的接口。"

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

更新
还有一种方法是使用Emgu.CV.Bitmap库将Mat转换为Bitmap对象。

var mat = mat.ToBitmap();

之后,Bitmap可以转换为SoftwareBitmap,或者可以直接在应用程序中使用。Bitmap可以显示在WinUI3的Image控件上。

英文:

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.

huangapple
  • 本文由 发表于 2023年7月3日 21:28:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76605208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定