เขียนโปรแกรมตรวจจับจำนวนใบหน้าคน OpenCV Haar Cascades โดยใช้ python
Tags: opencv, ai, python, machinelearning
Published: 2023-04-09 16:50:52

ในการตรวจจับใบหน้า (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 จำเป็นจะต้องกำหนดค่าพารามิเตอร์ด้วย คือ 
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)
```
ฟังก์ชันที่ใช้ในขั้นตอนที่ 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
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq9xn3mrv7l1ou835k2a.png)
และภาพนี้ก็ เป็นผลของภาพวาดช่องสี่เหลี่ยมแสดงจำนวนใบหน้าที่ตรวจจับได้ จากขั้นตอนที่ 7
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zy2yd2mp2gyxan3w6gg.png)

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

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

> 
**ขั้นตอนที่ 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 หมายถึงการรับค่าเพียงค่าเดียวจากผู้ใช้ ซึ่ง ณ ที่นี้ใช้ในการจบการทำงานของกล้องนั่นเอง
ผลลัพธิ์ที่ได้ก็แบบนี้เลย

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rc3lt43lym15xfopu78f.png)

เสร็จแล้ววเย้ 🎉
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tm24xr4ivf8p2iukkz5.gif)

---

> 
reference

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

[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
](url)

[https://pongpich-v.blogspot.com/2018/11/blog-post.html](url)

[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](url)