C#(Winform)通过添加AForge添加并使用系统摄像机
先展示效果
AForge介绍
AForge是一个专门为开发者和研究者基于C#框架设计的, 也是NET平台下的开源计算机视觉和人工智能库
它提供了许多常用的图像处理和视频处理算法、机器学习和神经网络模型,并且具有高效、易用、稳定等特点。
AForge主要包括:
计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等
- AForge.Imaging ——日常的图像处理和过滤器
- AForge.Vision —— 计算机视觉应用类库
- AForge.Neuro —— 神经网络计算库AForge.Genetic -进化算法编程库
- AForge. MachineLearning —— 机械学习类库
- AForge. Robotics —— 提供一些机器学习的工具类库
- AForge.Video —— 一系列的视频处理类库
- AForge.Fuzzy —— 模糊推理系统类库
- AForge.Controls —— 图像, 三维, 图表显示控件
AForge的使用方向
1. 基于符号识别的3D显示增强技术
2. 基于模糊系统的自动导航
3. 运动检测
4. 2D增强技术
5. 计算机视觉与人工智能
6. 模拟识别
7. 神经网络
8. 图像处理
9. 遗传算法
10. 机器学习
11. 机器人控制等等
AForge的安装方法
1.右键项目名
2.打开 "管理 NuGet程序包"

3.点击浏览 在浏览上输入 "AForge",并下载
注意:作者一般都是 aforge.net

4.全部下载之后,他会在你的winfrom的左边框会自动显示

一、下面是我做的一个相机拍摄小项目

1.我们先把页面搭好, 上面的字都是lable弄的不是textbox
控件: label button comboBox picture timer VideoSourcePlayer
注意: VideoSourcePlayer 是 我们下载的那个控件里的(AForge.NET)

2. 拉一个label , 右下角属性
label 的 属性
- Auto ==>False
- BorderStyle ==> Fixed3D
- TextAlign==>MiddleCenter
- ForeColor==>Red
- BackGround==>Black
3.最上面时间的显示
注意:这里是timer的控件一个点击事件
timer的Enable 属性 修改成 True
#region 显示实时时间private void timer1_Tick(object sender, EventArgs e){DateTime dt=DateTime.Now;this.txtYear.Text = dt.Year.ToString();this.txtMonth.Text = dt.Month.ToString();this.txtDay.Text = dt.Day.ToString();this.txtTime.Text=dt.ToLongTimeString();string week = "";switch(dt.DayOfWeek){case DayOfWeek.Sunday:week = "日";break;case DayOfWeek.Monday:week = "一";break;case DayOfWeek.Tuesday:week = "二";break;case DayOfWeek.Wednesday:week = "三";break;case DayOfWeek.Thursday:week = "四";break;case DayOfWeek.Friday:week = "五";break;case DayOfWeek.Saturday:week = "六";break;default:break;}this.txtWeek.Text = week;}#endregion
4.我们要把最基本的 给完善了,把该定义的全部完成,窗体加载我们要提前实例化相机
private FilterInfoCollection filterInfoCollection; //摄像头设备集合private VideoCaptureDevice videoCapture;//捕捉设备源private Bitmap image=null; //设置图片接收的int Isopen = 0; private void Form1_Load(object sender, EventArgs e){filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);//MessageBox.Show($"检测到了{filterInfoCollection.Count.ToString()}个摄像头");//这下面的for循环是为了检测电脑连接几个相机 ,来吧相机数量写在combobox控件下for(int i = 0; i < filterInfoCollection.Count; i++){comboBox1.Items.Add($"摄像头{i}");}}
5.下拉框(ComboBox)索引选择改变
CloseCamera(); //这个先提前关闭相机, 下面有介绍if (comboBox1.SelectedIndex == 0 && filterInfoCollection.Count > 0){videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);}else if (comboBox1.SelectedIndex == 1 && filterInfoCollection.Count > 1){videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);}else{MessageBox.Show("摄像头选择有误", "错误提示");return;}videoSourcePlayer1.VideoSource=videoCapture;videoSourcePlayer1.Start();
二、简化封装:相机关闭,相机连接(实时显示),保存图片
1.连接相机
#region 连接相机private void ConnCamera(){if(filterInfoCollection.Count>0){ videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);videoSourcePlayer1.VideoSource= videoCapture;videoSourcePlayer1.Start();}}#endregion
2.关闭相机
#region 关闭相机private void CloseCamera(){if(videoSourcePlayer1.VideoSource!=null){videoSourcePlayer1.SignalToStop();videoSourcePlayer1.VideoSource.Stop();videoSourcePlayer1.VideoSource = null;}}#endregion
3.保存图片
#region 保存图片private void SaveImage(){var date = DateTime.Now.ToString("yyyy-MM-dd");date += "-" + DateTime.Now.TimeOfDay.ToString("hhmmss");if(!Directory.Exists("D:\\Saved_Pictures")){Directory.CreateDirectory("D:\\Saved_Pictures");}image.Save(string.Format("D:\\Saved_Pictures\\" + date + ".jpg", date), System.Drawing.Imaging.ImageFormat.Png);}#endregion
三、实现相机拍照,相机实时显示(打开),图片保存功能,窗体关闭
1.打开相机(实时显示)
private void takeCamera_Click(object sender, EventArgs e){if(((uint)filterInfoCollection.Count)==0){MessageBox.Show("检测不到你的摄像头", "错误提示");}else{Isopen++;if(Isopen%2!=0){takeCamera.Text = "关闭摄像头";ConnCamera();}else if(Isopen%2==0){takeCamera.Text = "打开摄像头";CloseCamera();}}}
2.相机拍照
private void takephoto_Click(object sender, EventArgs e){image=videoSourcePlayer1.GetCurrentVideoFrame();pictureBox1.SizeMode=PictureBoxSizeMode.Zoom;pictureBox1.Image= image;}
3.图片保存
private void SavePicture_Click(object sender, EventArgs e){if(pictureBox1.Image!=null){SaveImage();}else{MessageBox.Show("请先进行拍照", "相机拍照");}}
4.窗体关闭
private void Form1_FormClosing(object sender, FormClosingEventArgs e){if(MessageBox.Show("将要关闭窗口,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes){e.Cancel=false;CloseCamera();Application.Exit();}else{e.Cancel = true;}}
}
补充: 窗体的关闭方法;窗体跳转文件夹
1.关闭窗体的多种方法
1. this.Close() ;
只是关闭当前窗口,如果不是主窗体的话,它后台还会再运行,是无法推出主程序的。
2.Application.Exit();
强制所有消息中止,退出所有的窗口,但是有托管线程,也无法干净退出
3.Applicat.ExitThread();
强制中止调用线程上的所有消息,同样面临其他线程无法正确退出问题
4.System.Environment.Exit(0);
这是彻底的强制退出,能把程序结束很干净
2.跳转功能
由于一般程序保存图片后都会有个跳转功能,这个我感觉保存后跳转,他就不是一个功能了,这里给大家写一下怎么去跳转。
System.Diagnostics.Process.Start("D:\\Saved_Pictures");
注意: 括号里面是路径
四、完结:代码展示和结果
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Video.DirectShow;namespace Camera
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private FilterInfoCollection filterInfoCollection; //摄像头设备集合private VideoCaptureDevice videoCapture;//捕捉设备源private Bitmap image=null;int Isopen = 0;#region 显示实时时间private void timer1_Tick(object sender, EventArgs e){DateTime dt=DateTime.Now;this.txtYear.Text = dt.Year.ToString();this.txtMonth.Text = dt.Month.ToString();this.txtDay.Text = dt.Day.ToString();this.txtTime.Text=dt.ToLongTimeString();string week = "";switch(dt.DayOfWeek){case DayOfWeek.Sunday:week = "日";break;case DayOfWeek.Monday:week = "一";break;case DayOfWeek.Tuesday:week = "二";break;case DayOfWeek.Wednesday:week = "三";break;case DayOfWeek.Thursday:week = "四";break;case DayOfWeek.Friday:week = "五";break;case DayOfWeek.Saturday:week = "六";break;default:break;}this.txtWeek.Text = week;}#endregionprivate void Form1_Load(object sender, EventArgs e){filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);//MessageBox.Show($"检测到了{filterInfoCollection.Count.ToString()}个摄像头");for(int i = 0; i < filterInfoCollection.Count; i++){comboBox1.Items.Add($"摄像头{i}");}System.Diagnostics.Process.Start("D:\\Saved_Pictures");}private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){CloseCamera();if (comboBox1.SelectedIndex == 0 && filterInfoCollection.Count > 0){videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);}else if (comboBox1.SelectedIndex == 1 && filterInfoCollection.Count > 1){videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);}else{MessageBox.Show("摄像头选择有误", "错误提示");return;}videoSourcePlayer1.VideoSource=videoCapture;videoSourcePlayer1.Start();}#region 关闭相机private void CloseCamera(){if(videoSourcePlayer1.VideoSource!=null){videoSourcePlayer1.SignalToStop();videoSourcePlayer1.VideoSource.Stop();videoSourcePlayer1.VideoSource = null;}}#endregion#region 连接相机private void ConnCamera(){if(filterInfoCollection.Count>0){ videoCapture = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);videoSourcePlayer1.VideoSource= videoCapture;videoSourcePlayer1.Start();}}#endregion#region 保存图片private void SaveImage(){var date = DateTime.Now.ToString("yyyy-MM-dd");date += "-" + DateTime.Now.TimeOfDay.ToString("hhmmss");if(!Directory.Exists("D:\\Saved_Pictures")){Directory.CreateDirectory("D:\\Saved_Pictures");}image.Save(string.Format("D:\\Saved_Pictures\\" + date + ".jpg", date), System.Drawing.Imaging.ImageFormat.Png);}#endregionprivate void takeCamera_Click(object sender, EventArgs e){if(((uint)filterInfoCollection.Count)==0){MessageBox.Show("检测不到你的摄像头", "错误提示");}else{Isopen++;if(Isopen%2!=0){takeCamera.Text = "关闭摄像头";ConnCamera();}else if(Isopen%2==0){takeCamera.Text = "打开摄像头";CloseCamera();}}}private void takephoto_Click(object sender, EventArgs e){image=videoSourcePlayer1.GetCurrentVideoFrame();pictureBox1.SizeMode=PictureBoxSizeMode.Zoom;pictureBox1.Image= image;}private void SavePicture_Click(object sender, EventArgs e){if(pictureBox1.Image!=null){SaveImage();}else{MessageBox.Show("请先进行拍照", "相机拍照");}}private void Form1_FormClosing(object sender, FormClosingEventArgs e){if(MessageBox.Show("将要关闭窗口,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes){e.Cancel=false;CloseCamera();Application.Exit();}else{e.Cancel = true;}}}
}
相关文章:
C#(Winform)通过添加AForge添加并使用系统摄像机
先展示效果 AForge介绍 AForge是一个专门为开发者和研究者基于C#框架设计的, 也是NET平台下的开源计算机视觉和人工智能库 它提供了许多常用的图像处理和视频处理算法、机器学习和神经网络模型,并且具有高效、易用、稳定等特点。 AForge主要包括: 计算机视觉与人…...
AI使用场景简单测试
前言 今天来分享下AI的2个实用场景,我这里是使用的博主:小虚竹,搭建的AI服务,用的ChatGPT 4O模型,主要是试了3个场景,服装设计、直播带货话术、检验报告分析。 一、服装设计 对于最后需要的裁片设计上的尺寸…...
Linux 配置 MySQL 定时自动备份到另一台服务器
Linux 配置 MySQL 定时自动备份到另一台服务器 前言1、配置服务器通信1.1:配置过程 2、编写自动备份sh脚本文件3:设置定时自动执行 前言 此方案可使一台服务器上的 MySQL 中的所有数据库每天 0 点自动转储为 .sql 文件,然后将文件同步到另一…...
PostgreSQL 备库的延迟问题
目录标题 1. 查看主备状态计算方式:实际情况:举个例子: 2. 查看历史状态3. 分析日志文件4. 查看数据库层面的复制状态5. 检查活动事务6. 检查系统资源7. 检查网络状况8. 检查复制槽状态9. 检查未提交的两阶段事务 要排查 PostgreSQL 备库的延…...
力扣-二叉树-226 翻转二叉树
思路 利用递归的思路 代码 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr){return root;}swap( root->right, root->left);invertTree(root->left);invertTree(root->right);return root;} };...
基于SpringBoot的在线车辆租赁信息管理系统
系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的不断发展和人们生活水平的提高,汽车租赁行业迎来了前所未有的发展机遇。传统的汽车租赁方式往往存在流程繁琐、信息不透明等问题,难以满足现代消费者对于便捷、高效服务的需求。因此&…...
掌握 systemd:Linux 服务管理的核心工具
1. 什么是 systemd? 定义:systemd 是 Linux 系统的初始化系统(init system)和服务管理器,用于替代传统的 SysVinit。核心目标: 加速系统启动(并行化任务)。统一管理服务、日志、挂载…...
【信息系统项目管理师-案例真题】2019下半年案例分析答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题 1】(6 分)【问题 2 】(8 分)【问题 3 】(11 分)试题二【问题 1】(5分)【问题 2】 (14 分)【问题 3 】(6 分)试题三【问题 1】(8 分)【问题 2 】(6 分)【问题 3】 (8 分)【问题 4 …...
C/C++程序的内存是如何开辟的?
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴…...
日志结构化处理:PO对象toString日志转JSON工具
日志结构化处理:PO对象toString日志转JSON工具 1. 解决的问题2. 下载地址 在Java项目中,PO(Plain Old Java Object)对象遍布各个角落,且常常伴随着大量的日志记录需求。传统的做法是通过toString方法直接打印这些对象&…...
python学opencv|读取图像(六十五)使用cv2.boundingRect()函数实现图像轮廓矩形标注
【1】引言 前序学习进程中,已经使用cv2.findContours()函数cv2.drawContours()函数实现图像轮廓识别和标注,这种标注沿着图像的轮廓进行,比较细致。相关文章链接为: python学opencv|读取图像(六十四)使用…...
大疆无人机需要的kml文件如何制作kml导出(大疆KML文件)
大疆无人机需要的轨迹kml文件,是一种专门的格式,这个kml里面只有轨迹点,其它的属性信息都不需要。 BigemapPro提供了专门的大疆格式输出, 软件这里下载 www.bigemap.com 安装后,kml导入如下图: 然后选择…...
ArrayList、LinkedList、HashMap、HashTable、HashSet、TreeSet
集合族谱 在这些集合中,仅有vector和hashtable是线程安全的,其内部方法基本都有synchronized修饰。 ArrayList 底层采用Object数组实现,实现了RandomAccess接口因此支持随机访问。插入删除操作效率慢。 ArrayList需要一份连续的内存空间。 A…...
手动配置IP
手动配置IP,需要考虑四个配置项: 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址:格式表现为点分十进制,如192.168.254.1 子网掩码:用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...
idea如何使用AI编程提升效率-在IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤-卓伊凡
idea如何使用AI编程提升效率-在IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤-卓伊凡 问题 idea编译器 安装copilot AI工具 实际操作 在 IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤如下: 打开 IntelliJ IDEA: 打开你的 IntelliJ IDEA 应用…...
游戏引擎学习第101天
回顾当前情况 昨天的进度基本上完成了所有内容,但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的,但还是存在一些可能或者确定的bug。正如昨天最后提到的,既然现在时间晚了,就不太适合开始调试,所以今天我…...
css块级元素和行内元素区别
在CSS中,元素可以分为两大类:块级元素(Block-level elements)和行内元素(Inline elements)。这两种元素在网页布局中起着不同的作用,主要体现在它们的显示方式、尺寸控制、以及与其他元素的交互…...
JAVA安全—Shiro反序列化DNS利用链CC利用链AES动态调试
前言 讲了FastJson反序列化的原理和利用链,今天讲一下Shiro的反序列化利用,这个也是目前比较热门的。 原生态反序列化 我们先来复习一下原生态的反序列化,之前也是讲过的,打开我们写过的serialization_demo。代码也很简单&…...
什么是信息熵
信息熵 公式 一个离散随机变量 X X X的可能取值为 X x 1 , x 2 , . . . , x n Xx_1,x_2,...,x_n Xx1,x2,...,xn,而对应的概率为 p i p ( X x i ) p_ip(Xx_i) pip(Xxi),如下 x 1 x_1 x1 x 2 x_2 x2 x 3 x_3 x3 x 4 x_4 x4… x n x_n xnp( x …...
使用API有效率地管理Dynadot域名,清除某一文件夹中域名的默认DNS设置
关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...




