เขียนโปรแกรมตรวจจับจำนวนใบหน้าคน OpenCV Haar Cascades โดยใช้ python
Supapon Rabiebpo
Posted on April 9, 2023
ในการตรวจจับใบหน้า (face detection) ด้วย AI สามารถใช้ไลบรารีต่าง ๆ ได้ เช่น face_recognition, OpenCV, dlib และอื่น ๆ ซึ่งได้รับความนิยมมากในงาน Computer Vision และ Deep Learning และยังมีประโยชน์ที่ช่วยให้เราสามารถตรวจจับใบหน้าจากกล้องได้ด้วย
บทความนี้จะแนะนำไอเดียการตรวจจับใบหน้าง่าย ๆ ด้วยการตรวจจับหน้าคนผ่านรูปภาพและกล้องจากคอมพิวเตอร์ ด้วยไลบรารี Haar Cascades ของ Opencv โดยใช้ python
ทั้งนี้ Haar Cascades เป็นเพียง ไลบรารีที่ถูกเทรนมาเพื่อตรวจจับ object , face และอื่น ๆ ซึ่งจะไม่สามารถระบุชนิดหรือบุคคลของแต่ละใบหน้า และ สิ่งของแต่ละชนิดได้
ไอเดียแรก คือตรวจจับจำนวนใบหน้าจากรูปภาพ
ก่อนจะไปเริ่มขั้นตอนแรก ให้เราเลือกภาพที่มีใบหน้าคนมา 1 ภาพเพื่อใช้ในการตรวจจับใบหน้าก่อน
ถ้าเลือกได้แล้วก็ไปดูขั้นตอนแรกกันเลย
ขั้นตอนที่ 1 import Modul cv2 และ matplotlib.pyplot ก่อน
import cv2 as cv2
import matplotlib.pyplot as plt
ขั้นตอนที่ 2 โหลดไลบรารี haarcascade เพื่อให้สามารถใช้คลาส CascadeClassifier ในการโหลดไฟล์โมเดลที่ถูกเทรนให้สามารถตรวจจับใบหน้าคนมาแล้ว
# Load the cascade
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
ต่อมาสิ่งที่จะขาดไปไม่ได้เลยคือ นำเข้ารูปภาพที่เราต้องการตรวจจับใบหน้าและอ่านรูปภาพซึ่งสามารถทำได้ตามขั้นตอนที่ 3
ขั้นตอนที่ 3 นำเข้าและอ่านรูปภาพ
ในขั้นตอนนี้ต้องระวังเรื่อง file path ด้วยนะถ้าโปรแกรมหาภาพไม่เจอ ก็จะทำการตรวจจับใบหน้าไม่ได้นะ😓
# Read the input image
img = cv2.imread(r"--file path--")
เมื่ออ่านรูปภาพเรียบร้อยเราก็สามารถตรวจจับใบหน้าได้แล้ว สามารถทำตามขั้นตอนที่ 4 ได้เลย
ขั้นตอนที่ 4 ทำการตรวจจับใบหน้าจากรูปภาพด้วย ฟังก์ชัน detectMultiScale
# Detect faces
faces = face_cascade.detectMultiScale(img,1.1,5)
ซึ่งในการใช้ฟังก์ชัน detectMultiScale จำเป็นจะต้องกำหนดค่าพารามิเตอร์ด้วย คือ
- img รูปภาพที่เราต้องการจะตรวจจับ
- scaleFactor ขนาดที่ใช้ในการสกัดรูปภาพ
- minNeighbors ตรวจสอบรอบๆของพิกัดเพื่อลดปัญหา false positives
ขั้นตอนที่ 5 ทำการวาดช่องสี่เหลี่ยมรอบใบหน้าที่ตรวจจับได้ และ นับจำนวนใบหน้าที่ทำการตรวจจับได้จากการวาดช่องสี่เหลี่ยม
# Draw bounding box around the faces
countFace = 0
for (x, y, w, h) in faces:
rect = cv2.rectangle(img, (x, y), (x+w, y+h), (2, 150, 255), 2)
countFace = countFace + 1
num = str(countFace)
cv2.putText(rect, num, (x, y-5), cv2.FONT_ITALIC, 0.5, (2, 150, 255), 2)
ฟังก์ชันที่ใช้ในขั้นตอนที่ 5 เนี้ยจะมีการกำหนดค่าพารามิเตอร์ดังนี้
1.ฟังก์ชัน cv2.rectangle
- img เป็นรูปภาพที่เราจะวาดช่องสี่เหลี่ยมลงไป
- (x,y) เป็นค่าจุดเริ่มต้นวาดช่องสี่เหลี่ยม
- (x+w, y+h) เป็นจุดสุดท้ายของการวาดสี่เหลี่ยม
- (2, 150, 255) กำหนดค่าสีของช่องสี่เหลี่ยม
- 2 ค่าความหนาของเส้นสี่เหลี่ยมที่เราจะวาด
2.ฟังก์ชัน cv2.putText
- rect ภาพที่เราจะใส่ตัวอักษรไป
- num ข้อความที่เราจะเขียนลงไป ซึ่งจะต้องเป็น string เพราะงั้นเลยต้องทำการแปลงจาก int string ก่อนด้วย str(countFace)
- (x,y-10) เป็นตำแหน่งที่ต้องการให้ตัวอักษรอยู่
- cv2.FONT_ITALIC เป็นรูปแบบตัวหนังสือ
- 0.5 เป็นขนาดตัวอักษร
- (2, 150, 255) เป็นสีของตัวอักษร
- 2 เป็นความหนาของตัวอักษร
ขั้นตอนที่ 6 โค้ดส่วนนี้จะเป็นการแสดงค่าจำนวนใบหน้าที่ตรวจจับได้
# Showing number of faces detected in the image
print(len(faces),"faces detected!")
และแล้วก็มาถึงขั้นตอนการแสดงผลลัพธ์ที่เราทำมาทั้งหมด
ขั้นตอนที่ 7 แสดงรูปภาพผลลัพธิ์การตรวจจับจำนวนใบหน้า
# Plotting the image with face detected
# picture size
plt.figure(figsize=(10,10))
#show Picture detected
cv2.imshow('Results',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
ฟังก์ชันที่ใช้ในขั้นตอนที่ 7 เนี้ยจะมีการกำหนดค่าพารามิเตอร์ดังนี้
1.ฟังก์ชัน plt.figure(figsize=(10,10))
ฟังก์ชันนี้เป็นฟังก์ชันที่ใช้ในการวาดกราฟ และวาดภาพ ซึ่งการใช้ figure ทำให้เราสามารถกำหนดขนาดรูปภาพได้ด้วย
- (10,10) กำหนดขนาดรูปภาพที่ต้องการวาด
2.ฟังก์ชัน cv2.imshow('Results',img)
- Results' ชื่อหน้าต่างการแสดงผล จะต้องเป็น string เท่านั้น
- img ภาพที่ต้องการแสดงผล
ผลการตรวจจับจำนวนใบหน้าที่ได้ก็จะแสดงผลได้ตามรูปภาพตัวอย่างเลยย
ภาพแรก เป็นการแสดงผลจำนวนใบหน้าที่ตรวจจับได้ จากขั้นตอนที่ 6
และภาพนี้ก็ เป็นผลของภาพวาดช่องสี่เหลี่ยมแสดงจำนวนใบหน้าที่ตรวจจับได้ จากขั้นตอนที่ 7
แค่นี้เราก็ได้รูปที่ภาพตรวจจับจำนวนใบหน้าจากรูปภาพได้แล้ววว
เป็นไงง๊ายง่ายยย✨
ไอเดียที่สอง ตรวจจับจำนวนใบหน้าด้วยกล้อง จะมีการเขียนโค้ดที่ต่างกันนิดหน่อย อยากรู้ว่าทำยังไงก็ไปดูโค้ดกันเลยย
ขั้นตอนที่ 1 import Modul cv2 และ matplotlib.pyplot และ โหลดไลบรารี haarcascade
import cv2 as cv2
import matplotlib.pyplot as plt
# Load the cascade
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
ขั้นตอนที่ 2 เรียกใช้ฟังก์ชัน cv2.VideoCapture เพื่อเปิดกล้อง
# open camera
cap = cv2.VideoCapture(0)
ซึ่งค่า 0 ที่ใส่เข้ามาหมายถึงการเรียกใช้งาน กล้องหน้า
ขั้นตอนที่ 3 ขั้นตอนนี้จะเป็นการตรวจจับใบหน้าจาก frame ซึ่งจะเป็นลูปตรวจจับจำนวนใบหน้าที่อยู่ในกล้องเฟรมต่อเฟรม และทำการวาดช่องสี่เหลี่ยมพร้อมทำการระบุจำนวนที่จับได้ด้วย
while True:
# read frame
ret, frame = cap.read()
# detect face from cmera frame
faces = face_cascade.detectMultiScale(frame, scaleFactor=1.3, minNeighbors=5)
countFace = 0
# drawing rectangle
for (x, y, w, h) in faces:
rect = cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
countFace = countFace + 1
num = str(countFace)
cv2.putText(rect, num, (x, y-5), cv2.FONT_ITALIC, 0.5, (2, 150, 255), 2)
# show image
cv2.imshow('Face Detection', frame)
# press ESC to close camera tap
if cv2.waitKey(1) == 27:
break
# close camera and tap
cap.release()
cv2.destroyAllWindows()
รายละเอียดค่าพารามิตเตอร์ของฟังก์ชันต่างๆได้อธิบายไปแล้วในไอเดียที่ 1 ขั้นตอนที่ 4-5 แต่จะอธิบายเพิ่มเติมในส่วนของ
ฟังก์ชัน cv2.waitKey(1) ซึ่ง 1 หมายถึงการรับค่าเพียงค่าเดียวจากผู้ใช้ ซึ่ง ณ ที่นี้ใช้ในการจบการทำงานของกล้องนั่นเอง
ผลลัพธิ์ที่ได้ก็แบบนี้เลย
reference
https://dev.to/saharshlaud/face-detection-in-just-15-lines-of-code-ft-python-and-opencv-37ci
Posted on April 9, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.