در این مقاله، ما راهی ساده برای تشخیص چهره توسط پایتون و کتابخانه متن باز OpenCV را بررسی خواهیم کرد.
پیش از اینکه در قسمت نظرات سوالی بپرسید لطفا به این بخش توجه فرمایید:
۱.از خواندن مقاله نگذرید و تنها به اجرای کد نپردازید. شما باید با نحوه عملکرد کد آشنا شوید تا بتوانید در صورت لزوم کد را اصلاح کنید.
۲.با داشتن وب کم میتوانید این کد را بصورت آنلاین اجرا کنید.
سپاسگزار
فهرست محتوا
OpenCV محبوبترین کتابخانه بینایی کامپیوتر است. این کتابخانه تحت زبان C/C++ نوشته شده است و اکنون برای پایتون در دسترس است.
OpenCV از الگوریتمهای یادگیری ماشین برای تشخیص چهره درون تصویر استفاده میکند. بخاطر اینکه چهرهها بسیار پیچیده هستند. اگر چهرهای در تصویر تشخیص داده شود و یا نشود راه کار سادهای برای آزمون شما وجود ندارد. هزاران الگوی کوچک و ویژگیها باید با هم منطبق شوند. الگوریتمها وظیفه دارند که چهره را به هزاران وظیفه کوچک تقسیم کنند تا مسائل به راحتی قابل حل باشند. این وظایف همچنین classifiers نامیده میشوند.
برای چیزی شبیه به یک چهره، شما ممکن است دارای بیش از ۶۰۰۰ یا بیشتر دارای classifier باشید. ۶۰۰۰ عدد تمام کلاسیفایرهایی است که برای تشخیص چهره نیازمند هستید (البته با خطای محدود). اما در اینجا مشکلی وجود دارد. برای تشخیص چهره، الگوریتم از گوشهی سمت چپ بالای تصویر، تصویر را به بلوکهای کوچکی تقسیم میکند و به آرامی در میان بلوکهای کوچک حرکت میکند و پیوسته میپرسد: آیا این یک چهره است؟ … آیا این یک چهره است؟ … آیا این یک چهره است؟ درنتیجه ۶۰۰۰ یا بیشتر آزمون وجود دارد که باید برای هر بلوک اجرا شود و ممکن است شما دارای میلیونها محاسبات باشید که تمام توان پردازنده شما را اشغال کند.
بدین منظور OpenCV از cascades استفاده میکند. Cascade چیست؟ بهترین جواب میتواند در دیکشنری یافت شود: یک آبشار و یا مجموعهای از آبشارها
مانند مجموعهای از آبشارها، OpenCV مسائل را به ایستگاههای مختلفی تقسیم میکند. برای هر بلوک آزمونی تخمینی و سریع اجرا میشود. اگر نتیجه آزمون مثبت باشد. آزمون با جزئیات بیشتری اجرا میشود و … . الگوریتم ممکن است به ۳ تا ۵۰ از این ایستگاهها یا آبشارها تقسیم شود. تنها زمانی یک چهره تشخیص داده میشود که تمامی این مراحل با موفقیت طی شوند.
مزیت این روش این است که بخش عظیمی از تصویر پاسخی منفی در مراحل اولیه خواهند داد که در نتیجه الگوریتم زمان خود را برای آزمون تمامی ۶۰۰۰ ویژگی بر روی تصویر تلف نخواهد کرد. به جای زمان بری حدود ساعتها، تشخیص چهره میتواند به لحظه صورت پذیرد.
گرچه تئوری تشخیص چهره ممکن است پیچیده به نظر برسد؛ در عمل ممکن است کاملا آسان باشد. آبشارها تنها فایلهای XML ای هستند که داده OpenCV را برای تشخیص اشیا مورد استفاده قرار میدهد. شما کد را با آبشاری که میخواهید آغاز میکنید و نهایتا آبشار، کار را برای شما انجام خواهد داد.
برای نصب OpenCV ابتدا لازم است. پایتون را بر روی سیستم خود نصب کنید. پس از نصب پایتون بر روی سیستم با دستور زیر به نصب OpenCV بپردازید.
pip3 install opencv-python
بیایید کد را بشکنیم. شما میتوانید کد را از گیت هاب دریافت کنید.
# Get user supplied values
imagePath = sys.argv[1]
cascPath = sys.argv[2]
شما ابتدا نام تصویر و آبشار را به عنوان ورودی های خط دستور به برنامه انتقال میدهید. ما از تصویر — به علاوه آبشار پیش فرض برای تشخیص چهره توسط OpenCV استفاده میکنیم.
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
حال ما آبشار را ایجاد میکنیم و آن را با فایل آبشار خود مقدار دهی میکنیم. این کار آبشار چهره را به حافظه انتقال میدهد و آماده به کار میکند. به خاطر داشته باشید که آبشار تنها یک فایل XML است که شامل دادههایی برای تشخیص چهره است.
# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
در اینجا ما تصویر را میخوانیم و به خاکستری تبدیل میکنیم. بسیاری از عملیات ها در OpenCV در مقیاس خاکستری صورت میپذیرد.
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
این تابع چهرههای حقیقی را در تصویر ما تشخیص میدهد و قسمت کلیدی کد ما است. پس بیایید بیشتر تابع را مورد بررسی قرار دهیم:
۱.تابع detectMultiScale تابعی عمومی برای تشخیص اشیا است. از آنجایی که ما این تابع را برای آبشار چهره فراخوانی میکنیم. پس این تابع، چهرهها را تشخیص میدهد.
۲.اولین گزینه تصویر خاکستری است.
۳.دومین گزینه scaleFactor است. از آنجایی که بعضی از چهرهها ممکن است به دوربین نزدیکتر باشند و نسبت به دیگر چهرهها بزرگتر به نظر برسند. مقیاس به ما در این زمینه کمک میکند.
۴.الگوریتم تشخیص از پنجره لغزانی برای تشخیص اشیا استفاده میکند. minNeighbors تشخیص اشیا نزدیکی که قابل تشخیص هستند را نزدیک پنجره حاضر مشخص میکند. minSize, meanwhile مشخص کننده اندازه هر پنجره است.
یادداشت: در واقعیت ممکن است شما مقادیر مختلفی را برای اندازه پنجره، مقیاس و … امتحان کنید تا مقداری که به خوبی برای شما کار میکند را پیدا کنید.
تابع فهرستی از مستطیلها که معتقد است چهره درون آنها وجود دارد را باز میگرداند. سپس ما حلقه ای در یافتهها ایجاد میکنیم.
print "Found {0} faces!".format(len(faces))
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
این تابع ۴ مقدار باز میگرداند: موقعیت x و y و عرض و ارتفاع مستطیل (w,h)
ما از این مقادیر برای ترسیم مستطیل توسط تابع rectangle بهره میگیریم.
cv2.imshow("Faces found", image)
cv2.waitKey(0)
نهایتا تصویر را نمایش میدهیم و منتظر دریافت کلید از صفحه کلید میمانیم.
بیایید دوباره تصویر را ببینیم:
خب ما ابتدا تصویر از دوربینی با کیفیت بالا را مورد پردازش جهت تشخیص چهره قرار دادیم. سپس تصویری از یک موبایل را مورد پردازش قرار دادیم. گاهی به همین دلیل ما باید مقدار scaleFactor را مورد دستکاری قرار دهیم. همانطور که پیشتر نیز گفتم: شما باید مقادیر الگوریتم را وابسته به شرایط تنظیم کنید تا از جوابهای اشتباه فاصله بگیرید.
آگاه باشید با توجه به اینکه این الگوریتم مبتنی بر یادگیری ماشین است. نتیجه به هیچ وجه ۱۰۰ درصد دقیق نخواهد بود. شما نتایج خوبی در بیشتر موارد دریافت خواهید کرد. اما گاهی الگوریتم شامل تشخیص اشتباه چهره خواهد بود. امیدوارم از مقاله تشخیص چهره توسط پایتون بهره کامل را برده باشید. نظرات خود را در این باره با ما به اشتراک بگذارید.