هروقت بحث شناسایی صورت وسط است احتمالا اولین چیزی که به ذهنتون میرسه کادری است که وب کم گوشی یا لپتاپ یا ... دور صورت شما ایجاد میکند، حالا میخواهیم با یک کد ساده در پایتون این کارو انجام بدیم:)
قبل از هرچیز باید بگم که این برنامه در محیط لینوکس اجرا شده است!
این آموزش شامل موارد زیر است:
نصب opencv در لینوکس
بازکردن وبکم
شناسایی صورت
ایجاد کادر دور صورت
نصب opencv در لینوکس
این کتابخانه با الگوریتمهای یادگیری ماشین کار میکند و عملیات تشخیص چهره را به هزاران عمل کوچک دیگر تبدیل میکند که به این اعمال کوچک طبقه بندی یا classifier میگویند.
به کتابخانه opencv نیاز داریم که با اجرای دستور زیر این کتابخانه نصب میشود.
pip install opencv-python
با دستور زیر این کتابخانه را فراخوانی میکنیم:
import cv2
حال باید به این فکر کنیم اگر بخواهیم یک چهره تشخیص داده شود چگونه این کار انجام میگیرد؟
cascade چیست؟
برای یک شیء ممکن است ما تعدادی طبقهبندی داشته باشیم که هر کدام از آنها برای تشخیص داده شدن باید با قالب یک شیء همخوانی داشتهباشند.
از طرفی دیگر اگر یک تصویر حاوی چهره را مانند یک پازل در نظر بگیریم، برای اینکه بخواهیم چهره را پیدا کنیم،الگوریتم، به ترتیب از بالا سمت چپ تا پایین هر قطعهی پازل را باید بررسی کند و با طبقهبندی موجود تشخیص چهره تطابق دهد که باعث ایجاد حجم محاسبات زمانبر میشود.حال برای اینکه زمان محاسبات را کاهش دهند openCV از cascade استفاده میکند. (پایتون کار مارو آسون کرده…:)
Cascades دارای گروهی از فایلهای XML هست که این فایلها دارای دادههای مورد نیاز برای تشخیص اشیاء مختلف نظیر چهره، بدن، توپ و... هستند. کافیست فایل مورد نظر برای تشخیص شیء دلخواهمان را در کد وارد کنیم و OpenCV آن شیء را درون تصاویر تشخیص میدهد.
برای تشخیص چهره از فایل xml زیر استفاده میکنیم.(به absolute path or relative path دقت کنید)
'haarcascade_frontalface_default.xml'
CascadeClassifier یک متد طبقهبندی آبشاری است که به وسیله چندین نمای ساده از یک شیء خاص (یعنی چهره) آموزش دیده است. به محض این که ابزار طبقهبندی، آموزش دید، میتواند روی یک تصویر جدید استفاده شده و شیء مورد نظر را تشخیص دهد. پس با استفاده از این تابع از کتابخانه opencv، و الگوریتم xml که به آن میدهیم، میتوانیم یک چهره را در تصویر تشخیص دهیم.کد کلی برای استفاده از مدل آموزش دیده آماده در پایتون به صورت زیر میشود:( یه جورایی انگار مدل را فراخوانی میکند.)
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
باز کردن وب کم
حال برای باز کردن وب کم لپ تاپ ما باید یک شیء از videocapture ایجاد کنیم و آرگومان آن را باید 0 یا -1 بدهیم که شماره وب کم سیستم است و یا میتوانیم شماره وبکمی که به سیستم وصل است بدهیم یا حتی میتوانیم آدرس ویدئویی در سیستم را به آن بدهیم.( در انتها یادتون نره capture را ببندید.)
cap = cv2.VideoCapture(0)
حال برای اینکه بفهمیم وبکم باز شده و ویدئو در حال گرفتن است در حلقهای بینهایت خط زیر را نوشته که یک مقدار بولین دارد که در متغیری به نام ret و خوده تصویر را در متغیر img ذخیره میکند.
ret, img = cap.read()
تغییر طیف رنگی تصویر
opencv یک تصویر را در قالب RGB بارگذاری میکند. متد ()cv2.cvtcolor در OpenCV تابعی است که برای تبدیل فضای رنگی یک تصویر استفاده می شود. بیش از 150 روش تبدیل فضای رنگی در OpenCV موجود است. در این قسمت برای اینکه تصویری که وبکم میگیرد را بتوانیم به مدل ود بدهیم، باید طیف رنگی آن را تغییر دهیم به سیاه سفید یا RGB که با دستور زیر انجام میشود.
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
پارامترهای ورودی این متد:۱- تصویر ورودی است که میخواهیم طیف آن را تغییر دهیم و ۲- کد تغییر طیف رنگی تصویر است. چرا طیف رو به خاکستری تغییر میدیم؟ چون متدی که قراره در قسمت پایین دربارش حرف بزنیم تصویر را با طیف خاکستری میگیرد.
تشخیص چهره
حالا به بحث شیرین ماجرای شناسایی چهره رسیدیم:) درباره مدل آموزش دیده آماده مفصل در ابتدا صحبت کردیم، حالا میخواهیم تصویری که از وبکم میگیریم را به مدل بدیم تا چهره را تشخیص بده:)
Facecascade یک متد داره به نام detectMultiScale که معمولاً برای تشخیص اشیا در تصاویر استفاده می شود. یک تصویر در مقیاس خاکستری را به عنوان ورودی میگیره و لیستی از مستطیل ها را در جایی که شی مورد نظر پیدا می شود، برمی گرداند.
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
به طور خلاصه بخوام درباره پارامترهای دوم و سوم صحبت کنم باید بگم اساساً از ضریب مقیاس برای ایجاد هرم مقیاس شما استفاده می شود. مدل شما دارای یک اندازه ثابت است که در طول آموزش تعریف شده است که در xml قابل مشاهده است. این به این معنی است که این اندازه چهره در صورت وجود در تصویر شناسایی میشود. با این حال، با تغییر مقیاس تصویر ورودی، میتوانید اندازه یک چهره بزرگتر را به صورت کوچکتر تغییر دهید و آن را توسط الگوریتم قابل تشخیص کنید.
ایجاد کادر دور چهره
برای اینکه بخوایم بفهمیم الگوریتم ما درست کار میکنه میتونیم دور چهره تشخیص داده شده با استفاده از خروجی متد detectMultiScale یک مستطیل بکشیم:)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 100), 3)
برای نمایش تصویر در یک پنجره از ()cv2.imshow استفاده می کنیم. پنجره به طور خودکار با اندازه تصویر متناسب می شود. این تابع دو آرگومان دارد. اولین آرگومان نام پنجره است که یک رشته میباشد. آرگومان دوم تصویری است که با خواندن آن، در یک متغیر ذخیره کردیم. شما میتوانید تعداد بیشتری پنجره با یک تصویر ایجاد کنید ولی باید نام تصاویر متفاوت باشد.
cv2.imshow('shima_viraweb123', img)
نتیجه نهایی
کل کد به صورت زیر درمیآید:
و اما نتیجه اجرای کد:)
چجوری چهره رو تو فیلم تشخیص بدیم و دورش کادر بندازیم؟