C#winforms实现windows窗体人脸识别(人脸检测、人脸注册)
在之前我写过一篇博客,是关于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)---------------脸的图片
然后我吧数据库脚本放上来:
USE [master]
GO
/****** Object: Database [TestFaceDB] Script Date: 2017-11-30 22:09:36 ******/
CREATE DATABASE [TestFaceDB]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'TestFaceDB', FILENAME = N'E:\DB\TestFaceDB.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'TestFaceDB_log', FILENAME = N'E:\DB\TestFaceDB_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [TestFaceDB] SET COMPATIBILITY_LEVEL = 110
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [TestFaceDB].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [TestFaceDB] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [TestFaceDB] SET ANSI_NULLS OFF
GO
ALTER DATABASE [TestFaceDB] SET ANSI_PADDING OFF
GO
ALTER DATABASE [TestFaceDB] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [TestFaceDB] SET ARITHABORT OFF
GO
ALTER DATABASE [TestFaceDB] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [TestFaceDB] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [TestFaceDB] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [TestFaceDB] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [TestFaceDB] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [TestFaceDB] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [TestFaceDB] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [TestFaceDB] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [TestFaceDB] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [TestFaceDB] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [TestFaceDB] SET DISABLE_BROKER
GO
ALTER DATABASE [TestFaceDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [TestFaceDB] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [TestFaceDB] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [TestFaceDB] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [TestFaceDB] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [TestFaceDB] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [TestFaceDB] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [TestFaceDB] SET RECOVERY FULL
GO
ALTER DATABASE [TestFaceDB] SET MULTI_USER
GO
ALTER DATABASE [TestFaceDB] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [TestFaceDB] SET DB_CHAINING OFF
GO
ALTER DATABASE [TestFaceDB] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )
GO
ALTER DATABASE [TestFaceDB] SET TARGET_RECOVERY_TIME = 0 SECONDS
GO
EXEC sys.sp_db_vardecimal_storage_format N'TestFaceDB', N'ON'
GO
USE [TestFaceDB]
GO
/****** Object: Table [dbo].[Users] Script Date: 2017-11-30 22:09:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Users](
[id] [bigint] NOT NULL,
[name] [varchar](50) NULL,
[age] [int] NULL,
[phone] [varchar](50) NULL,
[password] [varchar](50) NULL,
[address] [varchar](50) NULL,
[picture] [varchar](max) NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [master]
GO
ALTER DATABASE [TestFaceDB] SET READ_WRITE
GO
以上就是准备工作的数据库
二、在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
- 点赞
- 收藏
- 关注作者
评论(0)