C#(Winform)通过添加AForge添加并使用系统摄像机

news2025/4/3 23:00:39

先展示效果 

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;
        }
        #endregion
        private 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);
        }
        #endregion

        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();
                }
            }
        }

        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;
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2299242.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode: 611. 有效三角形的个数 + 排序 + 双指针】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

每日十题八股-补充材料-2025年2月15日

1.TCP是如何保证消息的顺序和可靠的&#xff1f; 写得超级好的文章 首先肯定是三次握手和四次挥手保证里通讯双方建立了正确有效的连接。 其次是校验和、序列号&#xff0c;ACK消息应答机制还有重传机制&#xff0c;保证了消息顺序和可靠。 同时配合拥塞机制和流量控制机制&am…

国内已经部署DeepSeek的第三方推荐

大家好&#xff0c;我是苍何。 最近DeepSeek爆火&#xff0c;我也说点心里话&#xff0c;其实就我们普通人而言&#xff0c;要想用好 DeepSeek&#xff0c;其实无非就是要利用好工具为我们自己提效。 比如你是搞编程的&#xff0c;你就得学会如何用 DeepSeek 更快速的辅助你编…

Windows环境下使用Ollama搭建本地AI大模型教程

注&#xff1a;Ollama仅支持Windows10及以上版本。 安装Ollama 去 ollama官网 下载对应平台及OS的安装包。 运行安装包&#xff0c;点击“安装”按钮即可开始安装。Ollama会自动安装到你的 C:\Users\<当前用户名>\AppData\Local\Programs\Ollama 目录上。 安装完成后&…

2024年认证杯SPSSPRO杯数学建模A题(第二阶段)保暖纤维的保暖能力全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 A题 保暖纤维的保暖能力 原题再现&#xff1a; 冬装最重要的作用是保暖&#xff0c;也就是阻挡温暖的人体与寒冷环境之间的热量传递。人们在不同款式的棉衣中会填充保暖材料&#xff0c;从古已有之的棉花、羽绒到近年来各种各样的人造纤维。不…

算法19(力扣244)反转字符串

1、问题 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 2、示例 &#xff08;1&#xff09; 示例 1&a…

DeepSeek 助力 Vue 开发:打造丝滑的卡片(Card)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

ESP32 arduino + DeepSeek API访问

此项目主要使用ESP32-S3实现一个AI语音聊天助手&#xff0c;可以通过该项目熟悉ESP32-S3 arduino的开发&#xff0c;百度语音识别&#xff0c;语音合成API调用&#xff0c;百度文心一言大模型API的调用方法&#xff0c;音频的录制及播放&#xff0c;SD卡的读写&#xff0c;Wifi…

最新国内 ChatGPT Plus/Pro 获取教程

最后更新版本&#xff1a;20250202 教程介绍&#xff1a; 本文将详细介绍如何快速获取一张虚拟信用卡&#xff0c;并通过该卡来获取ChatGPT Plus和ChatGPT Pro。 # 教程全程约15分钟开通ChatGPT Plus会员帐号前准备工作 一个尚未升级的ChatGPT帐号&#xff01;一张虚拟信用卡…

SQLMesh 系列教程4- 详解模型特点及模型类型

SQLMesh 作为一款强大的数据建模工具&#xff0c;以其灵活的模型设计和高效的增量处理能力脱颖而出。本文将详细介绍 SQLMesh 模型的特点和类型&#xff0c;帮助读者快速了解其强大功能。我们将深入探讨不同模型类型&#xff08;如增量模型、全量模型、SCD Type 2 等&#xff0…

渗透利器:YAKIT 工具-基础实战教程.

YAKIT 工具-基础实战教程. YAKIT&#xff08;Yak Integrated Toolkit&#xff09;是一款基于Yak语言开发的集成化网络安全单兵工具&#xff0c;旨在覆盖渗透测试全流程&#xff0c;提供从信息收集、漏洞扫描到攻击实施的自动化支持。其核心目标是通过GUI界面降低Yak语言的使用…

jenkins 配置ssh拉取gitlab

一、生成key ssh-keygen -t rsa -b 4096 -C "root" 二、将id_rsa内容拷贝到jenkins 公钥id_rsa.pub拷贝到gitlab

基于css实现正六边形的三种方案

方案一&#xff1a;通过旋转三个长方形生成正六边形 分析&#xff1a; 如下图所示&#xff0c;我们可以通过旋转三个长方形来得到一个正六边形。疑问&#xff1a; 1. 长方形的宽高分别是多少&#xff1f; 设正六边形的边长是100&#xff0c;基于一些数学常识&#xff0c;可以…

18.Python实战:实现年会抽奖系统

目录结构 python/ ├── sql/ │ └── table.sql # 创建数据库及数据表 ├── config/ │ └── __init__.py # 数据库和Flask配置 ├── static/ │ ├── style.css # 样式文件 │ └── script.js # JavaScript脚本…

145,【5】 buuctf web [GWCTF 2019]mypassword

进入靶场 修改了url后才到了注册页面 注测后再登录 查看源码 都点进去看看 有个反馈页面 再查看源码 又有收获 // 检查$feedback是否为数组 if (is_array($feedback)) {// 如果是数组&#xff0c;弹出提示框提示反馈不合法echo "<script>alert(反馈不合法);<…

19.4.9 数据库方式操作Excel

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 本节所说的操作Excel操作是讲如何把Excel作为数据库来操作。 通过COM来操作Excel操作&#xff0c;请参看第21.2节 在第19.3.4节【…

CAS单点登录(第7版)7.授权

如有疑问&#xff0c;请看视频&#xff1a;CAS单点登录&#xff08;第7版&#xff09; 授权 概述 授权和访问管理 可以使用以下策略实施授权策略以保护 CAS 中的应用程序和依赖方。 服务访问策略 服务访问策略允许您定义授权和访问策略&#xff0c;以控制对向 CAS 注册的…

java集合框架之Map系列

前言 首先从最常用的HashMap开始。HashMap是基于哈希表实现的&#xff0c;使用数组和链表&#xff08;或红黑树&#xff09;的结构。在Java 8之后&#xff0c;当链表长度超过阈值时会转换为红黑树&#xff0c;以提高查询效率。哈希冲突通过链地址法解决。需要明确的是&#xff…

C#windows窗体人脸识别

一、创建一个数据库&#xff0c;名为TestFaceDB 里面有一张表就OK了&#xff0c;表名Users,表里面有几个字段我说明一下&#xff1a; id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------v…

53倍性能提升!TiDB 全局索引如何优化分区表查询?

作者&#xff1a; Defined2014 原文来源&#xff1a; https://tidb.net/blog/7077577f 什么是 TiDB 全局索引 在 TiDB 中&#xff0c;全局索引是一种定义在分区表上的索引类型&#xff0c;它允许索引分区与表分区之间建立一对多的映射关系&#xff0c;即一个索引分区可以对…