C#实现窗体人脸识别教程详细整理

692 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情

在之前我写过一篇博客,是关于javaweb实现人脸识别,包括数据库以及java源码,还有相关的jar包都已经上传了,有想要了解的可以去看看,地址是:java实现人脸识别源码 实现了之后又正好朋友开发C#,想要我顺便给写个小功能的人脸识别,于是我就打开我的笔记本就干起代码了,既然java都实现了,难不成还怕个C#实现不了?web端的已经实现了一遍,这次偶就来个高难度的,用winfroms写了一个玩玩,废话不多说,步入正题! 首先我们来先整一个数据库,我这使用的版本: 数据库:sql server2012 C#开发工具:Visual Studio2012 操作系统:win10 家庭版

一、创建一个数据库,名为TestFaceDB

里面有一张表就OK了,表名Users,表里面有几个字段我说明一下: id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------varchar(50)----------------电话 password--------------varchar(50)------------密码 address--------------varchar(50)--------------地址 picture--------------varchar(50)---------------脸的图片 然后我吧数据库脚本放上来:

以上就是准备工作的数据库

二、在VS里面写代码之前我们需要引入一个AForgeDLL文件库

,下载地址: C#处理视频dll库AForge下载安装版

三、在vs里面新建个项目,名称是:Camtest

新建完项目之后我们在新建个sqlhelper,这个文件是用来操作数据库的,主要是人脸注册和认证以及登陆的时候用。源码在这里: C#人脸识别——————SqlHelper 新建一个实体类,名称就随便起个吧,我们命名为:Users,源码在这里: C#人脸识别——————Users

四、人脸检测

接下来我们就开始写窗体,一步一步的来,接着往下看,我们先来整一个人脸检测的玩玩练练手吧: 这里写图片描述 这个是人脸检测的运行结果图!我们不注重界面的美化,我们只注重功能的实现。接下来我们分析一下这个窗体是由哪些控件组成的! 序号对应控件说明: 1--------------------videoSourcePlayer,所在的dll是Aforge.Controls.Video这个里面,名称是videoSourcePlayer1 2--------------------groupBox控件,名称是groupBox1 3--------------------comboBox控件,名称是comboBoxCameras和picsize 4--------------------button控件,名称是button2和close 5--------------------label控件,名称是(左边从上到下)label3,label6,label8,label10,label12,label14。右边从上到下:label4,label5,label7,label9,label11,label13 6--------------------窗体,名称是facedetection 接着我们看一下这个窗体内部的实现代码: 1.首先引入AForge的命名空间:、

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

2.加载窗体的时候先检测一遍我们的摄像头:

 // 刷新可用相机的列表
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            comboBoxCameras.Items.Clear();

            for (int i = 0; i < videoDevices.Count; i++)
            {
                comboBoxCameras.Items.Add(videoDevices[i].Name.ToString());
            }


            if (comboBoxCameras.Items.Count > 0)
                comboBoxCameras.SelectedIndex = 0;
            picsize.SelectedIndex = 0;

3.打开摄像头的方法:

 /// <summary>
        /// 打开摄像头
        /// </summary>
        public void openCan()
        {
            selectedPICIndex = picsize.SelectedIndex;

            selectedDeviceIndex = comboBoxCameras.SelectedIndex;
            //连接摄像头。
            videoSource = new VideoCaptureDevice(videoDevices[selectedDeviceIndex].MonikerString);
            videoSource.VideoResolution = videoSource.VideoCapabilities[selectedDeviceIndex];
            // 枚举所有摄像头支持的像素,设置拍照为1920*1080
            foreach (VideoCapabilities capab in videoSource.VideoCapabilities)
            {
                if (selectedPICIndex == 0)
                {
                    if (capab.FrameSize.Width == 1920 && capab.FrameSize.Height == 1080)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                    if (capab.FrameSize.Width == 1280 && capab.FrameSize.Height == 720)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                }
                else
                {
                    if (capab.FrameSize.Width == 1280 && capab.FrameSize.Height == 720)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                }
            }
            videoSourcePlayer1.VideoSource = videoSource;

            // set NewFrame event handler
            videoSourcePlayer1.Start();
        }

4.保存人脸成一张图片,顺便调用人脸检测库:

//保存图片
        private void button2_Click(object sender, EventArgs e)
        {
            if (videoSource == null)
                return;

            Bitmap bitmap = videoSourcePlayer1.GetCurrentVideoFrame();
            //图片名称,年月日时分秒毫秒.jpg
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmssff") + ".jpg";

            //获取项目的根目录
            String path = AppDomain.CurrentDomain.BaseDirectory;

            //将图片保存在服务器里面
            bitmap.Save(path + "\\picture\\" + fileName, ImageFormat.Jpeg);
            bitmap.Dispose();

            //进行面部特征识别
            facemodel facem = face_test.FaceDetect(path + "\\picture\\" + fileName);
            this.label4.Text = facem.age;      //年龄
            this.label5.Text = facem.beauty;  //漂亮度
            string expression = facem.expression;//表情
            if (expression.Equals("0"))
            {
                this.label7.Text = "不笑";
            }
            else if (expression.Equals("1"))
            {
                this.label7.Text = "微笑";
            }
            else if (expression.Equals("2"))
            {
                this.label7.Text = "大笑";
            }
            string gender = facem.gender;//性别
            if (gender.Equals("male"))
            {
                this.label9.Text = "男";
            }
            else
            {
                this.label9.Text = "女";
            }
            string glasses = facem.glasses;//是否戴眼镜
            if (glasses.Equals("0"))
            {
                this.label11.Text = "无眼镜";
            }
            else if (glasses.Equals("1"))
            {
                this.label11.Text = "普通眼镜";
            }
            else
            {
                this.label11.Text = "墨镜";
            }
            string race = facem.race;//人种
            if (race.Equals("yellow"))
            {
                this.label13.Text = "黄人";
            }
            else if (race.Equals("white"))
            {
                this.label13.Text = "白人";
            }
            else if (race.Equals("black"))
            {
                this.label13.Text = "黑人";
            }
            else if (race.Equals("arabs"))
            {
                this.label13.Text = "棕人";
            }

        }

在上面的这个方法里面我们需要一个解析json的类,类的源码在: 人脸检测解析json的工具类face_test 还有一个model类,类的源码在: 人脸检测的model类facemodel 这就是我们主要的功能实现,整个窗体的源码请移步到这里面看: 人脸检测源码facedetection 最后完美运行。

五、人脸注册

1.新建一个窗体,名称是:faceregiste 下面是运行结果:

人脸注册 至于控件什么的我就不说的那么详细了,大家一看就知道用的什么控件了。 2.由于调用的是百度的API,所以需要Api_Key和Secret_Key,关于这两个,大家可以自行百度。所以先声明一下:

		//Api_Key
        public static string Api_Key = "这里是你的Api_Key";
        //Secret_Key
        public static string Secret_Key = "这里是你的Secret_Key ";

3.刷新可用摄像头列表

  //加载项目
        private void faceregiste_Load(object sender, EventArgs e)
        {

            // 刷新可用相机的列表
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            comboBoxCameras.Items.Clear();

            for (int i = 0; i < videoDevices.Count; i++)
            {
                comboBoxCameras.Items.Add(videoDevices[i].Name.ToString());
            }


            if (comboBoxCameras.Items.Count > 0)
                comboBoxCameras.SelectedIndex = 0;
            picsize.SelectedIndex = 0;

            //打开摄像头
            openCamera();
        }

5.打开摄像头:

//打开摄像头
        public void openCamera() {
            selectedPICIndex = picsize.SelectedIndex;

            selectedDeviceIndex = comboBoxCameras.SelectedIndex;
            //连接摄像头。
            videoSource = new VideoCaptureDevice(videoDevices[selectedDeviceIndex].MonikerString);
            videoSource.VideoResolution = videoSource.VideoCapabilities[selectedDeviceIndex];
            // 枚举所有摄像头支持的像素,设置拍照为1920*1080
            foreach (VideoCapabilities capab in videoSource.VideoCapabilities)
            {
                if (selectedPICIndex == 0)
                {
                    if (capab.FrameSize.Width == 1920 && capab.FrameSize.Height == 1080)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                    if (capab.FrameSize.Width == 1280 && capab.FrameSize.Height == 720)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                }
                else
                {
                    if (capab.FrameSize.Width == 1280 && capab.FrameSize.Height == 720)
                    {
                        videoSource.VideoResolution = capab;
                        break;
                    }
                }
            }
            videoSourcePlayer1.VideoSource = videoSource;

            // set NewFrame event handler
            videoSourcePlayer1.Start();
        }

6.点击注册执行的方法:

 //注册的按钮
        private void register_Click(object sender, EventArgs e)
        {
            Users user = new Users();
            user.name = this.name.Text;
            user.id = DateTime.Now.Ticks / 10000;
            user.password = this.password.Text;
            user.phone = this.phone.Text;
            user.age =(int)this.age.Value;
            user.address = this.address.Text;
            user.picture = SavePicture() ;
            //注册人脸通过的话进去
            if (FaceRegister(user))
            {
                int rel = AddUsers(user);//添加信息
                if (rel > 0)
                {
                    MessageBox.Show("注册成功", "提示信息");
                }
                else
                {
                    MessageBox.Show("添加失败", "提示信息");
                }
            }
        }

7.保存图片的方法:

/// <summary>
        /// 保存图片
        /// </summary>
        public string SavePicture() {
            if (videoSource == null)
            {
                return null;
            }

            Bitmap bitmap = videoSourcePlayer1.GetCurrentVideoFrame();
            //图片名称,年月日时分秒毫秒.jpg
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmssff") + ".jpg";

            //获取项目的根目录
            string path = AppDomain.CurrentDomain.BaseDirectory;
            string picture = path + "\\picture\\" + fileName;
            //将图片保存在服务器里面
            bitmap.Save(picture, ImageFormat.Jpeg);
            bitmap.Dispose();
            return picture;
        }

8.取消按钮的方法:

 //取消的按钮
        private void close_Click(object sender, EventArgs e)
        {
            //停止摄像头
            videoSourcePlayer1.Stop();
            this.Close();
            welcome we = new welcome();
            we.Show();
        }

10.用户注册的方法:

/// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        public int AddUsers(Users users)
        {
            int rel = 0;
            string sql = "insert INTO Users VALUES(@id,@name,@age,@phone,@password,@address,@picture)";
            SqlParameter[] param = {
                                        new SqlParameter("@id",users.id),
                                        new SqlParameter("@name",users.name),
                                        new SqlParameter("@age",users.age),
                                        new SqlParameter("@phone",users.phone),
                                        new SqlParameter("@password",users.password),
                                        new SqlParameter("@address",users.address),
                                        new SqlParameter("@picture",users.picture)
                                        
                                   };
            rel = SqlHelper.ExecuteNonQuery(sql, CommandType.Text, param);
            return rel;
        }

11.人脸注册的方法:

 /// <summary>
        /// 人脸注册
        /// </summary>
        /// <param name="picture"></param>
        public static bool FaceRegister(Users user)
        {
            var client = new Baidu.Aip.Face.Face(Api_Key, Secret_Key);
            //当前毫秒数可能是负数,取绝对值
            var image1 = File.ReadAllBytes(user.picture);

            var result = client.User.Register(image1, user.id.ToString(), user.name, new[] { "gr_test" });
            //得到根节点
            JObject jo_result = (JObject)JsonConvert.DeserializeObject(result.ToString());
            if ((string)jo_result["error_msg"] != null)
            {
                MessageBox.Show("对不起,请把脸放上!","提示",MessageBoxButtons.OK,MessageBoxIcon.Stop);
                return false;
            }
            
            return true;
        }

12.关闭窗体的方法:

 //关闭窗体
        private void faceregiste_FormClosing(object sender, FormClosingEventArgs e)
        {

            DialogResult r = MessageBox.Show("确定要退出程序?", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (r != DialogResult.OK)
            {

                e.Cancel = true;
            }
            videoSourcePlayer1.Stop();//停止摄像头
            videoSourcePlayer1.Dispose();
        }

源码请到这里来看: 人脸注册源码faceregiste