ทำการยืนยันตัวตนผ่านใบหน้า โดยใช้ face recognition
Published: 2024-04-16 14:10:58

ในทุกวันนี้เราอยู่ในสังคมที่มีผู้คนมากหน้าหลายตา ถ้าเราต้องการจำแนกใบหน้าของใครสักคนเพื่อที่จะระบุได้ว่าเขาคนนั้นเป็นใครกันแน่นั้น ถ้าเป็นเมื่อก่อนเราอาจจะใช้วิธีในการเปรียบเทียบใบหน้าจากรูปภาพที่เรามีหลายๆรูปด้วยสายตา ซึ่งถือเป็นวิธีที่ใช้เวลายาวนานและอาจเกิดข้อพลาดได้เมื่อจ้องระบุตัวตนพร้อมกันหลายๆคน โดยในครั้งนี้เราจะมาแนะนำวิธีที่เรียบง่ายและมีความแม่นยำในการตรวจสอบ นั่นคือการใช้ face recognition

face recognition เป็นไลบรารีที่ใช้งานเพื่อระบุและจดจำใบหน้าบนรูปภาพหรือวิดีโอด้วย Python ถูกสร้างขึ้นโดยใช้การจดจำใบหน้าที่ล้ำสมัยที่ใช้การเรียนรู้แบบ Deep Learning อย่าง dlib ซึ่งเป็นโมเดลที่มีความแม่นยำสูงถึง 99.38% บน Labeled Faces ในเกณฑ์มาตรฐานของ Wild

face recognition นั้นมีการทำงานที่หลากหลายให้เลือกใช้ ซึ่งที่เราจะนำมาใช้งานในครั้งนี้คือการ "การยืนยันใบหน้าในรูปภาพ" นั่นเอง โดยในการใช้งานครั้งนี้เราสามารถทดลองใช้งานและรันการทำงานได้เลยผ่าน Google Colab (จำเป็นจะต้องใช้รันไทม์แบบ GPU สำหรับการ import face_recognition)

## ขั้นตอนที่ 1 ติดตั้ง dlib และโมเดล face recognition
ทำการติดตั้งไลบรารี dlib โดยการ clone git ดังนี้ 
```
!git clone https://github.com/davisking/dlib.git
```
จากนั้นทำการสร้างไดเร็กทอรี build แล้วเรียกใช้งาน cmake ด้วยโค้ดต่อไปนี้
```
%cd dlib
!mkdir build; cd build; cmake ..; cmake --build .
```
ทำการติดตั้ง face recognition โดยใช้ไฟล์ setup.py
```
!git clone https://github.com/ageitgey/face_recognition.git
%cd  /content/face_recognition
!python setup.py install
```
ต่อมาทำการติดตั้งโมเดล face recognition
```
%cd ..
!pip install git+https://github.com/ageitgey/face_recognition_models
!pip install face_recognition
```
## ขั้นตอนที่ 2 นำเข้ารูปภาพ
ทำการสร้างไดเร็กทอรี images แล้วทำการดาวน์โหลดรูปภาพจากเว็บไซต์ที่มีรูปภาพที่เราต้องการ โดยระบุที่อยู่ของรูปภาพในเว็บไซต์ พร้อมทั้งระบุชื่อไฟล์ของรูปภาพที่ดาวน์โหลดมาดังนี้
```
!mkdir images
!wget https://www.unlockmen.com/wp-content/uploads/2021/07/hideo-kojima-tribeca-games-festival.jpg -O /content/images/Kojima.jpg
!wget https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Norman_Reedus_2016_%28cropped%29.jpg/220px-Norman_Reedus_2016_%28cropped%29.jpg -O /content/images/Norman.jpg
!wget https://mpics.mgronline.com/pics/Images/564000008778201.JPEG -O /content/images/two_people.jpg
```
สามารถตรวจสอบได้ว่ารูปภาพที่เราดาวน์โหลดจากเว็บไซต์นั้นถูกต้องหรือไม่ ด้วยโค้ดดังนี้
```
import matplotlib.pyplot as plt
import os
filenames = [os.path.join('/content/images',x) for x in os.listdir("/content/images/")]
print(filenames)
for filename in filenames:
    img = plt.imread(filename)
    plt.imshow(img)
    plt.axis('off')
    plt.show()
```
ผลที่ได้
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6we3dg7ytwsaoaeukms.png)
## ขั้นตอนที่ 3 ทำการใช้งาน face recognition
ในขั้นตอนนี้เป็นการนำโมเดล face recognition มาใช้กับรูปภาพที่เราต้องการระบุตัวตนผ่านใบหน้า โดยมีขั้นตอนดังนี้(สามารถคัดลอกโค้ดมาวางต่อกันได้เลย)
1.โหลดรูปภาพตัวอย่างใบหน้าที่เราต้องการเพื่อเป็นตัวอย่างในเรียนรู้สำหรับการจดจำใบหน้า และกำหนดชื่อของเจ้าของใบหน้าตามลำดับ
```
import face_recognition
from PIL import Image, ImageDraw
import numpy as np

# This is an example of running face recognition on a single image
# and drawing a box around each person that was identified.

# Load a sample picture and learn how to recognize it.
kojima_image = face_recognition.load_image_file(os.path.join('/content/images',"Kojima.jpg"))
kojima_face_encoding = face_recognition.face_encodings(kojima_image)[0]

# Load a second sample picture and learn how to recognize it.
norman_image = face_recognition.load_image_file(os.path.join('/content/images',"Norman.jpg"))
norman_face_encoding = face_recognition.face_encodings(norman_image)[0]

# Create arrays of known face encodings and their names
known_face_encodings = [
    kojima_face_encoding,
    norman_face_encoding
]
known_face_names = [
    "Hideo Kojima",
    "Norman Reedus"
]
```
2.นำเข้ารูปภาพเป้าหมายที่เราจะใช้ระบุตัวตนภายในภาพและทำการคำนวณเวกเตอร์สำหรับระบุใบหน้า จากนั้นทำการแปลงไฟล์ภาพเป็น PIL Image แล้วสร้าง object เพื่อวาดกรอบสีรอบบริเวณใบหน้า
```
# Load an image with an unknown face
unknown_image = face_recognition.load_image_file(os.path.join('/content/images',"two_people.jpg"))

# Find all the faces and face encodings in the unknown image
face_locations = face_recognition.face_locations(unknown_image)
face_encodings = face_recognition.face_encodings(unknown_image, face_locations)

# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
# See http://pillow.readthedocs.io/ for more about PIL/Pillow
pil_image = Image.fromarray(unknown_image)
# Create a Pillow ImageDraw Draw instance to draw with
draw = ImageDraw.Draw(pil_image)
```
3.ทำฟังก์ชัน loop สำหรับการนำรูปภาพเป้าหมายมาเปรียบเทียบกับรูปภาพตัวอย่างใบหน้าเพื่อตรวจสอบว่าเป็นใบหน้าที่รู้จักหรือไม่ หากตรงกับใบหน้าที่รู้จักจะทำการสร้างกรอบสีรอบบริเวณใบหน้าและเขียนชื่อกำกับเอาไว้
```
# Loop through each face found in the unknown image
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
    # See if the face is a match for the known face(s)
    matches = face_recognition.compare_faces(known_face_encodings, face_encoding)

    name = "Unknown"

    # If a match was found in known_face_encodings, just use the first one.
    # if True in matches:
    #     first_match_index = matches.index(True)
    #     name = known_face_names[first_match_index]

    # Or instead, use the known face with the smallest distance to the new face
    face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
    best_match_index = np.argmin(face_distances)
    if matches[best_match_index]:
        name = known_face_names[best_match_index]

    # Draw a box around the face using the Pillow module
    draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))

    # Draw a label with a name below the face
    text_width, text_height = draw.textsize(name)
    draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
    draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))


# Remove the drawing library from memory as per the Pillow docs
del draw
```

## ขั้นตอนที่ 4 แสดงผล
ทำการบันทึกรูปภาพ PIL Image ให้เป็นไฟล์ jpg แล้วทำการแสดงผลรูปภาพผลลัพธ์ของการระบุใบหน้า
```
from IPython.display import Image as IImage
from PIL import Image

# Save the PIL image
pil_image.save("result3.jpg")

# Display the saved image
IImage(filename='result3.jpg', width=800)
```
ผลที่ได้ 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vwm6thubw15h1sl5ec9.png)

## สรุปผล
จากผลลัพธ์ที่ได้เราจะเห็นว่า face recognition สามารถจำแนกและระบุตัวตนของบุคคลภายในรูปภาพได้อย่างแม่นยำและถูกต้อง โดยเราสามารถนำ face recognition มาประยุกต์ใช้ในงานต่างๆได้อย่างหลากหลายอาทิเช่น ระบบรักษาความปลอยภัยในการตรวจสอบผู้คนเข้า-ออกสถานที่ หรือ การจดจำใบหน้าผู้ใช้สำหรับการเข้าสู่ระบบ

## References

- face recognition : https://github.com/ageitgey/face_recognition.git

- dlib : https://github.com/davisking/dlib.git