از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
تشخیص چهره در پایتون با OpenCV
سرفصلهای مطلب
معرفی
تشخیص چهره یک مورد کاربردی قدرتمند و رایج در یادگیری ماشینی است. می توان از آن برای خودکارسازی کارهای دستی مانند حضور در مدرسه و اجرای قانون استفاده کرد. از سوی دیگر، می توان از آن برای مجوز بیومتریک استفاده کرد.
در این مقاله تشخیص چهره را در پایتون با استفاده از OpenCV انجام خواهیم داد.
OpenCV
OpenCV یکی از محبوب ترین کتابخانه های بینایی کامپیوتری است. به زبان های C و C++ نوشته شده است و علاوه بر جاوا و متلب، از پایتون نیز پشتیبانی می کند. در حالی که این سریعترین کتابخانه موجود نیست، کار با آن آسان است و یک رابط سطح بالا ارائه می دهد که به توسعه دهندگان اجازه می دهد کدهای پایدار بنویسند.
بیایید OpenCV را نصب کنیم تا بتوانیم از آن در کد پایتون خود استفاده کنیم:
$ pip install opencv-contrib-python
یا می توانید نصب کنید opencv-python
فقط برای ماژول های اصلی OpenCV. این opencv-contrib-python
شامل ماژول های اصلی و همچنین مشارکت ماژول هایی که عملکرد گسترده ای را ارائه می دهند.
تشخیص چهره در تصویر با استفاده از OpenCV
با نصب OpenCV، ما می توانیم import آن را به عنوان cv2
در کد ما
برای خواندن یک تصویر، از imread()
تابع، همراه با مسیر تصویری که می خواهیم process. این imread()
تابع به سادگی تصویر را از فایل مشخص شده در یک بارگذاری می کند ndarray
. اگر تصویر قابل خواندن نباشد، به عنوان مثال در صورت وجود یک فایل گم شده یا فرمت پشتیبانی نشده، عملکرد برمی گردد. None
.
ما از تصویری استفاده خواهیم کرد مجموعه داده Kaggle:
import cv2
path_to_image = 'Parade_12.jpg'
original_image = cv2.imread(path_to_image)
اطلاعات کامل RGB برای تشخیص چهره ضروری نیست. رنگ حاوی اطلاعات بی ربط زیادی است روی تصویر، بنابراین حذف آن و کار با یک تصویر خاکستری کارآمدتر است. علاوه بر این، الگوریتم Viola-Jones که در زیر کاپوت با OpenCV کار می کند، تفاوت در شدت ناحیه تصویر را بررسی می کند. تصاویر در مقیاس خاکستری این تفاوت را به طور چشمگیری نشان می دهند.
توجه داشته باشید: در مورد تصاویر رنگی، تصاویر رمزگشایی شده کانال ها را به ترتیب BGR ذخیره می کنند، بنابراین هنگام تغییر آنها به مقیاس خاکستری، باید از cv2.COLOR_BGR2GRAY
پرچم:
image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
این کار می توانست به طور مستقیم هنگام استفاده انجام شود imread()
، با تنظیم cv2.IMREAD_GRAYSCALE
پرچم:
original_image = cv2.imread(path_to_image, cv2.IMREAD_GRAYSCALE)
کتابخانه OpenCV دارای چندین طبقهبندی از قبل آموزشدیده است که برای یافتن چیزهای مختلف مانند چهرهها، چشمها، لبخندها، بالاتنه و غیره آموزش دیدهاند.
این هار ویژگی های شناسایی این اشیاء به صورت XML ذخیره می شوند و بسته به آن روی روش نصب OpenCV را اغلب می توان در آن یافت Lib\site-packages\cv2\data
. آنها همچنین می توانند در مخزن OpenCV GitHub.
برای دسترسی به آنها از طریق کد، می توانید از a استفاده کنید cv2.data.haarcascades
و نام فایل XML را که می خواهید استفاده کنید اضافه کنید.
میتوانیم با افزودن مسیر فایل به آن، ویژگیهای Haar را که میخواهیم برای تشخیص شی استفاده کنیم، انتخاب کنیم CascadeClassifier()
سازنده، که از مدل های از پیش آموزش دیده برای تشخیص اشیا استفاده می کند:
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
حالا، ما می توانیم از این استفاده کنیم face_cascade
شی برای تشخیص چهره در تصویر:
detected_faces = face_cascade.detectMultiScale(image=image, scaleFactor=1.3, minNeighbors=4)
وقتی مدلهای تشخیص اشیا آموزش داده میشوند، برای تشخیص چهرههایی با اندازه معین آموزش میبینند و ممکن است چهرههایی را که بزرگتر یا کوچکتر از حد انتظارشان هستند از دست بدهند. با در نظر گرفتن این موضوع، اندازه تصویر چندین بار تغییر می کند به این امید که یک چهره در نهایت به یک اندازه “قابل تشخیص” تبدیل شود. این scaleFactor
به OpenCV اجازه می دهد تا بداند که چقدر تصاویر را مقیاس بندی کند. در مورد ما، 1.3
به این معنی است که می تواند مقیاس پذیر باشد 30%
سعی کنید و چهره ها را بهتر مطابقت دهید.
همانطور که برای minNeighbors
پارامتر، برای کنترل تعداد مثبت کاذب و منفی کاذب استفاده می شود. حداقل تعداد مستطیلهای مثبت (تشخیص ویژگیهای صورت) را که باید در مجاورت یک مستطیل مثبت باشند، تعریف میکند تا در واقع مثبت در نظر گرفته شود. اگر minNeighbors
تنظیم شده است 0
، کوچکترین اشاره به چهره به عنوان چهره قطعی شمرده می شود، حتی اگر هیچ ویژگی صورت دیگری در نزدیکی آن تشخیص داده نشود.
هر دو scaleFactor
و minNeighbors
پارامترها تا حدودی دلخواه هستند و به صورت تجربی تنظیم می شوند. ما ارزشهایی را انتخاب کردهایم که به خوبی برای ما کار میکردند، و هیچ مثبت کاذبی نداشتند، با مبادله منفیهای کاذب بیشتر (چهرههای شناسایی نشده).
این detectMultiScale()
متد لیستی از مستطیل های تمام اشیاء شناسایی شده (چهره ها در مورد اول ما) را برمی گرداند. هر عنصر در لیست نمایانگر یک چهره منحصر به فرد است. این لیست شامل تاپل ها است، (x, y, w, h)
، جایی که x, y
مقادیر مختصات بالای سمت چپ مستطیل را نشان می دهند، در حالی که the w, h
مقادیر به ترتیب عرض و ارتفاع مستطیل را نشان می دهند.
ما می توانیم از لیست مستطیل های برگشتی استفاده کرده و از آن استفاده کنیم cv2.rectangle()
عملکردی برای ترسیم مستطیل هایی که در آن صورت تشخیص داده شده است. به خاطر داشته باشید که رنگ ارائه شده باید به ترتیب RGB یک تایی باشد:
for (x, y, width, height) in detected_faces:
cv2.rectangle(
image,
(x, y),
(x + width, y + height),
color,
thickness=2
)
حالا بیایید همه اینها را کنار هم بگذاریم:
import cv2
def draw_found_faces(detected, image, color: tuple):
for (x, y, width, height) in detected:
cv2.rectangle(
image,
(x, y),
(x + width, y + height),
color,
thickness=2
)
path_to_image = 'Parade_12.jpg'
original_image = cv2.imread(path_to_image)
if original_image is not None:
image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
profile_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_profileface.xml")
detected_faces = face_cascade.detectMultiScale(image=image, scaleFactor=1.3, minNeighbors=4)
detected_profiles = profile_cascade.detectMultiScale(image=image, scaleFactor=1.3, minNeighbors=4)
profiles_not_faces = (x for x in detected_profiles if x not in detected_faces)
draw_found_faces(detected_faces, original_image, (0, 255, 0))
draw_found_faces(detected_profiles, original_image, (0, 0, 255))
cv2.imshow(f'Detected Faces in {path_to_image}', original_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print(f'En error occurred while trying to load {path_to_image}')
ما از دو مدل مختلف استفاده کردیم روی این تصویر. مدل پیشفرض برای تشخیص چهرههای رو به جلو و مدلی که برای تشخیص بهتر چهرههایی که به طرفین نگاه میکنند ساخته شده است.
چهره های شناسایی شده با frontalface
مدل با رنگ سبز مشخص شده و چهره ها با علامت مشخص می شوند profileface
مدل با قرمز مشخص شده است. بیشتر چهره هایی که مدل اول پیدا کرد توسط دومی نیز پیدا می شد، بنابراین ما فقط مستطیل های قرمز را در جایی که profileface
مدل تشخیص چهره اما frontalface
نکرد:
profiles_not_faces = (x for x in detected_profiles if x not in detected_faces)
این imshow()
روش به سادگی تصویر ارسال شده را در پنجره ای با عنوان ارائه شده نشان می دهد. با تصویری که انتخاب کردیم، این خروجی زیر را ارائه می دهد:
استفاده از مقادیر مختلف برای scaleFactor
و minNeighbors
نتایج متفاوتی به ما خواهد داد. به عنوان مثال، با استفاده از scaleFactor = 1.1
و minNeighbors = 4
با هر دو مدل، موارد مثبت کاذب و مثبت واقعی بیشتری به ما می دهد:
می بینیم که الگوریتم کامل نیست، اما بسیار کارآمد است. این مورد در هنگام کار با داده های بلادرنگ، مانند فید ویدیویی از یک وب کم، بیشتر قابل توجه است.
تشخیص چهره در زمان واقعی با استفاده از وب کم
جریان های ویدئویی به سادگی جریان هایی از تصاویر هستند. با بهره وری از ویولا جونز الگوریتم، ما می توانیم تشخیص چهره را در زمان واقعی انجام دهیم.
مراحلی که باید برداریم بسیار شبیه به مثال قبلی تنها با یک تصویر هستند – ما این کار را انجام خواهیم داد روی هر تصویر در جریان
برای دریافت جریان ویدئو، از cv2.VideoCapture
کلاس سازنده این کلاس یک پارامتر عدد صحیح می گیرد که جریان ویدئو را نشان می دهد. در اکثر ماشین ها، وب کم با عبور قابل دسترسی است 0
، ولی روی ماشینهایی که دارای چندین جریان ویدئو هستند، ممکن است لازم باشد مقادیر مختلفی را امتحان کنید.
در مرحله بعد، باید تصاویر جداگانه را از جریان ورودی بخوانیم. این کار با read()
تابع، که برمی گردد retval
و image
. این image
به سادگی فریم بازیابی شده است. این retval
مقدار بازگشتی برای تشخیص اینکه آیا یک فریم بازیابی شده است یا نه استفاده می شود و خواهد شد False
اگر این کار را نکرده است.
با این حال، تمایل دارد با جریانهای ورودی ویدیو سازگار نباشد (مثلاً تشخیص نمیدهد که وبکم قطع شده است)، بنابراین این مقدار را نادیده میگیریم.
بیایید پیش برویم و کد قبلی را برای مدیریت یک جریان ویدئو تغییر دهیم:
import cv2
def draw_found_faces(detected, image, color: tuple):
for (x, y, width, height) in detected:
cv2.rectangle(
image,
(x, y),
(x + width, y + height),
color,
thickness=2
)
video_capture = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_eye_tree_eyeglasses.xml")
while True:
_, frame = video_capture.read()
grayscale_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
detected_faces = face_cascade.detectMultiScale(image=grayscale_image, scaleFactor=1.3, minNeighbors=4)
detected_eyes = eye_cascade.detectMultiScale(image=grayscale_image, scaleFactor=1.3, minNeighbors=4)
draw_found_faces(detected_faces, frame, (0, 0, 255))
draw_found_faces(detected_eyes, frame, (0, 255, 0))
cv2.imshow('Webcam Face Detection', frame)
if cv2.waitKey(1) == 27:
break
video_capture.release()
cv2.destroyAllWindows()
نتیجه
در این مقاله، ما یک اپلیکیشن تشخیص چهره با استفاده از پایتون و OpenCV ایجاد کرده ایم.
استفاده از کتابخانه OpenCV برای برنامه های اصلی تشخیص اشیا بسیار ساده است. تنظیم تجربی scaleFactor
و minNeighbors
پارامترها برای انواع تصاویری که می خواهید process می تواند نتایج بسیار دقیقی را بسیار کارآمد ارائه دهد.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-16 06:53:03