1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 基于emgucv的人脸检测及识别

基于emgucv的人脸检测及识别

时间:2018-06-26 17:07:25

相关推荐

基于emgucv的人脸检测及识别

文章目录

前言一、窗体设计二、代码部分三、结果四、总结

前言

这是该系列文章的第二篇。本篇文章主要实现的功能是对人脸进行检测及识别。人脸检测部分用的算法是级联分类器,人脸识别部分用的LBPH算法。识别精度可以媲美普通学校用的人脸识别系统,话不多说,上代码

一、窗体设计

二、代码部分

using Emgu.CV;using Emgu.CV.CvEnum;using Emgu.CV.Face;using Emgu.CV.Structure;using Emgu.CV.Util;using System;using System.Drawing;using System.IO;using System.Text;using System.Windows.Forms;namespace facerecognize{public partial class Form1 : Form{//在方法外面定义各个需要的变量和类,这样所有的方法都可调用相应的变量Capture _capture;//实例化人脸检测级联分类器CascadeClassifier face_detect = new CascadeClassifier(@"haarcascade\haarcascade_frontalface_alt2.xml");//haarcascade_frontalface_alt2Mat face_image = new Mat();VectorOfInt image_lable = new VectorOfInt();VectorOfMat image_data = new VectorOfMat();string[] name;//实例化局部二值模式人脸识别器FaceRecognizer face_recognize = new LBPHFaceRecognizer();bool after_train = false;bool catch_face = false;ASCIIEncoding ascii = new ASCIIEncoding();public Form1(){InitializeComponent();}//定义摄像头捕捉到图片时调用的方法void frame(object sender,EventArgs e){Mat scr = _capture.QueryFrame();//裁剪图片,提高电脑运行速度CvInvoke.Resize(scr, scr, new Size(320, 240));//检测人脸Rectangle[] recs = face_detect.DetectMultiScale(scr);foreach(Rectangle rec in recs){CvInvoke.Rectangle(scr, rec, new MCvScalar(0, 0, 255));//将人脸区域图片显示在imagebox2中,整张图片显示在imagebox1中imageBox2.Image = new Mat(scr, rec);imageBox1.Image = scr;}if(catch_face){if(labeltextBox.Text!=null){//这里输入的只能是英文字符,若是中文,则会出现乱码,笔者一开始以为是编码问题,后面尝试好几种解码方法,都没能解决这个问题。string labeltext = labeltextBox.Text;face_image = new Image<Gray, byte>(new Bitmap(imageBox2.Image.Bitmap)).Resize(120, 120, Inter.Area).Mat;//将图片以image_data-文本框中输入的名字-系统时间.jpg格式保存,方便后面将文本框中名字取出face_image.Save("Image_data" + "\\" + labeltext + "_" + DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + ".jpg");MessageBox.Show("保存成功");catch_face = false;}}if(after_train){foreach(Rectangle rec in recs){//局部变量text存放人脸名字string text = "";Mat scr_image = new Mat(scr, rec);//将人脸图片缩减,并且转为mat格式scr_image = scr_image.ToImage<Gray, byte>().Resize(120, 120, Inter.Area).Mat;//对人脸进行识别FaceRecognizer.PredictionResult result = face_recognize.Predict(scr_image);//name中存的是上面文本框存的各个人脸对应的名字,与label也是一一对应的text = name[result.Label];if(result.Distance>3000){text = "Miss";}CvInvoke.PutText(scr, text, rec.Location, FontFace.HersheyComplex, 1, new MCvScalar(0, 0, 255));imageBox1.Image = scr;}}}private void imageBox1_Click(object sender, EventArgs e){}//打开摄像头private void opencap_Click(object sender, EventArgs e){_capture = new Capture(0);Application.Idle += frame;}//保存图片,并将catch_face重置为trueprivate void savebtn_Click(object sender, EventArgs e){catch_face = true;}//开始训练图片private void trainbtn_Click(object sender, EventArgs e){//将iamge_data中获得所有文件存在path中,后面对其进行切片处理,并且将取得的人脸名字存在name中string[] path = Directory.GetFiles("Image_data");Mat[] data = new Mat[path.Length];int[] label = new int[path.Length];name = new string[path.Length];for(int i =0;i<path.Length;i++){Image<Gray, byte> image = new Image<Gray, byte>(path[i]);data[i] = image.Mat;label[i] = i;//返回最后出现\\的索引int a = path[i].LastIndexOf('\\');//返回最后出现_的索引int b = path[i].LastIndexOf('_');//从a+1处开始截取字符,截取b-a-1个,这就是人脸名字在的区域name[i] = path[i].Substring(a+1, b - a - 1);}image_data.Push(data);image_lable.Push(label);//训练图片face_recognize.Train(image_data, image_lable);face_recognize.Save("face\\data.txt");MessageBox.Show("训练成功");after_train = true;}}}

三、结果

四、总结

识别精度还是很不错的,但目前值得改进的部分就是文本框中不能输入中文,不然文件名中会出现乱码。笔者也已经换了好几种编码方式,依然没有解决这个问题。

希望与各位热爱cv的小伙伴们共同进步,有知道解决方法的读者可在评论区留言。

注:转载请备注出处,原创不易。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。