我需要添加一个计时器或一个循环,以在检测到脸部后立即捕获50张图像。 我尝试放置一个计时器,但是我不明白如何使用计时器在检测到人脸时自动捕获图片。
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 System.Windows;
using Emgu;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
namespace FaceDetAndRecog
{
public partial class frmRegistration : Form
{
//-----------------------Global declarations-------------------------------------------
double counter = 0.0;
// A classifier which is used to detect the object for which it has been trained for, from the source
HaarCascade _faceDet;
HaarCascade _eyeDet;
// Create a Font of the specific type, horizontal scale and vertical scale
MCvFont _font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_TRIPLEX, 0.6, 0.6);
// Accessing pixels through a managed array (OpenCV supports Bgr)
Image<Bgr, Byte> _frame;
// Create a capture using the default camera
Capture _camera;
// To create an 8bit unsigned Grayscale image
Image<Gray, byte> _result, _trainedFace = null, _grayFace = null;
// List of gray scale images for training
List<Image<Gray, byte>> _traineImages = new List<Image<Gray, byte>>();
// List of labels for trained images
List<string> _labels = new List<string>(), _user = new List<string>();
List<int> Labels_ID = new List<int>();
List<string> Labels_Name = new List<string>();
int _count, _numLabels, _t;
string _name, _names = null, _dirName = Application.StartupPath + "/Faces", _fileName = "Faces.txt", _fullFilePath = "";
//-------------------------------------Global declarations end---------------------------------
// ---------------------------------------Constructor----------------------------------------
public frmRegistration()
{
//initializing xml files to save data of images
InitializeComponent();
_faceDet = new HaarCascade("haarcascade_frontalface_default.xml");
_eyeDet = new HaarCascade("haarcascade_eye.xml");
_fullFilePath = _dirName + "/" + _fileName;
loadData();
}
//-------------------------------Constructor End-------------------------------------------------
//-------------------------------Method to reload all data from file---------------------------
public void loadData()
{
try
{
//Load previuos trained faces and labels for each image
string Labelsinfo = File.ReadAllText(_fullFilePath);
Console.WriteLine("read all text: " + Labelsinfo);//debug
string[] Labels = Labelsinfo.Split(',');
Console.WriteLine("string of labels: " + String.Join("\n", Labels));//debug
Console.WriteLine("length of labels(including spaces): " + Labels.Length);//debug
// print all labels (IDs)
int temp1 = 0;
Labels_ID.Clear();
for (int i = 1; i < (Labels.Length - 1); i++)
{
if (i % 2 != 0)
{
Console.WriteLine("Label_ID: " + int.Parse(Labels[i - 1]));
Labels_ID.Add(int.Parse(Labels[i - 1]));
temp1++;
}
}
//print total number of labels obtained after exiting the loop
Console.WriteLine("total Label_IDs : " + temp1);
_numLabels = _count;
string LoadFaces = null;
_traineImages.Clear();
int k = 1;
for (int tf = 1; tf < Labels_ID.Count+1; tf++)
{
LoadFaces = "face" + tf + ".bmp";
Console.WriteLine("Load face: " + LoadFaces);
_traineImages.Add(new Image<Gray, byte>(_dirName + "/" + LoadFaces));
_labels.Add(Labels[k]);
k = k + 2;
}
Console.WriteLine("labels name display:: ");// debug
int names_count = 0;
Labels_Name.Clear();
for (int j = 0; j < (Labels_ID.Count); j++)
{ // debug
Console.WriteLine(_labels[j]);
Labels_Name.Add(_labels[j]);
names_count++;
}
Console.WriteLine("total names: " + names_count);
Console.WriteLine("Total labels(IDs): " + Labels_ID.Count);// debug
}
catch (Exception e)
{
//MessageBox.Show(e.ToString());
MessageBox.Show("Nothing in binary database, please add at least a face(Simply train the prototype with the Add Face Button).", "Triained faces load", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
//---------------------------------------Method ends-------------------------------------------
private void frmRegistration_Load(object sender, EventArgs e)
{
}
//-----------------------------Detect button Handler------------------------------------------
private void btnDetect_Click(object sender, EventArgs e)
{
//Create a capture using the default camera (using OpenCV)
_camera = new Emgu.CV.Capture();
// A Bgr image frame. Returns Mat(matrix). If no more frames are available, null will be returned.
_camera.QueryFrame();
//Your WinForms app is driven by a message loop that pulls messages out of a queue.
//When that queue is emptied, the message loop enters a quiet state, sleeping efficiently
//until the next message appears in the message queue. This helps conserve CPU processing
//resources (cycles wasted spinning in a loop takes CPU time away from other processes
//running on the machine, so everything feels slower) and also helps reduce power
//consumption / extend laptop battery life.
//The code below sends the application into idle state and disables the Detect button
Application.Idle += new EventHandler(FrameProcedure);
btnDetect.Enabled = false;
}
//-----------------------------Detect button Handler End------------------------------------------
//--------------------------------Frame Procedure-------------------------------------------------
private void FrameProcedure(object sender, EventArgs e)
{
//A list of string defined at class level
_user.Add("");
//Resize the current image taken by camera and save into Bgr _frame
_frame = _camera.QueryFrame().Resize(320, 244, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
//Convert the resized image into gray scale
_grayFace = _frame.Convert<Gray, Byte>();
//Face detector, detects the face from gray scale image captured by the camera using a FaceDet xml with threshold values
MCvAvgComp[][] faceDetectedNow = _grayFace.DetectHaarCascade(
_faceDet,
1.2,
10,
Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(50, 50));
/////////////////////////////////////LOOP
//Everytime a face is detected by the camera
foreach (MCvAvgComp f in faceDetectedNow[0])
{
if(true){
timer1.Enabled = true;
}
_t = _t + 1;
//f.rect (Bounding rectangle for the object (average rectangle of a group)
//_result is a gray scale image
//Convert the detected image into gray scale and resize it, then save it into _result
while (timer1.Enabled)
{
_result = _frame.Copy(f.rect).Convert<Gray, Byte>().Resize(500, 500, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
//_frame (a Bgr image)
//Draw a rectangle(of detected image) on the frame with a specific color and thickness
_frame.Draw(f.rect, new Bgr(Color.Red), 2);
}
//_traineImages is a list of previously taken images
// If there exist any previous training images then
if (_traineImages.ToArray().Length != 0)
{
//======================LBPH recognizer=================================
//Initializing LBPH recognizer
FaceRecognizer recog = new LBPHFaceRecognizer(1, 8, 8, 8, 100);
//Training model
//Console.WriteLine("_labels is: " + _labels.Select(int.Parse).ToList()).ToArray());
recog.Train(_traineImages.ToArray(),Labels_ID.ToArray());
//predicting result
int temp_result = recog.Predict(_result).Label;
//Displaying predicted result in screen
if((temp_result != -1))
{
Console.Write("---> " + Labels_Name[temp_result - 1]);
_frame.Draw(Labels_Name[temp_result-1], ref _font, new Point(f.rect.X - 2, f.rect.Y - 2), new Bgr(Color.LightGreen));
}
}
_user[_t - 1] = _name;
_user.Add("");
//counter++;
}
_t = 0;
// For each face detected
for (int i = 0; i < faceDetectedNow[0].Length; i++ )
{
_names = _names + _user[i] + ", ";
}
// show detected image on the _frame of form
imgBoxCamera.Image = _frame;
lblDetName.Text = _names;
_names = "";
_user.Clear();
}
//-----------------------------------Frame Procedure----------------------------------------------
//------------------------------------Save Button-------------------------------------------------
private void btnSave_Click(object sender, EventArgs e)
{
_count = _count + 1;
_grayFace = _camera.QueryGrayFrame().Resize(320, 244, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
MCvAvgComp[][] faceDetectedNow = _grayFace.DetectHaarCascade(_faceDet, 1.2, 10, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(50, 50));
foreach(MCvAvgComp f in faceDetectedNow[0])
{
_trainedFace = _frame.Copy(f.rect).Convert<Gray, byte>();
break;
}
_trainedFace = _result.Resize(500, 500, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
_traineImages.Add(_trainedFace);
_labels.Add(txtUserName.Text);
string a = _traineImages.ToArray().Length.ToString() + ",";
Console.WriteLine("a : " + a);
string b = "";
Console.WriteLine("b : " + b);
//File.WriteAllText(_fullFilePath, a);
File.AppendAllText(_fullFilePath, a);
for (int i = _traineImages.ToArray().Length; i < _traineImages.ToArray().Length + 1; i++)
{
b = _labels.ToArray()[i-1] + ",";
Console.WriteLine("b inside for loop: " + b);
//save face image to '/Faces' folder
_traineImages.ToArray()[i-1].Save(_dirName +"/face"+ i + ".bmp");
File.AppendAllText(_fullFilePath, b);
}
MessageBox.Show(txtUserName.Text + " added Successfully");
loadData();
}
private void timer1_Tick(object sender, EventArgs e)
{
}
//--------------------------------Save button end-------------------------------------------------
}
}
单击“保存”按钮仅捕获一张图像。我希望程序在按下保存按钮时自动捕获50张图像。