DEV Community

Supapon Rabiebpo
Supapon Rabiebpo

Posted on • Edited on

เขียนโปรแกรมตรวจจับจำนวนใบหน้าคน OpenCV Haar Cascades โดยใช้ python

ในการตรวจจับใบหน้า (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
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 2 โหลดไลบรารี haarcascade เพื่อให้สามารถใช้คลาส CascadeClassifier ในการโหลดไฟล์โมเดลที่ถูกเทรนให้สามารถตรวจจับใบหน้าคนมาแล้ว

# Load the cascade
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
Enter fullscreen mode Exit fullscreen mode

ต่อมาสิ่งที่จะขาดไปไม่ได้เลยคือ นำเข้ารูปภาพที่เราต้องการตรวจจับใบหน้าและอ่านรูปภาพซึ่งสามารถทำได้ตามขั้นตอนที่ 3

ขั้นตอนที่ 3 นำเข้าและอ่านรูปภาพ
ในขั้นตอนนี้ต้องระวังเรื่อง file path ด้วยนะถ้าโปรแกรมหาภาพไม่เจอ ก็จะทำการตรวจจับใบหน้าไม่ได้นะ😓

# Read the input image
img = cv2.imread(r"--file path--")
Enter fullscreen mode Exit fullscreen mode

เมื่ออ่านรูปภาพเรียบร้อยเราก็สามารถตรวจจับใบหน้าได้แล้ว สามารถทำตามขั้นตอนที่ 4 ได้เลย

ขั้นตอนที่ 4 ทำการตรวจจับใบหน้าจากรูปภาพด้วย ฟังก์ชัน detectMultiScale

# Detect faces
faces = face_cascade.detectMultiScale(img,1.1,5)
Enter fullscreen mode Exit fullscreen mode

ซึ่งในการใช้ฟังก์ชัน detectMultiScale จำเป็นจะต้องกำหนดค่าพารามิเตอร์ด้วย คือ

  1. img รูปภาพที่เราต้องการจะตรวจจับ
  2. scaleFactor ขนาดที่ใช้ในการสกัดรูปภาพ
  3. 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)
Enter fullscreen mode Exit fullscreen mode

ฟังก์ชันที่ใช้ในขั้นตอนที่ 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!")
Enter fullscreen mode Exit fullscreen mode

และแล้วก็มาถึงขั้นตอนการแสดงผลลัพธ์ที่เราทำมาทั้งหมด

ขั้นตอนที่ 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()
Enter fullscreen mode Exit fullscreen mode

ฟังก์ชันที่ใช้ในขั้นตอนที่ 7 เนี้ยจะมีการกำหนดค่าพารามิเตอร์ดังนี้

1.ฟังก์ชัน plt.figure(figsize=(10,10))
ฟังก์ชันนี้เป็นฟังก์ชันที่ใช้ในการวาดกราฟ และวาดภาพ ซึ่งการใช้ figure ทำให้เราสามารถกำหนดขนาดรูปภาพได้ด้วย

  • (10,10) กำหนดขนาดรูปภาพที่ต้องการวาด

2.ฟังก์ชัน cv2.imshow('Results',img)

  • Results' ชื่อหน้าต่างการแสดงผล จะต้องเป็น string เท่านั้น
  • img ภาพที่ต้องการแสดงผล

ผลการตรวจจับจำนวนใบหน้าที่ได้ก็จะแสดงผลได้ตามรูปภาพตัวอย่างเลยย
ภาพแรก เป็นการแสดงผลจำนวนใบหน้าที่ตรวจจับได้ จากขั้นตอนที่ 6
Image description
และภาพนี้ก็ เป็นผลของภาพวาดช่องสี่เหลี่ยมแสดงจำนวนใบหน้าที่ตรวจจับได้ จากขั้นตอนที่ 7
Image description

แค่นี้เราก็ได้รูปที่ภาพตรวจจับจำนวนใบหน้าจากรูปภาพได้แล้ววว
เป็นไงง๊ายง่ายยย✨


ไอเดียที่สอง ตรวจจับจำนวนใบหน้าด้วยกล้อง จะมีการเขียนโค้ดที่ต่างกันนิดหน่อย อยากรู้ว่าทำยังไงก็ไปดูโค้ดกันเลยย

ขั้นตอนที่ 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')

Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 2 เรียกใช้ฟังก์ชัน cv2.VideoCapture เพื่อเปิดกล้อง

# open camera
cap = cv2.VideoCapture(0)
Enter fullscreen mode Exit fullscreen mode

ซึ่งค่า 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()
Enter fullscreen mode Exit fullscreen mode

รายละเอียดค่าพารามิตเตอร์ของฟังก์ชันต่างๆได้อธิบายไปแล้วในไอเดียที่ 1 ขั้นตอนที่ 4-5 แต่จะอธิบายเพิ่มเติมในส่วนของ
ฟังก์ชัน cv2.waitKey(1) ซึ่ง 1 หมายถึงการรับค่าเพียงค่าเดียวจากผู้ใช้ ซึ่ง ณ ที่นี้ใช้ในการจบการทำงานของกล้องนั่นเอง
ผลลัพธิ์ที่ได้ก็แบบนี้เลย

Image description

เสร็จแล้ววเย้ 🎉
Image description


reference

https://dev.to/saharshlaud/face-detection-in-just-15-lines-of-code-ft-python-and-opencv-37ci

https://medium.com/@wanchatpookhuntod_1602/face-detection-opencv-%E0%B9%84%E0%B8%9E%E0%B8%98%E0%B8%AD%E0%B8%99-%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2-%E0%B9%86-ef8749f7f473

https://pongpich-v.blogspot.com/2018/11/blog-post.html

https://www.mindphp.com/%E0%B8%9A%E0%B8%97%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%99%E0%B8%AD%E0%B8%AD%E0%B8%99%E0%B9%84%E0%B8%A5%E0%B8%99%E0%B9%8C/python-gui/7048-example-use-module-cv2.html

Top comments (0)