Stack Overflow 社区您好,
我正在使用 C# 中的 OpenCvSharp 开发实时人脸检测应用程序。当前的代码从视频源捕获帧并对其进行处理以检测面部并在其周围绘制边界框。然后,这些处理过的帧将显示在 WPF 图像控件中。
当前的实现感觉优化不够。具体来说,将 Mat 转换为 WPF 显示的 BitmapSource 可能会引入不必要的开销。
这是我的代码的主要部分:
public async Task Main(int selectedItemIndex, Image imageControl, CancellationToken token)
{
Mat frame = new Mat();
await UpdateDisplay(frame, imageControl);
}
private async Task UpdateDisplay(Mat frame, Image imageControl)
{
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
var bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(frame);
var bitmapSource = ConvertToBitmap(bitmap);
imageControl.Source = bitmapSource;
});
}
public static BitmapSource ConvertToBitmap(System.Drawing.Bitmap bitmap)
{
var bitmapData = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
try
{
var bitmapSource = new WriteableBitmap(bitmapData.Width, bitmapData.Height,
bitmap.HorizontalResolution, bitmap.VerticalResolution,
PixelFormats.Bgr24, null);
bitmapSource.Lock();
bitmapSource.WritePixels(new Int32Rect(0, 0, bitmapData.Width, bitmapData.Height),
bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);
bitmapSource.Unlock();
return bitmapSource;
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
我需要帮助的一些事情:
预先感谢您的见解和建议!
我的建议是使用WriteableBitmap,然后从矩阵复制数据。这应该避免任何不必要的分配和数据复制
首先创建与矩阵具有相同大小和类型的像素的可写位图。如果大小或像素格式可以更改,您可能需要在更新之前进行检查。
那就打电话吧
myWriteableBitmap.WritePixels(
new Int32Rect(0, 0, image.Width, image.Height)
frame.Data, // pointer to buffer
frame.AllocatedMemorySize, // buffer size
frame.Width * bytesPerPixel // stride of source, i.e. number of bytes used for each row
);
如果您只处理一种类型的图像或查找表,或者由某些现有方法提供,则每个像素的字节数可以是常量。