C#打开摄像头后获取图片,调用face_recognition进行人脸识别

3 篇文章 0 订阅
2 篇文章 1 订阅

运行效果如截图:左边和保存的图片做对比,打印相似度,部分打印内容为python中的打印输出,可以用来做结果判断。右边打开摄像头后,可以单张图片进行人脸识别,或者一直截图镜头中的图片进行比对。期中python使用开源的face_recognition进行人脸识别的。

想了解更多我发过的C#的博客,参考:C#基础知识体系框架图,及起对应我发过的博客_花开莫与流年错_的博客-CSDN博客

下面我先介绍python部分,后附上C#完整代码

官网参考连接:Windows Installation Tutorial · Issue #175 · ageitgey/face_recognition · GitHub

对应github网址:face_recognition/README_Simplified_Chinese.md at master · ageitgey/face_recognition · GitHub

需要先下载CMake,在官网下载即可:Download | CMake

下载python3安装,安装结束时勾选所有用户命令使用:Download Python | Python.org

pip下载地址:pip · PyPI

pip安装:下载解压后,到该目录输入

python setup.py install

pip升级:

pip3 install --upgrade pip
pip install pip	或者用这个试试

安装人脸识别及依赖

pip install dlib
pip install face_recognition
pip install opencv-contrib-python

执行测试用例(期中第一个图片为保存的图片,第二个图片为我的摄像头实时保存的图片)

import face_recognition
import sys
# face_recognition --cpus 4 ./pictures_of_people_i_know/ ./unknown_pictures/

known_image = face_recognition.load_image_file("图片/11.jpg")
unknown_image = face_recognition.load_image_file("xx.jpg")

biden_encoding = face_recognition.face_encodings(known_image)[0]
image_encoding = face_recognition.face_encodings(unknown_image)
if len(image_encoding) > 0:
    unknown_encoding = image_encoding[0]
else:
    print("no")
    sys.exit(0)

results = face_recognition.compare_faces([biden_encoding], unknown_encoding)
face_distances = face_recognition.face_distance([biden_encoding], unknown_encoding)

# print(results)
if results[0] == True and face_distances < 0.4:
    print("yes")
    #sys.exit(1)             # 返回1
else:
    print("no")
    #sys.exit(0)

print("人脸相似度")
print(face_distances)

#sleep(1)
#print(text)

#return results[0]

运行及错误处理

1、python退出运行并返回退出值

import sys
sys.exit(0)

2、C#调用python实现人脸识别,执行接收后获取python打印值

using (System.Diagnostics.Process p = new System.Diagnostics.Process())
{
    p.StartInfo.FileName = @"python3"; //python会运行错误,提示没有face_recognition,需要制定python3的安装路径
    p.StartInfo.Arguments = cmd;//python命令的参数
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.CreateNoWindow = true;
    p.Start();//启动进程
    Console.WriteLine("Start");

    // p.StandardInput.WriteLine(@"exit()");
    StreamReader reader = p.StandardOutput;
    if (reader == null)
        Console.WriteLine("reader is null");
    else
    {
        string output = reader.ReadToEnd();  // ReadToEnd/ReadLine
        Console.WriteLine("face output : " + output);
        string error = p.StandardError.ReadToEnd();
        if (error != null && error != "")
            Console.WriteLine("face err : " + error);
    }
    p.WaitForExit(); // 等待控制台程序执行完成
    Console.WriteLine("执行完毕!");
}

偶尔运行报错:IndexError: list index out of range\r\n"

# 不一定有人脸,所以需要先判断是否有人脸,有才对比相似度
image_encoding = face_recognition.face_encodings(unknown_image)
if len(image_encoding) > 0:
    unknown_encoding = image_encoding[0]
else:
    print("no")
    sys.exit(0)

C#完整代码

1、MainForm窗体显示部分


namespace Study_CSharp.摄像头
{
    partial class Video
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.videoSourcePlayer1 = new AForge.Controls.VideoSourcePlayer();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.button3 = new System.Windows.Forms.Button();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            this.button4 = new System.Windows.Forms.Button();
            this.button5 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // videoSourcePlayer1
            // 
            this.videoSourcePlayer1.Location = new System.Drawing.Point(41, 90);
            this.videoSourcePlayer1.Name = "videoSourcePlayer1";
            this.videoSourcePlayer1.Size = new System.Drawing.Size(932, 571);
            this.videoSourcePlayer1.TabIndex = 7;
            this.videoSourcePlayer1.Text = "videoSourcePlayer1";
            this.videoSourcePlayer1.VideoSource = null;
            // 
            // button1
            // 
            this.button1.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button1.Location = new System.Drawing.Point(704, 22);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(144, 47);
            this.button1.TabIndex = 8;
            this.button1.Text = "关闭摄像头";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button2.Location = new System.Drawing.Point(364, 22);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(144, 47);
            this.button2.TabIndex = 9;
            this.button2.Text = "拍照";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // button3
            // 
            this.button3.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button3.Location = new System.Drawing.Point(534, 22);
            this.button3.Name = "button3";
            this.button3.Size = new System.Drawing.Size(144, 47);
            this.button3.TabIndex = 10;
            this.button3.Text = "保存图片";
            this.button3.UseVisualStyleBackColor = true;
            this.button3.Click += new System.EventHandler(this.button3_Click);
            // 
            // comboBox1
            // 
            this.comboBox1.DropDownHeight = 100;
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.ItemHeight = 15;
            this.comboBox1.Location = new System.Drawing.Point(874, 37);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(121, 23);
            this.comboBox1.TabIndex = 11;
            this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
            // 
            // button4
            // 
            this.button4.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button4.Location = new System.Drawing.Point(24, 22);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(144, 47);
            this.button4.TabIndex = 12;
            this.button4.Text = "人脸识别";
            this.button4.UseVisualStyleBackColor = true;
            this.button4.Click += new System.EventHandler(this.button4_Click);
            // 
            // button5
            // 
            this.button5.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.button5.Location = new System.Drawing.Point(194, 22);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(144, 47);
            this.button5.TabIndex = 13;
            this.button5.Text = "实时扫描";
            this.button5.UseVisualStyleBackColor = true;
            this.button5.Click += new System.EventHandler(this.button5_Click);
            // 
            // Video
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1012, 673);
            this.Controls.Add(this.button5);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.comboBox1);
            this.Controls.Add(this.button3);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.videoSourcePlayer1);
            this.Name = "Video";
            this.Text = "video";
            this.ResumeLayout(false);

        }

        #endregion
        private AForge.Controls.VideoSourcePlayer videoSourcePlayer1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.ComboBox comboBox1;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
    }
}

2、窗体中代码处理部分

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

using AForge;
using AForge.Controls;
using AForge.Video;
using AForge.Video.DirectShow;


namespace Study_CSharp.摄像头
{
    public partial class Video : Form
    {
        FilterInfoCollection videoDevices;//摄像头设备集合
        VideoCaptureDevice videoSource;//捕获设备源
        Bitmap img;//处理图片

        public Video()
        {
            InitializeComponent();
            button3.Enabled = false;
            //先检测电脑所有的摄像头
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            OpenVideo(1);
            comboBox1.BeginUpdate();
            for (int i = 1; i <= videoDevices.Count; i++)
            {
                comboBox1.Items.Add("摄像头" + i);
            }
            comboBox1.EndUpdate();
            if (videoDevices.Count <= 0)
            {
                MessageBox.Show("没有摄像头");
            }
            else{
                comboBox1.Text = "摄像头1";
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "打开摄像头")
            {
                OpenVideo(1);
                button1.Text = "关闭摄像头";
            }
            else
            {
                ShutCamera();
                button1.Text = "打开摄像头";
            }
        }
        // 打开摄像头
        public void OpenVideo(int n)
        {
            if (videoDevices.Count >= n)
            {
                videoSource = new VideoCaptureDevice(videoDevices[n - 1].MonikerString);
                videoSourcePlayer1.VideoSource = videoSource;
                videoSourcePlayer1.Start();
            }
        }
        // 关闭并释放摄像头
        public void ShutCamera()
        {
            if (videoSourcePlayer1.VideoSource != null)
            {
                videoSourcePlayer1.SignalToStop();
                videoSourcePlayer1.WaitForStop();
                videoSourcePlayer1.VideoSource = null;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            img = videoSourcePlayer1.GetCurrentVideoFrame();//拍摄
            button3.Enabled = true; // 开启“保存”功能
        }

        // "保存"按钮click事件
        private void button3_Click(object sender, EventArgs e)
        {
            SaveImage(true);
        }
        public void SaveImage(bool changeName = false)
        {
            if (img == null)
                return;
            try
            {
                //以当前时间为文件名,保存为jpg格式
                //图片路径在程序bin目录下的Debug下
                TimeSpan tss = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                long a = Convert.ToInt64(tss.TotalMilliseconds) / 1000;  //以秒为单位
                if (changeName)
                    img.Save(string.Format("{0}.jpg", a.ToString()));
                else
                    img.Save("xx.jpg");
                button3.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string str = comboBox1.Text;
            int camr = Convert.ToInt32(str[3]) - '0'; // Encoding.ASCII.GetBytes(str);
            if (button1.Text != "打开摄像头" && camr <= videoDevices.Count)
            {
                ShutCamera();
                OpenVideo(camr);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            RunPythonFaceRecgn("test.py");
        }
        // 调用系统命令
        void RunPythonFaceRecgn(string cmd)
        {
            try
            {
                using (System.Diagnostics.Process p = new System.Diagnostics.Process())
                {
                    p.StartInfo.FileName = @"python3"; //python会运行错误,提示没有face_recognition,需要制定python3的安装路径
                    p.StartInfo.Arguments = cmd;//python命令的参数
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.RedirectStandardInput = true;
                    p.StartInfo.RedirectStandardError = true;
                    p.StartInfo.CreateNoWindow = true;
                    p.Start();//启动进程
                    Console.WriteLine("Start");

                    // p.StandardInput.WriteLine(@"exit()");
                    StreamReader reader = p.StandardOutput;
                    if (reader == null)
                        Console.WriteLine("reader is null");
                    else
                    {
                        string output = reader.ReadToEnd();  // ReadToEnd/ReadLine
                        Console.WriteLine("face output : " + output);
                        string error = p.StandardError.ReadToEnd();
                        if (error != null && error != "")
                            Console.WriteLine("face err : " + error);
                    }
                    p.WaitForExit(); // 等待控制台程序执行完成
                    Console.WriteLine("执行完毕!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        bool RunFaceRecgn = false;
        private void button5_Click(object sender, EventArgs e)
        {
            if (RunFaceRecgn)
                RunFaceRecgn = false;
            else
                RunFaceRecgn = true;

            Task.Run(() => {
                while (RunFaceRecgn)
                {
                    img = videoSourcePlayer1.GetCurrentVideoFrame();//拍摄
                    SaveImage();
                    RunPythonFaceRecgn("test.py");
                    System.Threading.Thread.Sleep(500);
                }
            });
        }
    }
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、主要内容:OpenCV能够实现强大丰富的图像处理,但是它缺少一个能够支持它运行的界面。Csharp经过多年的发展,得益于它的“所见及所得”能力,非常方便编写界面。这两者如果能够“双剑合璧”,将有效帮助实际工作产出。本课着重推荐GOCW采用“Csharp基于CLR直接调用Opencv编写的算法库”方法,能够将最新的OpenCV技术引入进来,同时保证生成程序的最小化。    为了进一步说明Csharp和OpenCV的结合使用,首先一个较为完整的基于winform实现答题卡识别的例子,相比较之前的实现,本次进一步贴近生产实际、内涵丰富,对算法也进行了进一步提炼。同时我们对WPF下对OpenCV函数的调用、OpenCV.js的调用进行相关教授。       二、课程结构1、 EmguCV、OpenCVSharp和GOCW之间进行比较(方便代码编写、能够融入最新的算法、速度有保障、方便调试找错、拒绝黑箱化);2、视频采集模块的构建,视频采集和图像处理之间的关系;3、视频采集专用的SDK和“陪练”系统的介绍;4、在视频增强类项目和图像处理项目,算法的选择;5、Csharp界面设计、图片的存储和其他构建设计;6、较为完整的答题卡识别例子,兼顾界面设计和算法分析;8、WPF基于GOCW也同样可以基于GOCW实现算法调用;webForm虽然也可以通过类似方法调用,但是OpenCV.JS的方法更现代高效。9、关于软件部署的相关要点和窍门。       三、知识要点:1、基本环境构建和程序框架;2、CLR基本原理和应用方法;3、接入、采集、模拟输入;4、图像处理,通过构建循环采集图片;5、增强和实时处理;6、基于投影等技术的答题卡识别算法;7、存储、转换;8、部署交付。        课程能够帮助你掌握Csharp调用Opencv的基本方法,获得相应框架代码和指导;从而进一步提升实现“基于图像处理”的解决方案能力。  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值