AI Hunter
Member
Chấm công bằng vân tay đã xưa rồi, đặc biệt là trong thời đại cần hạn chế tiếp xúc. Trong bài viết này, chúng ta sẽ xây dựng một hệ thống điểm danh "không chạm" (touchless) thông minh bằng Python:
Đây là bước "khó nhằn" nhất vì thư viện nhận diện khuôn mặt cần trình biên dịch C++. Hãy làm đúng thứ tự sau:
Bước 1: Cài đặt CMake (Bắt buộc để cài dlib).
Bước 2: Cài đặt các thư viện chính.
Bạn hãy tạo một thư mục tên là
Trong đó, hãy bỏ ảnh thẻ của những người cần điểm danh vào. Tên file chính là tên hiển thị.
Ví dụ:
Dưới đây là đoạn code Python hoàn chỉnh. Tôi đã thêm logic để tránh việc máy chấm công liên tục (Spam) và module giọng nói.
Sau khi chạy chương trình:
1. Webcam bật lên.
2. Bạn đưa mặt vào, máy vẽ khung xanh và hiện tên.
3. Loa phát ra: "Xin chào Elon Musk...".
4. File
Đây là nền tảng tuyệt vời để bạn phát triển thêm các tính năng như: Mở cửa tự động (kết nối Arduino), Gửi báo cáo về Telegram, v.v.
- Nhận diện khuôn mặt nhân viên qua Webcam.
- Tự động ghi giờ check-in vào file Excel/CSV.
- Đặc biệt: Máy tính sẽ chào tên nhân viên bằng giọng nói (như trong phim khoa học viễn tưởng).
1. Cài đặt môi trường (Quan trọng)
Đây là bước "khó nhằn" nhất vì thư viện nhận diện khuôn mặt cần trình biên dịch C++. Hãy làm đúng thứ tự sau:
Bước 1: Cài đặt CMake (Bắt buộc để cài dlib).
Mã:
pip install cmake
Bước 2: Cài đặt các thư viện chính.
Mã:
pip install dlib face_recognition opencv-python pandas pyttsx3
2. Chuẩn bị dữ liệu
Bạn hãy tạo một thư mục tên là
images cùng cấp với file code.Trong đó, hãy bỏ ảnh thẻ của những người cần điểm danh vào. Tên file chính là tên hiển thị.
Ví dụ:
- `images/Elon_Musk.jpg`
- `images/Son_Tung_MTP.jpg`
3. Triển khai Code (Full Source)
Dưới đây là đoạn code Python hoàn chỉnh. Tôi đã thêm logic để tránh việc máy chấm công liên tục (Spam) và module giọng nói.
Python:
import cv2
import face_recognition
import os
import datetime
import pyttsx3
import pandas as pd
# --- CẤU HÌNH ---
path = 'images' # Thư mục chứa ảnh mẫu
attendance_file = 'diem_danh.csv'
# Khởi tạo giọng nói
engine = pyttsx3.init()
engine.setProperty('rate', 150) # Tốc độ nói
def speak(text):
"""Máy phát âm thanh"""
engine.say(text)
engine.runAndWait()
def load_images(path):
"""Load ảnh và mã hóa khuôn mặt từ thư mục"""
images = []
classNames = []
myList = os.listdir(path)
print(f"📂 Đang load dữ liệu từ {path}...")
for cl in myList:
curImg = cv2.imread(f'{path}/{cl}')
images.append(curImg)
classNames.append(os.path.splitext(cl)[0]) # Lấy tên file bỏ đuôi .jpg
encoded_list = []
for img in images:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Mã hóa khuôn mặt (chuyển thành vector)
try:
encode = face_recognition.face_encodings(img)[0]
encoded_list.append(encode)
except IndexError:
print(f"⚠️ Không tìm thấy mặt trong ảnh: {path}/{cl}")
print(f"✅ Đã học xong {len(encoded_list)} khuôn mặt.")
return encoded_list, classNames
def mark_attendance(name):
"""Ghi log vào file CSV"""
# Nếu file chưa tồn tại thì tạo mới
if not os.path.isfile(attendance_file):
with open(attendance_file, 'w') as f:
f.writelines('Name,Time,Date')
# Đọc dữ liệu cũ để tránh trùng lặp trong cùng 1 ngày (hoặc phiên)
with open(attendance_file, 'r+') as f:
myDataList = f.readlines()
nameList = []
for line in myDataList:
entry = line.split(',')
nameList.append(entry[0])
# Nếu chưa điểm danh thì ghi vào
if name not in nameList:
now = datetime.datetime.now()
dtString = now.strftime('%H:%M:%S')
dateString = now.strftime('%d/%m/%Y')
f.writelines(f'\n{name},{dtString},{dateString}')
print(f"✅ Đã điểm danh: {name}")
speak(f"Xin chào {name}, chúc bạn một ngày tốt lành!")
return True # Đánh dấu là mới điểm danh
return False # Đã điểm danh rồi
# --- MAIN PROGRAM ---
encodeListKnown, classNames = load_images(path)
print("📷 Đang khởi động Webcam...")
cap = cv2.VideoCapture(0) # 0 là ID của Webcam
while True:
success, img = cap.read()
if not success:
print("Không mở được Camera")
break
# Thu nhỏ ảnh còn 1/4 để xử lý nhanh hơn (Tăng FPS)
imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25)
imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)
# Tìm vị trí khuôn mặt trong khung hình hiện tại
facesCurFrame = face_recognition.face_locations(imgS)
encodesCurFrame = face_recognition.face_encodings(imgS, facesCurFrame)
# So sánh từng khuôn mặt tìm thấy với dữ liệu đã học
for encodeFace, faceLoc in zip(encodesCurFrame, facesCurFrame):
matches = face_recognition.compare_faces(encodeListKnown, encodeFace, tolerance=0.5)
faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)
# Lấy index của khuôn mặt giống nhất
import numpy as np
matchIndex = np.argmin(faceDis)
if matches[matchIndex]:
name = classNames[matchIndex].upper()
# Vẽ khung hình chữ nhật quanh mặt
y1, x2, y2, x1 = faceLoc
y1, x2, y2, x1 = y1 * 4, x2 * 4, y2 * 4, x1 * 4 # Nhân 4 vì lúc nãy resize 0.25
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.rectangle(img, (x1, y2 - 35), (x2, y2), (0, 255, 0), cv2.FILLED)
cv2.putText(img, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
# Thực hiện điểm danh & Chào
mark_attendance(name)
cv2.imshow('Webcam - Face Recognition', img)
# Nhấn 'q' để thoát
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
4. Giải thích cơ chế
- Face Encoding: Máy tính sẽ đo đạc các tỉ lệ trên khuôn mặt (khoảng cách mắt, mũi, miệng...) và biến nó thành một chuỗi 128 con số.
- Tolerance (Độ dung sai): Trong dòng code
compare_faces(..., tolerance=0.5), số 0.5 là độ chính xác. Số càng nhỏ càng khắt khe, số càng lớn càng dễ nhận diện nhầm. - Resize 0.25: Mẹo nhỏ này giúp FPS của Camera mượt mà hơn, vì xử lý ảnh nhỏ tốn ít tài nguyên CPU hơn.
5. Kết quả
Sau khi chạy chương trình:
1. Webcam bật lên.
2. Bạn đưa mặt vào, máy vẽ khung xanh và hiện tên.
3. Loa phát ra: "Xin chào Elon Musk...".
4. File
diem_danh.csv xuất hiện dữ liệu chấm công.Đây là nền tảng tuyệt vời để bạn phát triển thêm các tính năng như: Mở cửa tự động (kết nối Arduino), Gửi báo cáo về Telegram, v.v.
Bài viết liên quan