Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Created by SharpDevelop.
- * User: Worker
- * Date: 8/9/2018
- * Time: 9:45 AM
- *
- * To change this template use Tools | Options | Coding | Edit Standard Headers.
- */
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.IO.Ports;
- using System.Windows.Forms;
- using Emgu.CV;
- using Emgu.CV.CvEnum;
- using Emgu.CV.Face;
- using Emgu.CV.Structure;
- using Emgu.CV.UI;
- using System.IO;
- using Emgu.CV.Util;
- namespace FaceUnlocker
- {
- public partial class MainForm : Form
- {
- Mat frame = new Mat();
- //lưu các khung hình nhận được từ camera
- VideoCapture capture;
- //đối tượng ghi hình từ camera
- private object lockObject = new object();
- Mat faceOnly = null;
- //lưu hình ảnh khuôn mặt
- Mat capturedFace = null;
- //lưu hình huôn mặt ghi lại
- CascadeClassifier faceDetetor;
- //đối tượng phát hiện khuôn mặt
- EigenFaceRecognizer recog = new EigenFaceRecognizer();
- //đối tượng nhận diện khuôn mặt
- const String PASSWORD_FILE = "password.txt";
- //file lưu mật khẩu
- const String RECOG_FILE = "face.xml";
- //file lưu dữ liệu các khuôn mặt đã huấn luyện
- const String FACE_DIR = "./faces/";
- //thư mục lưu các khuô mặt
- const String ALLOWED_FILE = "./allowed.txt";
- //file lưu những người mở được cửa
- Boolean isTraining = true;
- //trạng thái đang huấn luyện hay không
- String password = "123456";
- //mật khuẩ mặc định
- Dictionary<int,string> labelToName = new Dictionary<int, string>();
- //ánh xạ từ nhãn sang tên
- long checkFaceStartTime = -1;
- //lần cuối cùng kiểm
- int failed = 0;
- //số lần mở cửa thất bại
- String[] allAllowed;
- //tên người mở được cửa
- int openThreshold = 0;
- public MainForm() //hàm khởi đầu chương trình
- {
- InitializeComponent();
- capture = new Emgu.CV.VideoCapture(); //kết nối camera
- capture.ImageGrabbed += ProcessFrame; //lắng nghe mỗi khi có hình ảnh từ camera
- capture.Start(); //bắt đầu ghi hình
- faceDetetor = new CascadeClassifier("lbpcascade_frontalface_improved.xml"); //đọc file phát hiện khuôn mặt
- foreach (var port in SerialPort.GetPortNames()) { //lấy danh sách cổng Serial
- portsBox.Items.Add(port); //thêm vào danh sách chọn
- portsBox.Text = port;
- }
- serialPort1.DataReceived += port_DataReceived; //lắng nghe dữ liệu từ cổng serial
- if (File.Exists(PASSWORD_FILE)) //đọc mật khẩu cũ nếu có
- password = File.ReadAllText(PASSWORD_FILE);
- if (File.Exists(RECOG_FILE)) { //đọc dữ leiu65 huấn luyện nếu có
- recog.Read(RECOG_FILE);
- print("Read recog file.");
- }
- readAllowed(); //đọc danh sách cho phép mở cửa
- reloadData(); //đọc lại dữ liệu khuôn mặt
- }
- void readAllowed()
- {
- if (File.Exists(ALLOWED_FILE)) { //đọc danh sách mở cửa nếu có
- var text = File.ReadAllText(ALLOWED_FILE);
- allowedUsers.Text = text;
- }
- loadAllow();
- }
- void ProcessFrame(object sender, EventArgs e) //xử lý các khung hình từ camera
- {
- if (isTraining) //nếu đang huấn luyện thì không xử lý
- return;
- var shouldOpen = false; //không mở cửa
- capture.Retrieve(frame); //đọc khung hình từ camera
- using (var gray = new Mat()) {
- CvInvoke.CvtColor(frame, gray, ColorConversion.Bgr2Gray); //chuyển hình ảnh thành màu xám
- var faces = faceDetetor.DetectMultiScale(gray); //tìm các khuôn mặt
- foreach (var face in faces) { //duyệt qua danh sách các khuôn mặt
- CvInvoke.Rectangle(gray, face, new MCvScalar(255, 0, 255)); //vẽ hình chữ nhật quanh khuôn mặt đã phát hiện
- faceOnly = new Mat(gray, face);//lưu khuôn mặt ra đối tượng riêng
- faceOnly = faceOnly.Clone();
- CvInvoke.Resize(faceOnly, faceOnly, new Size(160, 160)); //co giãn về kích cỡ chuẩn 160x160
- var result = recog.Predict(faceOnly); //thử dự đoán khuôn mặt
- var label = result.Label; //nhãn của khuôn mặt nhận diện được
- if (label != -1) { //nếu nhận ra người đó
- var name = labelToName[label].Trim(); //lấy ra tên người đó
- if (Array.IndexOf(allAllowed, name) != -1) { //nếu trong danh sách mở cửa
- shouldOpen = true; //có thể mở cửa
- }
- CvInvoke.PutText(gray, name + ":" + Math.Ceiling(result.Distance), face.Location, FontFace.HersheyPlain, 1, new MCvScalar(255, 0, 255));
- } else
- CvInvoke.PutText(gray, "Người lạ", face.Location, FontFace.HersheyPlain, 1, new MCvScalar(255, 0, 255));
- }
- try {
- pictureBox1.Image = gray.Bitmap; //hiển thị hình ảnh camera
- } catch {
- }
- }
- if (checkFaceStartTime != -1) { //nếu đang kiểm tra khuôn mặt
- var now = getCurrentSecond(); //lấy thời gian hiện tại
- if (now - checkFaceStartTime > 5) { //nếu quá 5s
- checkFaceStartTime = -1; //hủy kiểm tra khuôn mặt
- failed++; //cộng số lần thất bại
- if (failed >= 5) { //nếu thất bại quá 5 lần
- sendToArduino("alert=5;"); //báo động arduino
- }
- print("Face checking failed!");
- } else { //chưa quá 5s
- if (shouldOpen) { //nếu có thể mở
- openThreshold++; //cộng dồn
- if (openThreshold > 10) { //nếu đủ 10 lần kiểm tra thành công trong 5s
- checkFaceStartTime = -1; //hủy kiểm tra khuôn mặt
- failed = 0; //reset số lần thất bại
- openThreshold = 0; //reset
- print("Face checking success!!");
- sendToArduino("door=open;echo=Unlocked by face;"); //mở cửa arduino
- }
- }
- }
- tries.Invoke((MethodInvoker)delegate {
- tries.Text = "Đã thử nhận diện: " + failed + " lần"; //hiển thị số lần thất bại
- });
- }
- }
- long getCurrentSecond() //lấy thời gian hiện tại
- {
- return (long)(Math.Ceiling((double)DateTime.Now.ToFileTime() / 10000000));
- }
- void MainFormLoad(object sender, EventArgs e)
- {
- print("ok");
- }
- void ChangePasswordClick(object sender, EventArgs e) //sự kiện đồi mật khẩu
- {
- var newPWForm = new NewPassword(); //gọi form đổi mật khẩu
- newPWForm.ShowDialog(); //hiển thị form
- if (newPWForm.DialogResult == DialogResult.OK) { //nếu bấm ok
- password = newPWForm.getPassword(); //lấy mật khẩu mới
- File.WriteAllText(PASSWORD_FILE, password); //lưu lại
- MessageBox.Show("Đã lưu mật khẩu mới!");//thông báo thành công
- } else {
- MessageBox.Show("Mật khẩu không hợp lệ!");
- }
- }
- void ConnectClick(object sender, EventArgs e) //bấm nút kết nối arduino
- {
- if (serialPort1.IsOpen) { //nếu cổng đã mở
- serialPort1.Close(); //đóng cổng
- connect.Text = "Kết nối";
- } else {
- connect.Text = "Ngắt kết nối";
- serialPort1.PortName = "" + portsBox.SelectedItem;
- serialPort1.Open(); //mở cổng
- }
- }
- private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) //dữ liệu từ arduino tới
- {
- while (serialPort1.BytesToRead > 0) { //nếu có dữ liệu
- var command = serialPort1.ReadTo("="); //đọc lệnh
- var value = serialPort1.ReadTo(";");//đọc giá trị của lệnh
- print("Receive: " + command + "=" + value);
- if (command.Equals("password")) { //lệnh kiểm tra mật khẩu
- if (value.Equals(password)) { //mật khuẩ đúng
- sendToArduino("door=open;"); //mở cửa
- sendToArduino("echo= Unlocked!! ;");
- } else {
- sendToArduino("door=close;"); //đóng cửa
- sendToArduino("echo= Password is incorrect!! ;");
- }
- } else if (command.Equals("check") & value.Equals("face")) { //lệnh kiểm tra khuôn mặt
- startCheckingFace(); //bắt đầu kiểm tra khuôn mặt
- }
- }
- }
- void startCheckingFace()
- {
- checkFaceStartTime = getCurrentSecond(); //bắt đầu kiểm tra từ thời điểm này
- print("Start checking face");
- openThreshold = 0;
- }
- void print(String s)
- {
- System.Diagnostics.Debug.WriteLine(s);
- }
- void sendToArduino(String s) //lệnh gửi dữ liệu tới arduino
- {
- if (serialPort1.IsOpen) { //nếu cỗng mở
- serialPort1.Write(s); //thì gửi
- print("Sent command: " + s);
- } else {
- print("Serial is not opened yet"); //báo lỗi
- }
- }
- void AddImageClick(object sender, EventArgs e) //thêm ảnh vào thư viện
- {
- var userName = currentUser.Text.Trim(); //lấy tên người hiện tại
- if (userName.Length > 0) { //nếu tên không rỗng
- if (capturedFace != null) { //nếu đã chụp được khuôn mặt
- Directory.CreateDirectory(FACE_DIR + "/" + userName); //tại thư mục cho người đó
- print("Add new image to " + userName);
- CvInvoke.Imwrite(FACE_DIR + "/" + userName + "/" + DateTime.Now.ToFileTime() + ".jpg", capturedFace); //lưu ảnh vào đó
- } else
- MessageBox.Show("Chưa có hình ảnh!");
- } else
- MessageBox.Show("Chưa có tên!");
- }
- void OpenDoorClick(object sender, EventArgs e) //bấm nút mỡ cửa
- {
- sendToArduino("door=open;");
- }
- void CloseDoorClick(object sender, EventArgs e) //bấm nút đóng cửa
- {
- sendToArduino("door=close;");
- }
- void retrain() //huấn luyện lại dữ liệu
- {
- isTraining = true;
- MessageBox.Show("Start retraining");
- recog = new EigenFaceRecognizer(30, 5000); //tạo đối tượng nhận diện với 30 đặc trưng và ngưỡng nhận diện là 5000
- var imgs = new VectorOfMat();
- var labels = new VectorOfInt();
- var count = 1; //biến đếm nhãn
- labelToName.Clear();
- foreach (var userPath in Directory.GetDirectories(FACE_DIR)) { //duyệt qua danh sách thư mục trong /faces
- var userName = Path.GetFileName(userPath).Trim(); //lấy tên thư mục, chính là tên người
- foreach (var file in Directory.GetFiles(userPath)) { //lấy danh sách file trong đó
- var img = CvInvoke.Imread(file, ImreadModes.Grayscale); //đọc hình ảnh
- imgs.Push(img); //cho vào danh sách huấn luyện
- labels.Push(new []{ count }); //gán nhãn
- }
- labelToName.Add(count, userName); //thêm vào danh sách ánh xạ nhãn tới tên
- count++; //tăng biến đếm nhãn
- }
- try {
- recog.Train(imgs, labels); //huấn luyện
- recog.Write(RECOG_FILE); //lưu file huấn luyện
- } catch {
- }
- isTraining = false;
- MessageBox.Show("Done retraining");
- }
- void Button1Click(object sender, EventArgs e) //chụp hình ảnh
- {
- if (faceOnly != null)
- try {
- pictureBox2.Image = faceOnly.Bitmap;
- capturedFace = faceOnly;
- } catch {
- }
- }
- void GroupBox2Enter(object sender, EventArgs e)
- {
- }
- void Button2Click(object sender, EventArgs e)
- {
- sendToArduino("alert=5;");
- }
- void ComboBox1SelectedIndexChanged(object sender, EventArgs e)
- {
- }
- void reloadData()
- {
- currentUser.Items.Clear();
- if (Directory.Exists(FACE_DIR)) {
- foreach (var user in Directory.GetDirectories(FACE_DIR)) { //đọc danh sách người có trong thư mục faces
- print(user);
- var userName = Path.GetFileName(user);
- currentUser.Items.Add(userName);
- currentUser.Text = userName;
- }
- } else {
- MessageBox.Show("Không có dữ liệu!");
- }
- retrain();
- }
- void saveData()
- {
- File.WriteAllText(ALLOWED_FILE, allowedUsers.Text);
- }
- void RefreshButtonClick(object sender, EventArgs e)
- {
- reloadData();
- saveData();
- }
- void TextBox1TextChanged(object sender, EventArgs e)
- {
- }
- void CheckFaceClick(object sender, EventArgs e)
- {
- startCheckingFace();
- }
- void loadAllow()
- {
- allAllowed = allowedUsers.Text.Split(',');
- for (int i = 0; i < allAllowed.Length; i++) {
- allAllowed[i] = allAllowed[i].Trim();
- }
- }
- void AllowedUsersTextChanged(object sender, EventArgs e)
- {
- loadAllow();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement