C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。
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呈现,抓拍图像保存呈现。没有注释版本。的更多相关文章
- 利用opencv从USB摄像头获取图片
由于opencv自带的VideoCapture函数直接从usb摄像头获取视频数据,所以用这个来作为实时的图像来源用于实体检测识别是很方便的. 1. 安装opencv 安装的步骤可以按照之前这个文章操作 ...
- python opencv 读取USB摄像头的像素问题
问题描述 每次调用capture读取video的时候,还回的像素都是640x480,不管是笔记本的摄像头还是USB摄像头,明明我的摄像头是支持130万读取的功能的呀. 问题分析 一番查找,关于用ope ...
- 使用openCV打开USB摄像头(UVC 小米micro接口)
之前在AndroidStudio上就用了别人用写的库成功地打开了USB摄像头. 于是我之后又在PC上尝试了一下,首先去淘宝买了个MICRO母转USB公的转接口,然后在Qt上配置了一下OPENCV后开始 ...
- C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流
https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118 ...
- 使用摄像头或视频运行 ORB-SLAM2 SLAM14讲 第一次课后作业
参考:视觉SLAM十四讲(第一章作业) 深蓝上高博的第一讲课后题: 题目:6 * 使用摄像头或视频运行 ORB-SLAM2(3 分,约 1 小时)请注意本题为附加题.了解⼀样东西最快的⽅式是⾃⼰上⼿使 ...
- USB摄像头无法正常读取问题
opencv读取摄像头或者视频一种是早期版本的IplImage结构体,图片就存在结构体指针IplImage*中,另一种是Mat类,两者在操作上略有差异,且opencv2都兼容这两个版本,前面的博客也说 ...
- DIY远程移动图像监测(tiny6410+USB摄像头+motion+yeelink+curl)
看到有博客上采用motion搭建移动图像监测系统,感觉很强大,但大多缺少远程监测能力,大多局限于局域网.OK,笔者手头刚好有一个30W像素的USB摄像头,那么借用yeelink服务,也来DIY一把,哈 ...
- 荣品四核4412开发板的USB摄像头问题
RP4412开发板是荣品电子研发的一款三星四核Exynos4412评估板开发板,支持WIFI+LAN上网.蓝牙4.0.4G上网.500万自动对焦摄像头.GPS.网卡.音频,1080P HDMI音视频同 ...
- Linux USB摄像头驱动【转】
本文转载自:http://www.itdadao.com/articles/c15a509940p0.html 在 cortex-a8 中,可接入摄像头的接口通常可以分为两种, CAMERA 接口和 ...
- javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
随机推荐
- CMake构建学习笔记19-OpenSSL库的构建
1. 概述 OpenSSL是一个开源的加密工具包和库,主要实现了安全套接字层(SSL)和传输层安全(TLS)协议,以及各种加密算法.数字签名.消息摘要.加密证书等功能.这个库可以说是Web开发尤其是H ...
- 【数据库】MongoDB服务启动失败的问题。
1.确保MongoDB所在文件夹拥有所有权限 2.确保打开CMD窗口是以管理员身份运行的 3.配置文件中的路径应该为完整路径,且不包含空格和特殊字符(不建议包含) systemLog: destina ...
- 如何使用特定的SSH Key提交GIT
问题提出 最近在自己的MAC上面提交Github代码的时候发现居然失败了: $ git push origin master Permission denied (publickey). fatal: ...
- 如何在众多Ubuntu版本中挑选出最适配自身需求的系统版本?用德承工控机GM-1100来深度剖析其中的门道
Ubuntu是一款基于Debian GNU/Linux,支持x86.amd64(x64)和ppc架构,以桌面应用为主的Linux操作系统.其名称来自非洲南部的语言"ubuntu"( ...
- [转]Windows10下CLion配置说明
Windows10下CLion配置说明CLion 是 C/C++的 IDE,可以配置多种编译环境,本文以配置MinGW编译环境为例. 安装CLion 的安装可直接到官网下载 ZIP,文件解压后直接运行 ...
- 开源即时通讯IM框架MobileIMSDK的Uniapp端开发快速入门
► 相关链接: ①MobileIMSDK-Uniapp端的详细介绍 ② MobileIMSDK-Uniapp端的开发手册new(* 精编PDF版) 一.理论知识准备 您需要对Uniapp和Vue开发有 ...
- AI实战营第二期 | 环境配置及安装
AI实战营第二期 | 环境配置及安装 强烈推荐使用 mim 来管理 OpenMMLab repo OpenMMLab repo 不要 mim 和 pip 混用 OpenMMLab 1.0 和 Open ...
- 【狂神说Java】Java零基础学习笔记-Java流程控制
[狂神说Java]Java零基础学习笔记-Java流程控制 Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入.ja ...
- [LC593]有效的正方形-Valid Square
题目描述 给定2D空间中四个点的坐标 p1, p2, p3 和 p4,如果这四个点构成一个正方形,则返回 true . 点的坐标 pi 表示为 [xi, yi] .输入 不是 按任何顺序给出的. 一个 ...
- C#+ WPF 实现蓝牙转WIFI计步上位机
前言 一个WIFI上位机,接收底层MPU6050数据,途中转蓝牙从机透传,到蓝牙主机直连WIFI,PC端UDP通信,实现三轴加速度数据传送和计步功能. 项目介绍 本项目基于.NET平台,使用WPF开发 ...