You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#高版本EmguCV中如何将Mat对象转换为Bitmap

问题原因

新版本EmguCV(4.x及以上版本)将Mat转位图的相关逻辑从核心库拆分到了独立NuGet包中,原有的ToBitmap()方法没有被删除,只是作为扩展方法存在,需要单独安装对应包才能调用。另外你当前的代码存在两个额外问题:

  • 将VideoCapture放在点击事件内用using包裹,方法执行完会立刻释放摄像头资源,仅能获取单帧画面,无法持续输出摄像头流
  • 你使用的是WPF的Image控件,其Source属性接收BitmapSource类型,就算引入ToBitmap()返回WinForm下的Bitmap类型,直接赋值也会报类型不匹配错误
解决步骤

1. 安装依赖

右键项目打开NuGet包管理器,搜索安装Emgu.CV.Bitmap,注意包版本必须和你当前安装的EmguCV核心包版本完全一致,避免出现版本兼容问题。
代码文件顶部引入必要命名空间:

using Emgu.CV;
using System.Windows.Media.Imaging;
using System.Windows.Media;

2. 修正摄像头调用与转换逻辑

不要在点击事件内瞬时创建、释放摄像头对象,将摄像头实例和帧刷新定时器定义为类级别变量,配合Mat转BitmapSource的方法实现画面持续渲染,完整可运行代码如下:

// 类级别变量,避免方法执行完被回收
private VideoCapture _webcamCapture;
private System.Windows.Threading.DispatcherTimer _frameRefreshTimer;

private void OpenWebcam_Click(object sender, RoutedEventArgs e)
{
    // 防止重复初始化摄像头
    if (_webcamCapture != null) return;

    _webcamCapture = new VideoCapture(0); // 传入0代表调用系统默认摄像头,多设备可修改索引
    if (!_webcamCapture.IsOpened)
    {
        MessageBox.Show("摄像头启动失败,请检查设备权限与连接状态");
        _webcamCapture.Dispose();
        _webcamCapture = null;
        return;
    }

    // 定时拉取帧刷新画面,间隔33ms约对应30帧刷新率
    _frameRefreshTimer = new System.Windows.Threading.DispatcherTimer();
    _frameRefreshTimer.Interval = TimeSpan.FromMilliseconds(33);
    _frameRefreshTimer.Tick += (s, args) =>
    {
        using (Mat currentFrame = _webcamCapture.QueryFrame())
        {
            if (currentFrame == null) return;
            image.Source = ConvertMatToBitmapSource(currentFrame);
        }
    };
    _frameRefreshTimer.Start();
}

/// <summary>
/// EmguCV Mat对象转WPF可用的BitmapSource
/// </summary>
private BitmapSource ConvertMatToBitmapSource(Mat mat)
{
    // 统一转换为Bgr24格式,适配WPF像素格式要求,避免颜色错位、花屏
    if (mat.NumberOfChannels == 1)
        CvInvoke.CvtColor(mat, mat, ColorConversion.Gray2Bgr);
    else if (mat.NumberOfChannels == 4)
        CvInvoke.CvtColor(mat, mat, ColorConversion.Bgra2Bgr);

    return BitmapSource.Create(
        pixelWidth: mat.Width,
        pixelHeight: mat.Height,
        dpiX: 96,
        dpiY: 96,
        pixelFormat: PixelFormats.Bgr24,
        palette: null,
        buffer: mat.DataPointer,
        bufferSize: mat.Stride * mat.Height,
        stride: mat.Stride);
}

// 窗口关闭时释放资源,避免摄像头被进程长期占用
protected override void OnClosed(EventArgs e)
{
    _frameRefreshTimer?.Stop();
    _webcamCapture?.Stop();
    _webcamCapture?.Dispose();
    base.OnClosed(e);
}
补充说明
  • 如果你是WinForm开发,只需要拿到System.Drawing.Bitmap类型,安装完Emgu.CV.Bitmap包、引入Emgu.CV命名空间后,就可以直接调用mat.ToBitmap()扩展方法,不会再出现找不到方法的报错
  • 帧刷新间隔可以根据需求调整,设置为16ms约对应60帧刷新率,对性能要求不高的场景设置为50ms(20帧)也可满足基础预览需求
  • 摄像头读取、帧渲染建议放在UI线程调度,避免跨线程调用控件的权限报错

内容的提问来源于stack exchange,提问作者Dotnet_Developer10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 18:09:22