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. Shadow DOM 及 Custom Elements

    今天发现 shadow DOM 和 自定义元素,这两个东西和 molecule 简直是同出而异名. 我得好好推敲一下,如果 shadow dom 确实能达到目的且新款浏览器都支持,molecule 就 ...

  2. ASP.NET Core EventStream (SSE) 使用以及 WebSocket 比较

    在开发环境中,对于实时数据流的需求非常常见,最常用的技术包括 Server-Sent Events (SSE) 和 WebSocket. 什么是 Server-Sent Events (SSE)? S ...

  3. Android7以上https抓包

    1. 问题描述 1.1 运行环境 1.2 问题描述 virtualXposed 不一定支持Android模拟器 无法抓包 https 请求 1.3 问题原因 Android7 以后,系统分了系统证书和 ...

  4. sed 指定行后或行前插入

    sed 功能非常强大,这里主要列出一些工作中常用到的举例,以后再追加 示例文本 example.cfg Config = { a = 1, b = 1024, c = { ErrLevel = 4, ...

  5. resttemplate的ReadTimeout和ConnectTimeout

    问题描述:今天,在做微服务开发中,A服务区调用B服务,获取数据做导出excel操作.A服务出现了"java.net.SocketTimeoutException: Read timed ou ...

  6. Qt/C++音视频开发72-倍速推流/音视频同步倍速推流/不改变帧率和采样率/低倍速和高倍速

    一.前言 最近多了个新需求,需要倍速推流,推流界的扛把子obs也有倍速推流功能,最高支持到两倍速.这里所说的倍速,当然只限定在文件,只有文件才可能有倍速功能,因为也只有文件才能倍速解码播放.实时视频流 ...

  7. 得物自研客服IM中收发聊天消息背后的技术逻辑和思考实现

    本文由得物技术WWQ分享,原题"客服发送一条消息背后的技术和思",本文有修订和改动. 1.引言 在企业IM客服场景中,客服发送一条消息的背后,需要考虑网络通信.前端展示.后端存储以 ...

  8. IM扫码登录技术专题(三):通俗易懂,IM扫码登录功能详细原理一篇就够

    本文引用了作者"大古同学"的"二维码扫码登录是什么原理"一文的主要内容,为了更好的理解和阅读,即时通讯网收录时有修订和改动,感谢原作者的分享. 1.引言 自从微 ...

  9. ArrayList源码解析-JDK18

    引言 ArrayList在JDK1.7和1.8中的差距并不大,主要差距以下几个方面: JDK1.7 在JDK1.7中,使用ArrayList list = new ArrayList()创建List集 ...

  10. 隐私集合求交(PSI)-两方

    在知乎上看到大佬写的关于论文:Efficient Batched Oblivious PRF with Applications to Private Set Intersection的讲解,循序渐进 ...