1、winform 应用程序,两个picturebox空间,一个用于视频呈现,一个用于抓拍呈现。

2、引用包OpenCvSharp4、OpenCvSharp4.Extensions、OpenCvSharp4.runtime.win等。

    public partial class Form2 : Form
{
// 修改成员变量
private volatile Bitmap _latestFrameBitmap;
private readonly object _bitmapLock = new object();
private VideoCapture _capture;
private CancellationTokenSource _cts; public Form2()
{
InitializeComponent();
} private async void Form2_Load(object sender, EventArgs e)
{
_capture = new VideoCapture(0);
if (!_capture.IsOpened())
{
MessageBox.Show("无法打开摄像头!");
return;
} _cts = new CancellationTokenSource();
try
{
await StartCapturingAsync(_cts.Token);
}
catch (OperationCanceledException)
{
// 正常取消
}
catch (Exception ex)
{
MessageBox.Show($"捕获出错: {ex.Message}");
}
} private async Task StartCapturingAsync(CancellationToken token)
{
using (var frame = new Mat())
{
while (!token.IsCancellationRequested)
{
_capture.Read(frame);
if (frame.Empty()) continue; var newBitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(frame); // 更新最新帧
lock (_bitmapLock)
{
var old = _latestFrameBitmap;
_latestFrameBitmap = newBitmap;
old?.Dispose();
} await UpdateCameraPreviewAsync(newBitmap);
await Task.Delay(30, token);
}
}
} private async Task UpdateCameraPreviewAsync(Bitmap bitmap)
{
if (picCamera.IsDisposed)
{
bitmap.Dispose();
return;
} try
{
if (picCamera.InvokeRequired)
{
picCamera.BeginInvoke(new Action(() => UpdateCamera(bitmap)));
}
else
{
UpdateCamera(bitmap);
}
}
catch (ObjectDisposedException)
{
bitmap.Dispose();
}
} private void UpdateCamera(Bitmap newBitmap)
{
if (picCamera.IsDisposed)
{
newBitmap.Dispose();
return;
} var old = picCamera.Image;
picCamera.Image = newBitmap;
old?.Dispose();
} // 优化后的抓拍方法
private async void catchBtn_Click(object sender, EventArgs e)
{
try
{
Bitmap snapshot = null; // 安全获取当前帧
lock (_bitmapLock)
{
if (_latestFrameBitmap != null)
{
snapshot = (Bitmap)_latestFrameBitmap.Clone();
}
} if (snapshot == null)
{
MessageBox.Show("当前没有可用的视频帧");
return;
} // 异步保存防止界面卡顿
await Task.Run(() => SaveSnapshot(snapshot));
}
catch (Exception ex)
{
MessageBox.Show($"抓拍失败: {ex.Message}");
}
} private void SaveSnapshot(Bitmap bitmap)
{
try
{
var fileName = GenerateUniqueFileName();
using (bitmap) // 确保释放资源
{
bitmap.Save(fileName, ImageFormat.Jpeg); // 显示预览(需要克隆新实例)
var previewBitmap = (Bitmap)bitmap.Clone(); BeginInvoke(new Action(() =>
{
UpdateSnapshotPreview(previewBitmap);
MessageBox.Show($"图片已保存到:\n{fileName}");
}));
}
}
catch (Exception ex)
{
BeginInvoke(new Action(() =>
{
MessageBox.Show($"保存失败: {ex.Message}");
}));
}
} // 新增预览更新方法
private void UpdateSnapshotPreview(Bitmap newBitmap)
{
if (pictureBoxSnapshot.IsDisposed)
{
newBitmap.Dispose();
return;
} // 处理跨线程访问
if (pictureBoxSnapshot.InvokeRequired)
{
pictureBoxSnapshot.BeginInvoke(new Action(() => UpdateSnapshotPreview(newBitmap)));
return;
} // 更新控件并释放旧资源
var old = pictureBoxSnapshot.Image;
pictureBoxSnapshot.Image = newBitmap;
old?.Dispose();
} private string GenerateUniqueFileName()
{
var docs = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmssfff");
return Path.Combine(docs, $"Snapshot_{timestamp}.jpg");
} private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
_cts?.Cancel();
_cts?.Dispose(); // 释放所有资源
_capture?.Dispose();
lock (_bitmapLock)
{
_latestFrameBitmap?.Dispose();
} // 清理预览图
if (picCamera.Image != null)
{
var img = picCamera.Image;
picCamera.Image = null;
img.Dispose();
} // 新增快照预览清理
if (pictureBoxSnapshot.Image != null)
{
var img = pictureBoxSnapshot.Image;
pictureBoxSnapshot.Image = null;
img.Dispose();
}
}
}

C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。的更多相关文章

  1. 利用opencv从USB摄像头获取图片

    由于opencv自带的VideoCapture函数直接从usb摄像头获取视频数据,所以用这个来作为实时的图像来源用于实体检测识别是很方便的. 1. 安装opencv 安装的步骤可以按照之前这个文章操作 ...

  2. python opencv 读取USB摄像头的像素问题

    问题描述 每次调用capture读取video的时候,还回的像素都是640x480,不管是笔记本的摄像头还是USB摄像头,明明我的摄像头是支持130万读取的功能的呀. 问题分析 一番查找,关于用ope ...

  3. 使用openCV打开USB摄像头(UVC 小米micro接口)

    之前在AndroidStudio上就用了别人用写的库成功地打开了USB摄像头. 于是我之后又在PC上尝试了一下,首先去淘宝买了个MICRO母转USB公的转接口,然后在Qt上配置了一下OPENCV后开始 ...

  4. C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流

    https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118 ...

  5. 使用摄像头或视频运行 ORB-SLAM2 SLAM14讲 第一次课后作业

    参考:视觉SLAM十四讲(第一章作业) 深蓝上高博的第一讲课后题: 题目:6 * 使用摄像头或视频运行 ORB-SLAM2(3 分,约 1 小时)请注意本题为附加题.了解⼀样东西最快的⽅式是⾃⼰上⼿使 ...

  6. USB摄像头无法正常读取问题

    opencv读取摄像头或者视频一种是早期版本的IplImage结构体,图片就存在结构体指针IplImage*中,另一种是Mat类,两者在操作上略有差异,且opencv2都兼容这两个版本,前面的博客也说 ...

  7. DIY远程移动图像监测(tiny6410+USB摄像头+motion+yeelink+curl)

    看到有博客上采用motion搭建移动图像监测系统,感觉很强大,但大多缺少远程监测能力,大多局限于局域网.OK,笔者手头刚好有一个30W像素的USB摄像头,那么借用yeelink服务,也来DIY一把,哈 ...

  8. 荣品四核4412开发板的USB摄像头问题

    RP4412开发板是荣品电子研发的一款三星四核Exynos4412评估板开发板,支持WIFI+LAN上网.蓝牙4.0.4G上网.500万自动对焦摄像头.GPS.网卡.音频,1080P HDMI音视频同 ...

  9. Linux USB摄像头驱动【转】

    本文转载自:http://www.itdadao.com/articles/c15a509940p0.html 在 cortex-a8 中,可接入摄像头的接口通常可以分为两种, CAMERA 接口和 ...

  10. javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

随机推荐

  1. 【Spring】Sring基础概念(黑马SSM学习笔记)

    目录 Spring简介 Spring是什么 Spring发展 Spring优势 Spring体系结构 Spring快速入门 Spring程序开发步骤 不用Spring的一般步骤 使用Spring框架 ...

  2. Qt音视频开发46-视频传输UDP版

    一.前言 上篇文章写道采用的TCP传输视频,优缺点很明显,优点就是不丢包,缺点就是速度慢,后面换成UDP通信,速度快了很多,少了3次握手,而且在局域网中基本上不丢包,就算偶尔丢包,对于一秒钟25-30 ...

  3. Qt音视频开发20-海康sdk本地播放

    一.前言 海康sdk中包含了MP4解码播放库,对应的API函数都是PlayM4开头的,顾名思义播放MP4,海康的视频默认可以保存成MP4文件,可以用通用的播放器来播放,这就是为啥前面好多篇文章讲到的各 ...

  4. [转]VS2019+CUDA11.1 没有CUDA出现

    1.VS2019+CUDA11.1 没有CUDA出现 2.VS+CUDA 新建项目里没有CUDA选项(附详细图文步骤) 3.No Cuda 10.1 runtime Template in Visua ...

  5. 优化博客Ⅰ-压缩图片为webp格式

    自动压缩博客图片为webp格式 作为自己的个人博客,我非常喜欢搞一些花里胡哨的东西,其中就包括不少精美图片,但是过多的图片会占用大量的网络资源导致博客加载速度变慢. 那怎么办呢? 第一个想到的就是升级 ...

  6. python SQLAlchemy ORM——从零开始学习 02简单的增删查改

    02 简单的增删查改 前情提要:承接了01中的engine以及User类 2-1 了解会话机制 个人理解 在SQLAlchemy 增删查改中是依赖会话(Session)这个机制进行操作的,我个人的理解 ...

  7. React基础笔记2

    一.生命周期函数 挂载卸载过程 constructor        props context componentWillMount  服务器与客户端 componentDidMount  ajax ...

  8. c# 微软小冰-虚拟女友聊天

    using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System ...

  9. 第八章 (Nginx+Lua)流量复制/AB测试/协程

    流量复制 在实际开发中经常涉及到项目的升级,而该升级不能简单的上线就完事了,需要验证该升级是否兼容老的上线,因此可能需要并行运行两个项目一段时间进行数据比对和校验,待没问题后再进行上线.这其实就需要进 ...

  10. 一个基于 Roslyn 和 AvalonEdit 的跨平台 C# 编辑器

    前言 今天大姚给大家分享一个基于 Roslyn 和 AvalonEdit 开源.轻量.跨平台的 C# 编辑器:RoslynPad. Roslyn介绍 Roslyn是一个强大的.NET编译器实现,为C# ...