เช็คชื่ออัตโนมัติด้วยระบบจดจำใบหน้า : Automatic Attendance 

ผู้เขียนบทความ
นาย ธีรพล เถาว์ชู COE #16
นาย อนันต์วุฒิ ธรรมสุวรรณ COE #16
นาย วิวรรธน์ เจริญมาศ COE #16
คณะ : วิศวกรรมศาสตร์ สาขา : วิศวกรรมคอมพิวเตอร์
วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง

1.ความเป็นมา

ในปัจจุบันเทคโนโลยีเข้ามามีบทบาทในใช้ชีวิตประจำวันอย่าง ทั้งในเรื่องของการแพทย์ เรื่องการเรียนการศึกษา หรือแม้กระทั่งในการอำนวยความสะดวกต่าง ๆ และในปัจจุบันนี้ได้มี ระบบ Face Recognition และ Deep face ที่เป็นเทคโนโลยีที่ใช้การวิเคราะห์และเปรียบเทียบใบหน้าของบุคคลเพื่อตรวจสอบหรือยืนยันตัวตนของพวกเขาเนื่องด้วยการเรียนการสอนนั้นอาจจะเสียเวลาเป็นอย่างในการเช็ครายชื่อของนักเรียน นักศึกษาภายในห้องเรียน และต้องเสียเวลามากขึ้นอีกหาว่าห้องเรียนนั้นมีจำนวนนักเรียน นักศึกษาเป็นจำนวนมากจากปัญหาดั่งกล่าวอาจจะมีส่วนส่งผลกระทบหรืออาจจะเป็นอุปสรรค์ต่อการเรียนการสอนได้ 
ดังนั้นทางคณะกลุ่มได้เล็งเห็นปัญหาจึงได้ระดมความคิดและได้จัดทำมินิโปรเจคชื่อ เช็คชื่ออัตโนมัติด้วยใบหน้า  ( Automatic Face Recognition Attendance ) เพื่อแก้ไขปัญหาการเสียเวลาเช็ครายชื่อนักเรียน นักศึกษา พัฒนาเทคโนโลยีที่อำนวยความสะดวกเพื่อยกระดับการเรียนการสอนขึ้นอีกขั้น และเพื่อการศึกษาการทำงานของ ภาษาpython และ opencv ในการำสร้างระบบ Face Recognition และ Deep Face

2.วัตถุประสงค์

2.1 เพื่อทำการเช็คชื่อนักเรียน นักศึกษาในชั้นเรียน
2.2 เพื่อศึกษาการใช้ ภาษา python และ AI ในการสร้างระบบ Face Recognition 

3 ขอบเขตการทำงาน 

3.1 ให้ opencv เก็บภาพและจดจำใบหน้าสมาชิกในห้องเรียน 
3.4 นำใบหน้าที่ได้มาทำการเช็คชื่อ 

4 ประโยชน์ที่ได้รับ 

2.1 ได้ประยุกต์ใช้ ภาษา python และ opencv ในการสร้างระบบ Face Recognition
2.2 ได้โปรเจคที่สามารถนำมาใช้เช็คชื่อนักเรียน นักศึกษา

5.ความรู้ที่เกี่ยวข้อง

5.1. cv2 (OpenCV) – OpenCV เป็นไลบรารีสำหรับการประมวลผลภาพและวิดีโอที่มีฟังก์ชันหลากหลาย โปรแกรมนี้ใช้ OpenCV เพื่อรับภาพจากกล้องหรือไฟล์วิดีโอ การประมวลผลภาพที่ได้มา และการวาดจุดที่ MediaPipe ตรวจจับได้ลงบนเฟรมภาพ รวมถึงการแสดงผลภาพแบบเรียลไทม์ ตัวอย่างการใช้งาน เช่น การวาดจุดตำแหน่งของข้อนิ้วและปลายนิ้วลงบนภาพวิดีโอ และการติดตามการเคลื่อนไหวของมือเพื่อนำไปแปลเป็นสัญลักษณ์ภาษามือ

5.2 numpy คือ ไลบรารีที่ทรงพลังสำหรับการคำนวณเชิงตัวเลขและการจัดการข้อมูลในรูปแบบของอาเรย์ (Array) โปรแกรมนี้ใช้ numpy ในการจัดเก็บและคำนวณค่าตำแหน่งของจุดบนมือที่ได้รับจาก MediaPipe ฟังก์ชันของ numpy เช่น การคำนวณค่าระยะห่างระหว่างจุด การคำนวณมุมหรือการคำนวณเชิงเวกเตอร์ ช่วยให้โปรแกรมสามารถวิเคราะห์ตำแหน่งและลักษณะการเคลื่อนไหวของมือได้อย่างแม่นยำและรวดเร็ว

5.3. os Python คือคำสั่งนำเข้า module OS มาในโค้ดภาษา Python เพื่อทำงานกับระบบปฏิบัติ หรือ operating system โดย module OS จะมีฟังก์ชันต่างๆ ที่เกี่ยวข้องกับ OS สามารถเขียนโปรแกรม

5.4 SheetDB คือ บริการที่ช่วยเชื่อมต่อ Google Sheets กับแอปพลิเคชันต่างๆ ผ่าน API ทำให้สามารถเข้าถึงและจัดการข้อมูลใน Google Sheets ได้อย่างสะดวก เช่น การอ่าน/เขียนข้อมูลจากภายนอกโดยไม่ต้องใช้ Google Sheets UI หรือใช้สูตรในตัวเอง เป็นเครื่องมือที่เหมาะสำหรับการสร้างแอปพลิเคชันที่ต้องการเชื่อมโยงกับข้อมูลในตาราง Google Sheets.

5.5 requests คือ ไลบรารีใน Python ที่ใช้สำหรับการส่งคำขอ HTTP (เช่น GET, POST) ไปยังเว็บไซต์หรือ API เพื่อดึงข้อมูลหรือส่งข้อมูล โดยที่โค้ดสั้นและใช้งานง่าย ช่วยให้การทำงานกับการเชื่อมต่อเว็บเป็นไปได้อย่างสะดวกและมีประสิทธิภาพ เช่น การดึงข้อมูลจากเว็บหรือส่งข้อมูลไปยังเซิร์ฟเวอร์

5.6 Threading คือ ไลบรารีที่ใช้ในการจัดการการทำงานแบบ หลายเธรด (multithreading) ซึ่งช่วยให้สามารถทำงานหลายๆ อย่างพร้อมกันในกระบวนการเดียว (process) โดยไม่ต้องเปิดหลายโปรแกรม ตัวอย่างเช่น การทำงานพร้อมกันของหลายฟังก์ชันหรือการดำเนินการที่ใช้เวลานาน เช่น การดาวน์โหลดไฟล์หลายๆ ไฟล์ หรือการประมวลผลข้อมูลในขณะที่รอการตอบกลับจากเซิร์ฟเวอร์

สรุป

โค้ดนี้จะเกี่ยวข้องกับการประมวลผลภาพจากกล้องหรือวิดีโอแบบเรียลไทม์ ซึ่งใช้ OpenCV ในการตรวจจับใบหน้าและเปรียบเทียบใบหน้า เพื่อทำการเช็คชื่อลงใน Google Sheet

6.การดำเนินงาน

โค้ดของการทำงานของโปรแกรมที่ใช้สำหรับการค้นหาข้อมูลจากฐานข้อมูลโดยการรับข้อความจากผู้ใช้ทั้งแบบพิมพ์และพูด

ส่วนหลักของโปรแกรม

import cv2
import numpy as np
import requests
import json
import os
import threading

data_student = {}  # ใช้เซ็ตเพื่อเก็บชื่อที่ไม่ซ้ำกัน

# กำหนด URL สำหรับ API ของ SheetDB
url = 'https://sheetdb.io/api/v1/gg8eyhjfthkjm'

# ฟังก์ชั่นเอาไว้หารูปภาพในรูปภาพอีกที (เหมาะกับไว้ทำบอทเกม , หารูปหน้าหรือพวกอื่นๆตำแหน่งจะแม่นขึ้น)
def find_face_in_frame(frame, template):
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)

    result = cv2.matchTemplate(frame_gray, template_gray, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, max_loc = cv2.minMaxLoc(result)
    
    # ปรับค่าละเอียดในการหาตำแหน่งของรูปให้มันตรงเป๊ะ หรือจะปรับต่ำกว่านี้ให้มันหาละเอียดแต่ใช้เวลานาน
    threshold = 0.6  # ปรับ threshold เป็น 0.7 เพื่อลด false positives
    if max_val > threshold:
        h, w = template.shape[:2]
        return True, max_loc, (max_loc[0] + w, max_loc[1] + h), max_val
    
    return False, None, None, None
def send_sheet(name):
    name_student = name.split(" ")[0]
    headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
     }
    data = {
        'data': [
            {
                'ชื่อ': name_student,
                'รหัส': name.split(" ")[1],
                '11/7/2024': "✅"
            }
        ]
    }
    response = requests.post('https://sheetdb.io/api/v1/gg8eyhjfthkjm', headers=headers, data=json.dumps(data))

# โฟลเดอร์ faces ไว้เก็บข้อมูลหน้าของแต่ละคน
face_folder = 'faces/'
facedata = {}

# เก็บพวกไฟล์รูปเข้า data เพื่อไปโชว์ใน Frame
for filename in os.listdir(face_folder):
    if filename.endswith('.jpg') or filename.endswith('.png'):
        # อ่านไฟล์รูปแล้วเก็บใน facedata
        facedata[filename.split('.')[0]] = cv2.imread(os.path.join(face_folder, filename))

# เชื่อมต่อกับกล้องเว็บแคม
wiwat_cap = cv2.VideoCapture(0)

# ตั้งค่าความละเอียด (ถ้าต้องการ)
wiwat_cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
wiwat_cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# เก็บข้อมูลใบหน้าที่ตรวจพบไว้ในลิสต์
detected_faces = []

# ลูปโชว์เฟรมเรื่อยๆ
while True:
    ret, frame = wiwat_cap.read()
    if not ret:
        break
    
    detected_faces.clear()  # ล้างข้อมูลใบหน้าที่ตรวจพบในแต่ละเฟรมใหม่
    
    # หาใบหน้าที่ตรงกับรูปที่เก็บไว้ในโฟลเดอร์ faces
    for name, template in facedata.items():
        jer_laew, top_left, bottom_right, confidence = find_face_in_frame(frame, template)
        
        # ถ้ามันเจอแล้ว และค่าความเชื่อมั่นมากกว่า 0.7
        if jer_laew and confidence > 0.72:
            # ตรวจสอบว่ามีใบหน้าอื่นที่ใกล้เคียงอยู่แล้วหรือไม่
            overlap = False
            for detected_name, detected_top_left, detected_bottom_right in detected_faces:
                # คำนวณระยะห่างระหว่างใบหน้าที่ตรวจพบ
                distance = np.linalg.norm(np.array(detected_top_left) - np.array(top_left))
                
                # ถ้าระยะห่างน้อยกว่า 50 แสดงว่าทับซ้อนกัน
                if distance < 50:
                    overlap = True
                    break

            # ถ้าไม่มีการทับซ้อน ให้เพิ่มใบหน้านี้เข้าไปในลิสต์และแสดงผล
            if not overlap:
                detected_faces.append((name, top_left, bottom_right))
                
                # ใส่กรอบเขียว ปรับสีได้ตามใจชอบตรง (0,255,0)
                cv2.rectangle(frame, top_left, bottom_right, (0, 255, 0), 2)

                # ใส่ข้อความที่เป็นชื่อเรา พร้อมกับ confidence
                name_studentzzz = name.split(" ")[0]
                print(name_studentzzz, f'{confidence:.2f}')
                if name_studentzzz not in data_student:
                    data_student[name_studentzzz] = True

                    thread = threading.Thread(target=send_sheet, args=(name,))
                    thread.start()

                    cv2.putText(frame, f"{name} {confidence:.2f}", (top_left[0], top_left[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
                else:
                    # print("KUY", name)
                    cv2.putText(frame, f"{name} {confidence:.2f}", (top_left[0], top_left[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
                    pass
            else:
                printf('{confidence:.2f}')


    # แสดงหน้าต่างโปรแกรมเอาไว้โชว์ Output ที่มันออกมา
    cv2.imshow('Webcam', frame)

    # ถ้ากด Q คือออกโปรแกรม
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# ปิดการใช้งานกล้องและหน้าต่างแสดงผล
wiwat_cap.release()
cv2.destroyAllWindows()

7.วิธีการใช้งานโปรแกรม

วิธีการใช้งานโปรแกรม
7.1. เปิด cmd
7.2. พิมพ์ py espcam.py
7.3. ใช้งานได้เลย
7.4. เข้ากล้องเพื่อสแกนหน้าและเช็คชื่อ

8.การทดลอง

9.เทคนิกการประยุคเพื่อเพิ่มประสิทธิภาพมากขึ้น

แนะนำให้ใช้ Machine Learning เพื่อเพิ่มประสิทธิภาพในการจับหน้าใหัละเอียดและเพื่อให้มีปัญหาในการใช้งานน้อยลง ทำให้แม่นยำขึ้น และอาจจะมีการทำ database แบบ Cloud เพื่อใช้ในการเก็บข้อมูลเพื่อเชื่อมต่อกับตัวจับภาพจากกล้องตัวอื่นๆเพื่อดึงข้อมูลและนำข้อมูลมารวบรวมได้ในที่เดียว

10.สรุปผลและข้อเสนอแนะ

สรุปผล
จากการทดลองพบว่า เช็คชื่ออัตโนมัติด้วยระบบจดจำใบหน้า : Automatic Attendance  นั้นสามารถทำงานได้อย่างถูกต้อง สามารถตรวจจับใบหน้าและทำการเช็ค ชื่อนักเรียน-นักศึกษาได้ แต่ยังคงมีความผิดพลาดเล็กน้อย เช่น จับหน้าไม่ค่อยติด และ เมื่อส่ง data ไป sheet จะทำให้โปรแกรมค้างไปชั่วขณะ
ข้อเสนอแนะ
– ก่อนนำภาพมาประมวลผล ควรปรับปรุงคุณภาพภาพให้ดีขึ้น เช่น การปรับความสว่าง ความคมชัด
– เพิ่มข้อมูลในการฝึกสอนให้มากขึัน เพื่อให้มีความแม่นยำมากขึ้น
– อาจจะเพิ่มการเเจ้งเตือนเมื่อทำการเช็คชื่อเสร็จเเล้ว
– เพิ่ม Deep learning เพื่อเพิ่มความแม่นยำในการวิเคราะห์ใบหน้า

11. ข้อมูลอ้างอิง

11.1 Python | เขียนโปรแกรมถ่ายภาพหน้าจอ โดยใช้ OpenCV/Numpy และ mss : https://medium.com/@pattanapong.sriph/python-
11.2 อยากมี API เป็นของตัวเอง สร้างได้ง่าย ๆ ด้วย Google Sheet :
https://www.borntodev.com/2022/09/23/
11.3 สรุปพื้นฐาน python :
https://medium.com/@teeppiphat/

วิดีโอการทำงานของระบบโปรแกรมแปลภาษามือเบื้องต้นด้วยการประมวณผลภาพ

You may also like...

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *