وبلاگ رسانگار
با ما حرفه ای باشید

سرور مجازی NVMe

تشخیص چهره در پایتون با OpenCV

0 152
زمان لازم برای مطالعه: 6 دقیقه


معرفی

تشخیص چهره یک مورد کاربردی قدرتمند و رایج در یادگیری ماشینی است. می توان از آن برای خودکارسازی کارهای دستی مانند حضور در مدرسه و اجرای قانون استفاده کرد. از سوی دیگر، می توان از آن برای مجوز بیومتریک استفاده کرد.

در این مقاله تشخیص چهره را در پایتون با استفاده از 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

1/5 (1 رای)
دیدگاه شما در خصوص مطلب چیست ؟

آدرس ایمیل شما منتشر نخواهد شد.

لطفا دیدگاه خود را با احترام به دیدگاه های دیگران و با توجه به محتوای مطلب درج کنید