本系统开发环境为Visual Studio 2010,使用.net 4.0开发,使用AForge库和Aipsdk库和Newtonsoft.json库和system.sqlite库以及第三方插件DevExpress完成。
本系统特点:分为人脸库的录入,将信息保存在sqlite数据库中,该数据库中使用一张表,字段有用户姓名,性别,工号,人脸图片(图像存入数据库中可以点击此链接查看)。
数据库字段
本系统功能介绍:
打卡系统界面
首先构造出的是本界面,首先说下个人信息栏,上方的人脸录入和打卡是一个功能只要是调用本机摄像头,找到一张合适的角度拍下此张图片,当界面运行时:界面隐藏了“确定打卡”和“登记按钮”,因为不确定的是当前是打卡还是录入信息。
界面运行时
如果选择打卡,该打卡功能只要是调用摄像头,此时界面变成
打卡界面
如果点击确认打卡,循环读取数据库人脸信息,当相似度大于90的时候跳出循环,读取该条信息显示在界面上,打卡状态为成功。如果没有大于90的就返回重新打卡(不方便人脸不截图)。
打卡成功
下面我将说下信息录入功能,当点击信息录入时打卡按钮变成人脸录入,个人信息文本框变成可用,此时可以输入此人的信息,信息输入完毕,打开人脸录入,最后点击登记功能。
录入信息
登记完成,信息读入数据库:
数据库
此时整个功能就实现了。
下面讲一下具体功能实现,人脸识别当然不是自己写的,调用的是百度AI开放平台的SDK,
百度AI
然后需要创建一个应用列表,需要使用到的是API Key和Secret Key
应用列表
调用代码
然后调用摄像头方面代码。首先是获取摄像头代码
摄像头
FaceCommon是我自己写的一个类,获取已插USB摄像头硬件id
FaceCommon
最后最核心的还是人脸对比
人脸对比
核心代码到此结束文末附源码
FaceCommon代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AForge.Video.DirectShow;
namespace RenLianShiBie
{
public class FaceCommon
{
#region 方法
///
/// 获取已插USB摄像头硬件Id
///
///
public static List GetCameraDeviceId()
{
List _cameraList = new List();
FilterInfoCollection _filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);//获取所有已插USB摄像头驱动信息
if (_filterInfoCollection != null && _filterInfoCollection.Count > 0)
{
for (int i = 0; i < _filterInfoCollection.Count; i++)
{
_cameraList.Add(_filterInfoCollection[i].MonikerString); //向集合中添加USB摄像头硬件Id
}
_cameraList.Remove(""); //移出空项
return _cameraList;
}
else
{
return null;
}
}
#endregion
}
}
宏定义
public class UserImation
{
///
/// 用户
///
public const string strUser = "用户";
///
/// 性别
///
public const string strGender = "性别";
///
/// 工号
///
public const string strNumber = "工号";
///
/// 人脸库图片
///
public const string strFace = "人脸库图片";
}
public class UserImation2
{
///
/// 用户
///
public static string strUser { get; set; }
///
/// 性别
///
public static string strGender { get; set; }
///
/// 工号
///
public static string strNumber { get; set; }
///
/// 人脸库图片
///
public static string strFace { get; set; }
}
from1.cs如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using AForge.Video.DirectShow;
using AForge.Video;
using System.Threading;
using Newtonsoft.Json.Linq;
using System.IO;
namespace RenLianShiBie
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
///
/// USB摄像头硬件Id集合
///
private List _cameraList = new List();
///
/// 视频驱动
///
private VideoCaptureDevice _videoCaptureDevice;
///
/// 人脸图片
///
private Image imgobj;
///
/// 路径
///
string strPath = @"F:\中地学习\人脸识别\测试\" ;
///
/// 录入信息按钮
///
///
///
private void simpleButton1_Click(object sender, EventArgs e)
{
simpleButton2.Visible = false;
simpleButton4.Text = "人脸录入";
simpleButton4.Visible = true;
simpleButton3.Visible = true;
textEdit1.Properties.ReadOnly = textEdit2.Properties.ReadOnly = textEdit3.Properties.ReadOnly = false;
}
///
/// 界面初始化
///
///
///
private void Form1_Load(object sender, EventArgs e)
{
simpleButton2.Visible=false;
simpleButton4.Text = "打卡";
simpleButton4.Visible = true;
simpleButton3.Visible = false;
#region 填充摄像头下拉框
_cameraList = FaceCommon.GetCameraDeviceId();//获取所有USB摄像头硬件Id集合
if (_cameraList != null && _cameraList.Count > 0)
{
foreach (var item in _cameraList)
{
labelControl7.Text = item; //向下拉框中添加摄像头列表
}
}
else
{
//如何未获取到USB摄像头则禁用此选择
labelControl7.Text = "当前无摄像头"; ;
}
#endregion
}
///
/// 人脸录入
///
///
///
private void simpleButton4_Click(object sender, EventArgs e)
{
if (simpleButton4.Text == "打卡")
{
simpleButton1.Visible = false;
simpleButton2.Visible = true;
}
if (this.labelControl7.Text != null)
{
_videoCaptureDevice = new VideoCaptureDevice(this.labelControl7.Text);
_videoCaptureDevice.NewFrame += HandNewFrame;
}
if (_videoCaptureDevice != null)
{
_videoCaptureDevice.Start();
}
}
///
/// 播放事件
///
///
///
private void HandNewFrame(object sender, NewFrameEventArgs args)
{
try
{
this.Invoke(new Action(() =>
{
if (args != null)
{
this.pictureBox1.Image = args.Frame.Clone() as Image;
// imgobj = args.Frame.Clone() as Image;
// imgobj.Save(@"F:\中地学习\人脸识别\测试\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg");
}
}));
}
catch (Exception exception)
{
//throw;
}
}
///
/// 全部信息录入
///
///
///
private void simpleButton3_Click(object sender, EventArgs e)
{
MySqlite.MySqliteConnection();
UserImation2.strUser = textEdit1.Text;
UserImation2.strGender = textEdit2.Text;
UserImation2.strNumber = textEdit3.Text;
if(UserImation2.strUser=="")//图片以姓名命名,要求必须先填用户姓名,才能录照片
{
return;
}
//关闭
if (_videoCaptureDevice != null)
{
_videoCaptureDevice.SignalToStop();
}
//点击全部录入时也就是拍照,获取定格图片
imgobj = this.pictureBox1.Image;
imgobj.Save(strPath + textEdit1.Text + ".jpg");
MySqlite.MyInsertTable(UserImation2.strUser, UserImation2.strGender, UserImation2.strNumber, strPath + textEdit1.Text + ".jpg");
}
private void simpleButton2_Click(object sender, EventArgs e)
{
//关闭
if (_videoCaptureDevice != null)
{
_videoCaptureDevice.SignalToStop();
}
imgobj = this.pictureBox1.Image;
imgobj.Save(strPath +@"\打卡\" + "1.jpg");
var API_KEY = "zKASe0f2AtMvzdd05fBQEEl4";
var SECRET_KEY = "Q7C5nwHw9aLA815vL60mRRkhProZusq7";
Baidu.Aip.Face.Face client = new Baidu.Aip.Face.Face(API_KEY, SECRET_KEY);
MySqlite.MySqliteConnection();
while(true)
{
string strPa = "";
int nNum = 0;
Dictionary> dic= MySqlite.MySelectGridViewTable();
foreach (KeyValuePair> ergodic in dic)
{
foreach (var myValues in ergodic.Value)
{
nNum++;
if (nNum == 1)
{
textEdit1.Text = myValues;
}
else if (nNum == 2)
{
textEdit2.Text = myValues;
}
else if (nNum == 3)
{
textEdit3.Text = myValues;
}
else if (nNum == 4)
{
// textEdit4.Text = myValues;
strPa = myValues;//获取最后一个图片的位置
}
else
{
}
}
}
var faces = new JArray
{
new JObject
{
{"image", ReadImg(strPa)},
{"image_type", "BASE64"},
{"face_type", "LIVE"},
{"quality_control", "LOW"},
{"liveness_control", "NONE"},
},
new JObject
{
{"image", ReadImg(strPath +@"\打卡\"+ "1.jpg")},
{"image_type", "BASE64"},
{"face_type", "LIVE"},
{"quality_control", "LOW"},
{"liveness_control", "NONE"},
}
};
var result = client.Match(faces);
try
{
double dData = double.Parse(result.First.Next.Next.Next.Next.Next.First.First.First.ToString());
if (dData >= 90)
{
textEdit4.Text = "打卡成功";
break;
}
}
catch (System.Exception ex)
{
}
}
}
///
/// 格式转换
///
///
///
public string ReadImg(string img)
{
return Convert.ToBase64String(File.ReadAllBytes(img));
}
}
}
数据库代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data;
using DevExpress.XtraEditors;
using System.IO;
using System.Drawing;
namespace RenLianShiBie
{
class MySqlite
{
static SQLiteConnection sqlCnn = null;
///
/// 数据库链接
///
public static void MySqliteConnection()
{
try
{
string strPath = @"F:\中地学习\yuanma\FacecorePlatform_53da9c13-237f-4e2b-a5bd-29b74c3ea02e\faceView\RenMan.db";
sqlCnn = new SQLiteConnection();
sqlCnn.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strPath;
sqlCnn.Open();
if (sqlCnn.State != ConnectionState.Open)
{
XtraMessageBox.Show("数据库连接失败 ");
return;
}
}
catch (System.Exception ex)
{
return;
}
}
///
/// 创建表
///
public static void MyCreateTable()
{
SQLiteCommand mDbCmd = sqlCnn.CreateCommand();
mDbCmd.CommandText = "SELECT COUNT(*) FROM sqlite_master where type='table' and name='QrCode';";
if (0 == Convert.ToInt32(mDbCmd.ExecuteScalar()))
{
string sql = "CREATE TABLE " + "QrCode" + "(" + "用户 string,性别 string,工号 string, 人脸库 oleobject" + ")";
SQLiteCommand oledbCmdup1 = new SQLiteCommand(sql, sqlCnn);
oledbCmdup1.ExecuteNonQuery();
}
else
{
}
}
///
/// 插入
///
public static void MyInsertTable(string strUser,string strGender,string strNumber,string strFace)
{
//读取人脸图片
FileStream fileStream = new FileStream(strFace, FileMode.Open);
byte[] bFile = new byte[fileStream.Length];//分配数组大小
fileStream.Read(bFile, 0, (int)fileStream.Length);//将文件内容读进数组
fileStream.Close();//关闭文件对象
SQLiteCommand com = sqlCnn.CreateCommand();
com.CommandText = "Insert into QrCode(用户,性别,工号,人脸库) Values(@用户,@性别, @工号,@人脸库)";
com.Parameters.AddWithValue("@用户", strUser);
com.Parameters.AddWithValue("@性别", strGender);
com.Parameters.AddWithValue("@工号", strNumber);
com.Parameters.AddWithValue("@人脸库", bFile);
com.ExecuteNonQuery();
XtraMessageBox.Show("增加人员信息成功");
}
///
/// 查询
///
///
///
public static Dictionary> MySelectGridViewTable()
{
string strUser = "";
string strGender = "";
string strNumber = "";
string strFace = "";
Dictionary> dic = new Dictionary>();
List lstInformation = new List();
string sql = "select * from QrCode";
SQLiteCommand oledbCmdup = new SQLiteCommand(sql, sqlCnn);
SQLiteDataReader r = oledbCmdup.ExecuteReader();
int num = 0;
while (r.Read())
{
num++;
strUser = r[UserImation.strUser].ToString();
strGender = r[UserImation.strGender].ToString();
strNumber = r[UserImation.strNumber].ToString();
SQLiteCommand com = sqlCnn.CreateCommand();
com.CommandText = "Select 人脸库 From QrCode where 用户=" + "'" + strUser + "'";
byte[] bFile = (byte[])com.ExecuteScalar();//读取之后转换成二进制字节数组
if (bFile == null)
{
XtraMessageBox.Show("数据出错");
return null;
}
MemoryStream stream = new MemoryStream(bFile);
Image img = Image.FromStream(stream);//将二进制字节数组还原成原本的图像
img.Save(@"F:\中地学习\人脸识别\测试\临时数据\" + num + ".jpg");
strFace = @"F:\中地学习\人脸识别\测试\临时数据\" + num + ".jpg";
lstInformation.Add(strUser);
lstInformation.Add(strGender);
lstInformation.Add(strNumber);
lstInformation.Add(strFace);
dic.Add(num, lstInformation);
}
return dic;
}
}
}