运行效果如截图:左边和保存的图片做对比,打印相似度,部分打印内容为python中的打印输出,可以用来做结果判断。右边打开摄像头后,可以单张图片进行人脸识别,或者一直截图镜头中的图片进行比对。期中python是使用开源的face_recognition进行人脸识别的。
想了解更多我发过的C#的博客,参考:C#基础知识体系框架图,及起对应我发过的博客_花开莫与流年错_的博客-CSDN博客
下面我先介绍python部分
官网参考连接: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);
}
});
}
}
}