تشخیص اجزای صورت (چشم، بینی، فک، دهان و غیره) با Python OpenCV، فرایند تشخیص قسمت‌های مختلف روی صورت مانند ابرو، چشم، بینی، دهان و فک می‌باشد. برنامه‌های بسیاری وجود دارد که از تکنیک‌های تشخیص چهره Facial استفاده می‌کنند.

تشخیص اجزای صورت با استفاده از Python OpenCV

پیش از این ما با استفاده از OpenCV یک سیستم تشخیص چهره می‌ساختیم، امروزه از همان OpenCV با Raspberry Pi برای تشخیص اجزای صورت استفاده خواهیم کرد. برای شناسایی محل ساختارهای اصلی صورت در چهره، از ماژول ردیاب مشخصه صورت و از پایتون OpenCV برای تجسم بخش‌های چهره شناسایی شده استفاده خواهد شد.

اجزای موردنیاز تشخیص اجزای صورت با Python OpenCV

قطعات سخت‌افزاری

  • Raspberry Pi 3
  • ماژول Pi Camera

نرم افزار و خدمات آنلاین

  • Open CV
  • Dlib
  • Python3

قبل از شروع کار با این Raspberry Pi 3 Facial Detection، ابتدا باید OpenCV ،imutils ،dlib ،Numpy و برخی از وابستگی‌های دیگر را در این پروژه نصب کنیم. OpenCV در اینجا برای پردازش تصویر دیجیتال استفاده شده است. متداول‌ترین کاربردهای پردازش تصویر دیجیتال تشخیص شیء، تشخیص چهره و شمارنده افراد می‌باشد.

 تشخیص اجزای صورت با Python OpenCV

نصب OpenCV در Raspberry Pi

در اینجا از کتابخانه OpenCV برای اسکنر Raspberry Pi QR استفاده می‌شود. برای نصب OpenCV، ابتدا Raspberry Pi را به روز کنید. سپس برای نصب OpenCV بر روی Raspberry Pi وابستگی‌های مورد نیاز را نصب نمایید.

sudo apt-get install libhdf5-dev -y 
sudo apt-get install libhdf5-serial-dev –y 
sudo apt-get install libatlas-base-dev –y 
sudo apt-get install libjasper-dev -y 
sudo apt-get install libqtgui4 –y
sudo apt-get install libqt4-test –y

پس از آن با استفاده از دستور زیر OpenCV را در Raspberry Pi نصب کنید.

pip3 install opencv-contrib-python==4.1.0.25

نصب imutils در تشخیص اجزای صورت با Python OpenCV

از imutils برای اجرای چند کارکرد لازم جهت پردازش تصویر مانند ترجمه، چرخش، تغییر اندازه، اسکلت‌سازی و نمایش تصاویر Matplotlib با OpenCV آسان‌تر استفاده می‌شود. بنابراین imutils را با استفاده از دستور زیر نصب کنید:

pip3 install imutils

نصب dlib در تشخیص اجزای صورت با Python OpenCV

dlib ابزاری مدرن است که شامل الگوریتم‌های Machine Learning و ابزارهایی برای مشکلات دنیای واقعی است. برای نصب dlib از دستور زیر استفاده کنید.

pip3 install dlib

نصب NumPy در تشخیص اجزای صورت با Python OpenCV

NumPy کتابخانه اصلی برای محاسبات علمی است که شامل یک شیء آرایه‌ای قدرتمند بصورت ابعادی است، ابزاری برای ادغام C ،C ++ و غیره فراهم می‌کند.

Pip3 install numpy

نحوه تشخیص بخش های چهره با استفاده از dlib

ما می‌خواهیم از ردیاب علائم صورت، کتابخانه dlib برای تشخیص محل قرارگیری 68 (x ، y) – هماهنگ‌کننده آن نقشه برای ساختارهای صورت در چهره استفاده کنیم. تصویری که شامل نمایه‌های 68 مختصات در زیر آمده است:

 تشخیص اجزای صورت با Python OpenCV

 تشخیص اجزای صورت با Python OpenCV

برنامه نویسی Raspberry Pi برای تشخیص چهره

کد کامل پایتون برای تشخیص قسمت‌های چهره با آشکارساز مشخص شده صورت قبل از آموزش dlib در انتهای صفحه آورده شده است. در اینجا ما برای درک بهتر بخش‌های مهم کد را توضیح می‌دهیم. طبق معمول، کد را با درج کلیه کتابخانه‌های مورد نیاز شروع کنید.

from imutils import face_utils
import numpy as np
import argparse
import imutils
import dlib
import cv2
from picamera.array import PiRGBArray
from picamera import PiCamera

سپس دوربین را تنظیم کرده و وضوح تصویر را در (640 ، 480) و میزان فریم در 30 فریم در ثانیه تنظیم کنید.

camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 30

حال در سطرهای بعدی، از تجزیه‌کننده آرگومان استفاده کنید تا مسیری را برای پیش‌بینی اجزای صورت ارائه دهید.

ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
            help="facial landmark predictor path")
args = vars(ap.parse_args())

در سطرهای بعدی، ردیاب چهره را با چهره dlib مبتنی بر HOG را آغاز کنید و پیشگویی‌کننده اجزای صورت را بارگیری نمایید.

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])

سپس از تابع capt_continuous استفاده کنید تا بتوانید فریم‌ها را از دوربین Raspberry Pi دریافت نمایید.

for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
        image = frame.array
        cv2.imshow("Frame", image)
        key = cv2.waitKey(1) & 0xFF
        rawCapture.truncate(0)

برای گرفتن یک قاب خاص از کلید صفحه کلید “S” استفاده کنید. سپس تصویر گرفته شده را تغییر اندازه دهید و آن را به مقیاس خاکستری تبدیل کنید.

if key == ord("s"):
       image = imutils.resize(image, width=400)
       gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

از تابع تشخیص‌دهنده dlib برای تشخیص چهره‌ها در تصویر گرفته شده استفاده کنید.

rects = detector(gray, 1)

تصویری را که تشخیص چهره در آن انجام شده است بگیرید، علائم صورت را تعیین کنید و 68 امتیاز را به یک آرایه NumPy تبدیل کنید. روی هر یک از مناطق صورت بطور جداگانه حلقه بزنید.

for (i, rect) in enumerate(rects):
          shape = predictor(gray, rect)
          shape = face_utils.shape_to_np(shape)

سپس از یک تصویر اصلی کپی بگیرید و از آن برای حلقه استفاده کنید تا نام قسمت چهره روی تصویر کشیده شود. رنگ متن قرمز خواهد بود، با تغییر مقادیر RGB می‌توانید آن را به رنگ دیگری تغییر دهید.

for (name, (i, j)) in face_utils.FACIAL_LANDMARKS_IDXS.items():
          clone = image.copy()
          cv2.putText(clone, name, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
                                    0.7, (0, 0, 255), 2)

اکنون قسمت‌های چهره شناسایی شده را حلقه می‌زنیم و از تابلوی طراحی OpenCV برای ترسیم محافل روی این قسمت‌های چهره استفاده خواهیم کرد. برای کسب اطلاعات بیشتر در مورد توابع ترسیم می‌توانید این سند OpenCV را دنبال کنید.

for (x, y) in shape[i:j]:
               cv2.circle(clone, (x, y), 1, (0, 0, 255), -1)

اکنون در سطرهای بعدی، با محاسبه جعبه محدودیت مختصات یک قسمت خاص صورت، هر قسمت از صورت را به عنوان یک تصویر جداگانه استخراج می‌کنیم. تصویر استخراج شده در 250 پیکسل تغییر اندازه می‌یابد.

(x, y, w, h) = cv2.boundingRect(np.array([shape[i:j]]))
 roi = image[y:y + h, x:x + w]
 roi = imutils.resize(roi, width=250, inter=cv2.INTER_CUBIC)

اکنون در آخرین خط کد، قسمت‌های صورت را با نام آنها و یک تصویر جداگانه از آن قسمت نمایش دهید. برای تغییر ناحیه صورت از کلید ESC استفاده کنید.

cv2.imshow("ROI", roi)
cv2.imshow("Image", clone)
cv2.waitKey(0)

تست تشخیص قسمت چهره

برای آزمایش پروژه، فهرست راهنمایی ایجاد کرده و با استفاده از دستورات زیر آن را هدایت کنید:

mkdir face-part-detector
cd face-part-detector

اکنون  shape_predictor_68_face_landmarks.dat file from this link را دانلود کنید، سپس فایل shape_predictor_68_face_landmarks.dat را درون این کتابخانه استخراج و کپی کنید و سپس یک فایل جدید با نام detect.py را باز کرده و کد ذکر شده در زیر را جایگذاری کنید. اینک کد پایتون را با استفاده از دستور زیر راه‌اندازی نمایید:

python3 detect.py --shape-predictor shape_predictor_68_face_landmarks.dat

 تشخیص اجزای صورت با Python OpenCV

پنجره‌ای را مشاهده می‌کنید که یک تصویر زنده از دوربین را نشان می‌دهد. سپس کلید “S” را فشار دهید تا یک قاب از جریان مستقیم انتخاب شود. نقاط قرمز را در قسمت دهان خود مشاهده خواهید کرد. برای دیدن سایر قسمت های چهره از کلید ESC استفاده کنید. کد کامل پایتون در زیر آورده شده است:

from imutils import face_utils
import numpy as np
import argparse
import imutils
import dlib
import cv2
from picamera.array import PiRGBArray
from picamera import PiCamera
from PIL import Image
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 30
rawCapture = PiRGBArray(camera, size=(640, 480))
 
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p", "--shape-predictor", required=True,
help="facial landmark predictor path")
args = vars(ap.parse_args())
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
    image = frame.array
    cv2.imshow("Frame", image)
    key = cv2.waitKey(1) & 0xFF
    rawCapture.truncate(0)
    if key == ord("s"):
       image = imutils.resize(image, width=300)
       gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
       rects = detector(gray, 1)
 
# loop over the face detections
       for (i, rect) in enumerate(rects):
 
# determine the facial landmarks for the face region
          shape = predictor(gray, rect)
          shape = face_utils.shape_to_np(shape)
 
# loop over the face parts individually
          for (name, (i, j)) in face_utils.FACIAL_LANDMARKS_IDXS.items():
 
# display the name of the face part on the image
                clone = image.copy()
                cv2.putText(clone, name, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0, 0, 255), 2)
 
# Draw Circles on specific face part
                for (x, y) in shape[i:j]:
                       cv2.circle(clone, (x, y), 1, (0, 0, 255), -1)
 
# extract the ROI of the face region as a separate image
                (x, y, w, h) = cv2.boundingRect(np.array([shape[i:j]]))
                roi = image[y:y + h, x:x + w]
                roi = imutils.resize(roi, width=250, inter=cv2.INTER_CUBIC)
 
# show the particular face part
                cv2.imshow("ROI", roi)
                cv2.imshow("Image", clone)
                cv2.waitKey(0)
 
# visualize all facial landmarks 
          for (x, y) in shape:
           cv2.circle(image, (x, y), 1, (0, 0, 255), -1)
           cv2.imshow("Image",image)
          cv2.waitKey(0)