از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
تشخیص شی با OpenCv-Python با استفاده از طبقه بندی کننده آبشار HAAR
سرفصلهای مطلب
معرفی
پایتون کاربردهای زیادی در زمینه دارد کامپیوتر ویژن، به طور معمول هر چند یادگیری عمیق. از انجام OCR روی اسنادی که به روبات ها اجازه می دهند “ببینند” – دید رایانه یک زمینه هیجان انگیز و چالش برانگیز است!
OpenCV یک منبع باز ، چارچوب متقابل پلتفرم است ، که به عنوان یک کتابخانه گرا به سمت چشم انداز رایانه در زمان واقعی ساخته شده است. بدون توجه به سیستم عامل خود ، می توانید از طریق C ++ ، Python و Java با آن ارتباط برقرار کنید!
دید رایانه یک زمینه گسترده است و بسیاری از وظایف/مشکلات فردی وجود دارد که می توانید با آن مقابله کنید. یک بزرگ است تشخیص شی.
توجه داشته باشید: تشخیص شی به طبقه بندی (برچسب زدن)، تشخیص موقعیت و تشخیص طرح کلی (معمولاً خام ، مانند جعبه محدود) برای یک شیء در یک تصویر ، فیلم یا جریان. اینها سه وظیفه متمایز هستند که می توانند از منظر خودشان موضوع باشند.
تشخیص طرح نگاری غیر کادمی نیز می تواند به آن گفته شود تقسیم بندی تصویر، اگر تصویر را به هر شی مجزا تقسیم کنید، تقسیم بندی تصویر به این برنامه محدود نمی شود.
در این راهنما، روش انجام تشخیص شی در پایتون با OpenCV را خواهید آموخت. ما روش خواندن، شناسایی و نمایش اشیاء شناسایی شده در یک را پوشش خواهیم داد تصویر، فایل ویدیویی و در زمان واقعی، با استفاده از طبقه بندی کننده Haar-Cascade از قبل آموزش دیده.
بیایید با نصب OpenCV شروع کنیم!
تشخیص شی با استفاده از OpenCV
اگر قبلاً OpenCV را نصب نکرده اید – نصب درایور پایتون برای آن آسان است pip
:
$ pip install opencv-python
خودشه! OpenCV و تمام وابستگی هایی که با آن کار می کند نصب خواهند شد.
توجه داشته باشید: اگر هنگام نصب با خطا مواجه شدید، نصب را امتحان کنید opencv-contrib-python
بجای.
اکنون که کتابخانه خود را راهاندازی کردهایم، اولین قدم ما در تشخیص شیء خواندن و نمایش یک تصویر با OpenCV است. شما می توانید از هر تصویری که دوست دارید استفاده کنید، در این راهنما از آن استفاده خواهیم کرد face_image.jpg
، بدست آمده از طریق thispersondoesnotexist.com.
وب سایت با استفاده از “افراد خیالی” تولید می کند StyleGan.
imread()
روش از cv2
ماژول (نماینده OpenCV) می تواند برای بارگذاری در یک تصویر استفاده شود. سپس – می توانیم آن را در یک پنجره نمایش دهیم:
import cv2
image_path = "generic-face.webp"
window_name = f"Detected Objects in {image_path}"
original_image = cv2.imread(image_path)
cv2.namedWindow(window_name, cv2.WINDOW_KEEPRATIO)
cv2.imshow(window_name, original_image)
cv2.resizeWindow(window_name, (400, 400))
cv2.waitKey(0)
cv2.destroyAllWindows()
با اجرای این کد، پنجره ای مانند زیر ظاهر می شود:
توجه داشته باشید: گاهی اوقات سیستم عامل شما ممکن است پنجره را به جلوی صفحه نمایش نیاورد و به نظر برسد که کد به طور نامحدود در حال اجرا است. اگر پس از اجرای کد، پنجرهای را مشاهده نکردید، حتماً از پنجرههای باز خود عبور کنید.
imread()
روش بارگذاری تصویر، و imshow()
روش برای نمایش تصویر استفاده می شود روی پنجره. namedWindow()
و resizeWindow()
روش هایی برای ایجاد یک پنجره سفارشی برای تصویر در صورت وجود هر گونه اختلاف مربوط به اندازه پنجره و تصویر استفاده می شود.
waitKey()
روش یک پنجره را برای مقدار مشخصی از میلی ثانیه یا تا زمانی که یک کلید فشار داده شود باز نگه می دارد. یک ارزش از 0
به این معنی که OpenCV پنجره را به طور نامحدود باز نگه می دارد تا زمانی که کلیدی را برای بستن آن فشار دهیم. destroyAllWindows()
متد به OpenCV می گوید که تمام پنجره هایی را که باز می کند ببندد.
با تنظیمات اولیه، بیایید مراحل بعدی را برای شناسایی اشیاء با OpenCV برداریم. باید بفهمیم:
- روش ترسیم با استفاده از OpenCV (برای “محلی کردن” / طرح کلی اشیاء در صورت شناسایی)
- طبقهبندیکنندههای آبشار Haar (چگونه OpenCV اشیا را متمایز میکند)
چگونه با استفاده از OpenCV ترسیم کنیم؟
OpenCV می تواند اشکال مختلفی از جمله مستطیل، دایره و خطوط را ترسیم کند. ما حتی می توانیم از a استفاده کنیم putText()
روش برای گذاشتن یک برچسب با شکل بیایید با استفاده از تصویر یک شکل مستطیلی ساده در تصویر بکشیم rectangle()
روشی که آرگومان های موقعیتی، رنگ و ضخامت شکل را می گیرد.
یک خط جدید برای ایجاد یک مستطیل اضافه کنید پس از خواندن تصویر و قبل از نامگذاری پنجره:
...
original_image = cv2.imread(image_path)
rectangle = cv2.rectangle(original_image,
(200, 100),
(900, 800),
(0, 255, 0),
2)
cv2.namedWindow(window_name, cv2.WINDOW_KEEPRATIO)
...
اکنون، کد خود را دوباره اجرا کنید تا یک مستطیل بر روی تصویر کشیده شده باشد:
در اینجا، محل مستطیل را با علامت ثابت کردیم cv2.rectangle()
زنگ زدن. این مکان ها چیزی است که از تصویر قابل استنباط است، نه حدس زده. اینجاست که OpenCV می تواند کارهای سنگین را انجام دهد! هنگامی که این کار انجام شد – می توانیم به جای آن از این روش دقیق برای کشیدن یک مستطیل در اطراف شی شناسایی شده استفاده کنیم.
رسم مستطیل ها (یا دایره ها) مانند این مرحله مهمی در تشخیص شی است، زیرا به ما امکان می دهد اشیایی را که تشخیص می دهیم به روشی واضح حاشیه نویسی کنیم (برچسب گذاری کنیم).
اکنون که طراحی با OpenCV تمام شد، بیایید نگاهی به مفهوم the بیاندازیم طبقه بندی آبشار هار، چگونه کار می کند، و چگونه به ما امکان می دهد اشیاء را در یک تصویر شناسایی کنیم!
طبقه بندی کننده هار-آبشار
Haar-Cascade Classifier یک طبقه بندی کننده یادگیری ماشینی است که با آن کار می کند ویژگی های هار. این در تجسم یافته است cv2.CascadeClassifier
کلاس چندین فایل XML با OpenCV از پیش بسته بندی شده است که هر کدام دارای این فایل هستند ویژگی های هار برای اشیاء مختلف
ویژگی های هار به روشی مشابه کار کنید نقشه های ویژگی منظم شبکه های عصبی کانولوشن (CNN).
ویژگی ها برای بسیاری از مناطق یک تصویر محاسبه می شوند، جایی که شدت پیکسل ها جمع می شوند، قبل از اینکه تفاوت بین این مجموع محاسبه شود. این نمونه برداری از تصویر منجر به یک نقشه ویژگی ساده شده می شود که می تواند برای شناسایی الگوها در تصاویر استفاده شود.
توجه داشته باشید: گزینههای تشخیص الگوی زیادی وجود دارد، از جمله شبکههای بسیار قدرتمندی که دقت و انعطافپذیری بیشتری نسبت به طبقهبندیکنندههای Haar-Cascade ارائه میدهند. جذابیت اصلی ویژگی های هار و طبقه بندی کننده هار آبشار سرعت آن است. واقعاً مناسب است تشخیص شی در زمان واقعی، جایی که بیشترین کاربرد آن را می بیند.
هنگامی که OpenCV را نصب می کنید، به فایل های XML با ویژگی های Haar برای موارد زیر دسترسی خواهید داشت:
- چشم ها
- صورت جلویی
- تمام قد
- قسمت بالای بدن
- پایین تنه
- گربه ها
- علائم توقف
- پلاک و غیره
شما می توانید نام فایل های آنها را در رسمی پیدا کنید مخزن GitHub.
اینها طیف نسبتاً گسترده ای از استفاده را پوشش می دهند! به عنوان مثال، بیایید در طبقه بندی کننده برای بارگذاری کنیم چشم ها و سعی کنید چشمها را در تصویری که بارگذاری کردهایم تشخیص دهید و یک مستطیل در اطراف شی شناسایی شده بکشید:
import cv2
image_path = "face_image.jpg"
window_name = f"Detected Objects in {image_path}"
original_image = cv2.imread(image_path)
image_grey = cv2.cvtColor(original_image, cv2.COLOR_RGB2GRAY)
cascade_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_eye.xml")
detected_objects = cascade_classifier.detectMultiScale(image_grey, minSize=(50, 50))
if len(detected_objects) != 0:
for (x, y, width, height) in detected_objects:
cv2.rectangle(original_image, (x, y),
(x + height, y + width),
(0, 255, 0), 2)
cv2.namedWindow(window_name, cv2.WINDOW_KEEPRATIO)
cv2.imshow(window_name, original_image)
cv2.resizeWindow(window_name, 400, 400)
cv2.waitKey(0)
cv2.destroyAllWindows()
اجرای این کد باید چیزی شبیه به این را نشان دهد:
در اینجا، برای کاهش هزینه محاسباتی، تصویر را برای طبقهبندیکننده مقیاسبندی خاکستری میکنیم (اطلاعات بیشتر به معنای محاسبات بیشتر). رنگ ها برای این تشخیص خیلی مهم نیستند، زیرا الگوهایی که چشم ها را مشخص می کنند، چه رنگی باشند و چه نباشند، تقریباً یکسان به نظر می رسند.
cascade_classifier
هست یک CascadeClassifier
به عنوان مثال، با ویژگی های هار بارگذاری شده برای چشم. ما به صورت پویا فایل را از طریق f-Strings مکان یابی می کنیم!
detectMultiScale()
روش چیزی است که تشخیص واقعی را انجام می دهد و می تواند همان شی را تشخیص دهد روی یک تصویر، صرف نظر از مقیاس فهرستی از مختصات اشیاء شناسایی شده را به شکل مستطیل (تبل) برمی گرداند. این طبیعی است که آنها را با مستطیل ترسیم کنیم! برای هر چند تایی از (x, y, width, height)
واقع در detected_objects
، می توانیم یک مستطیل رسم کنیم.
minSize
آرگومان حداقل اندازه یک شی را که باید در نظر گرفته شود را تعریف می کند. اگر اندازه را واقعاً کوچک تنظیم کنید، طبقه بندی کننده احتمالاً انتخاب می کند زیاد از مثبت کاذب روی تصویر. این معمولا بستگی دارد روی وضوح تصاویری که با آنها کار می کنید و اندازه متوسط شی. در عمل، تا زمانی که عملکرد خوبی داشته باشد، به اندازه های معقول تست می رسد.
بیایید اندازه حداقل را روی آن تنظیم کنیم (0, 0)
برای دیدن آنچه که برداشت می شود:
در این تصویر، کرک دیگری وجود ندارد که بتوان آن را بهعنوان چشم طبقهبندی کرد، بنابراین ما فقط دو طبقهبندی اشتباه داریم. یکی در خود چشم و یکی روی چانه! بسته به روی رزولوشن تصویر و همچنین محتویات، تنظیم اندازه کم ممکن است قسمت خوبی از تصویر را به اشتباه برجسته کند.
process تشخیص اشیا برای تمام تصاویر دیگر یکسان است. شما در طبقه بندی کننده به درستی آموزش دیده بارگذاری می کنید، اجرا کنید
detectMultiScale()
و ترسیم کنید روی بالایdetected_objects
.
شایان ذکر است که می توانید چندین طبقه بندی کننده را با هم ترکیب کنید! به عنوان مثال، می توانید صورت، چشم ها و دهان یک فرد را به طور جداگانه تشخیص دهید و نقاشی کنید روی آنها را بیایید در این طبقهبندیکنندهها بارگذاری کنیم و از یک تصویر با رنگهای مختلف برای هر نوع شی استفاده کنیم:
import cv2
image_path = "face_image.jpg"
window_name = f"Detected Objects in {image_path}"
original_image = cv2.imread(image_path)
image_grey = cv2.cvtColor(original_image, cv2.COLOR_RGB2GRAY)
eye_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_eye.xml")
face_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_frontalface_alt.xml")
smile_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_smile.xml")
detected_eyes = eye_classifier.detectMultiScale(image_grey, minSize=(50, 50))
detected_face = face_classifier.detectMultiScale(image_grey, minSize=(50, 50))
detected_smile = smile_classifier.detectMultiScale(image_grey, minSize=(200, 200))
if len(detected_eyes) != 0:
for (x, y, width, height) in detected_eyes:
cv2.rectangle(original_image, (x, y),
(x + height, y + width),
(0, 255, 0), 2)
if len(detected_face) != 0:
for (x, y, width, height) in detected_face:
cv2.rectangle(original_image, (x, y),
(x + height, y + width),
(255, 0, 0), 2)
if len(detected_smile) != 0:
for (x, y, width, height) in detected_smile:
cv2.rectangle(original_image, (x, y),
(x + height, y + width),
(0, 0, 255), 2)
cv2.namedWindow(window_name, cv2.WINDOW_KEEPRATIO)
cv2.imshow(window_name, original_image)
cv2.resizeWindow(window_name, 400, 400)
cv2.waitKey(0)
cv2.destroyAllWindows()
در اینجا، ما در سه طبقه بندی بارگذاری کرده ایم – یکی برای لبخند، یکی برای چشم ها و دیگری برای چهره ها. هر کدام از آنها اجرا می شود روی تصویر و ما مستطیل ها را در اطراف ترسیم می کنیم همه اشیاء شناسایی شده، رنگ آمیزی مستطیل ها بر اساس کلاس شی:
لبخند به این خوبی گرفته نشد – شاید به این دلیل که لبخند در تصویر بسیار خنثی است. این یک نیست لبخند فراخ، که می توانست طبقه بندی کننده را از بین ببرد.
تشخیص اشیا در یک ویدیو با استفاده از OpenCV
با تشخیص اشیاء در تصاویر خارج از مسیر – بیایید به ویدیوها برویم. به هر حال ویدیوها فقط تصاویری هستند که پشت سر هم قرار گرفته اند، به همین ترتیب process اعمال می شود. با این حال، این بار، آنها اعمال می شوند روی هر فریم
برای شناسایی اشیاء در یک ویدیو، مرحله اولیه بارگذاری فایل ویدیویی در برنامه است. پس از بارگذاری فایل ویدئویی، باید داده های ویدئو را فریم به فریم جدا کرده و با استفاده از روش قبلی، تشخیص اشیا را انجام دهیم.
بارگیری یک ویدیو با استفاده از OpenCV
برای این راهنما، ما از یک ویدیوی رایگان در دسترس استفاده خواهیم کرد یک گربه روی یک درخت، ذخیره شده به عنوان cat-روی-tree.mp4
به صورت محلی به گفته سازنده ویدیو، استفاده از فایل رایگان است، بنابراین ما آماده ایم!
بیایید ابتدا ویدیو را بارگذاری کنیم و نمایش دهیم:
import cv2
import time
video_path = "cat-روی-tree.mp4"
window_name = f"Detected Objects in {video_path}"
video = cv2.VideoCapture(video_path)
while True:
ret, frame = video.read()
if not ret:
break
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
cv2.imshow(window_name, frame)
if cv2.waitKey(1) == 27:
break
time.sleep(1/30)
video.release()
cv2.destroyAllWindows()
این کد فایل ویدئویی را می خواند و محتویات آن را تا زمانی که کلید نمایش داده می شود نمایش می دهد Esc
کلید فشرده شده است VideoCapture()
برای خواندن فایل ویدیویی از مسیر استفاده می شود و اگر مقدار را بدهیم 0
در روش، وب کم را باز می کند و فریم ها را از ورودی می خواند. ما این کار را انجام خواهیم داد بعد و در حال حاضر با یک فایل ویدئویی محلی سر و کار داشته باشید.
اکنون، میتوانیم یک طبقهبندی کننده Haar-Cascade را مانند قبل اعمال کنیم روی هر تصویر در ویدیو:
import cv2
import time
video_path = "cat-روی-tree.mp4"
window_name = f"Detected Objects in {video_path}"
video = cv2.VideoCapture(video_path)
while True:
ret, frame = video.read()
if not ret:
break
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cascade_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_frontalcatface.xml")
detected_objects = cascade_classifier.detectMultiScale(
image, minSize=(50, 50))
if len(detected_objects) != 0:
for (x, y, height, width) in detected_objects:
cv2.rectangle(
frame, (x, y), ((x + height), (y + width)), (0, 255, 0), 15)
cv2.imshow(window_name, frame)
if cv2.waitKey(1) == 27:
break
video.release()
cv2.destroyAllWindows()
طبقه بندی کننده آموزش دیده است روی جلویی تصاویر گربه ها، به این معنی که واقعا نمی تواند پروفایل ها را تشخیص دهد. در بخش خوبی از ویدئو، گربه از نمایه ای قرار گرفته است، بنابراین تا زمانی که صورت خود را به سمت دوربین حرکت دهد – طبقه بندی های اشتباه زیادی وجود خواهد داشت.
اتفاقاً پسزمینه تار دارای ویژگیهایی است که طبقهبندیکننده احتمالاً بهعنوان صورت گربهای انتخاب میکند. اگرچه، هنگامی که سر خود را حرکت می دهد – به وضوح روی صورت خود قفل می شود.
این چیزی است که وقتی گربه به پهلو نگاه می کند طبقه بندی می کند:
و اینکه چگونه به درستی گربه را هنگام مواجهه با دوربین می گیرد:
ما واقعاً در حال شناسایی این جعبه ها هستیم به موقع در ویدیو ما همچنین میتوانیم این اشیاء شناساییشده را ذخیره کنیم (دوباره، فقط فهرستی از اعداد) و آنها را بهصورت آفلاین برای هر فریم ترسیم کنیم و ویدیو را دوباره رندر کنیم تا ذخیره شود. روی قدرت CPU در حالی که تشخیص در حال انجام است روی.
تشخیص شی در زمان واقعی با استفاده از OpenCV
باز هم تشخیص اشیاء در یک ویدیوی بلادرنگ هیچ تفاوتی با تشخیص از ویدیوها یا تصاویر ندارد. ما صورت گربه را در زمان واقعی شناسایی کرده ایم روی با این حال، ویدیو محلی بود.
بیایید یک جریان ویدیویی از یک وب کم دریافت کنیم! برای گرفتن ورودی از وبکم، باید تغییری جزئی در آن ایجاد کنیم VideoCapture()
زنگ زدن. همانطور که قبلا ذکر شد، به جای دادن یک مسیر فایل، به آن یک عدد می دهیم (در بیشتر موارد، 0
وقتی یک وب کم دارید):
import cv2
window_name = "Detected Objects in webcam"
video = cv2.VideoCapture(0)
while video.isOpened():
ret, frame = video.read()
if not ret:
break
cv2.imshow(window_name, frame)
if cv2.waitKey(1) == 27:
break
video.release()
cv2.destroyAllWindows()
توجه داشته باشید: در macOS، ممکن است لازم باشد قبل از اینکه این کار انجام شود، به ترمینال یا برنامه ای که ترمینال را اجرا می کند مجوز استفاده از وب کم بدهید.
اکنون برای انجام تشخیص اشیا بلادرنگ میتوانیم همان رویکردی را که با فایل ویدیویی انجام دادیم، یعنی جداسازی هر فریم و شناسایی اشیاء فریم به فریم و نمایش آنها به صورت هماهنگ دنبال کنیم:
import cv2
window_name = "Detected Objects in webcam"
video = cv2.VideoCapture(0)
while video.isOpened():
ret, frame = video.read()
if not ret:
break
image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cascade_classifier = cv2.CascadeClassifier(
f"{cv2.data.haarcascades}haarcascade_frontalface_default.xml")
detected_objects = cascade_classifier.detectMultiScale(
image, minSize=(20, 20))
if len(detected_objects) != 0:
for (x, y, height, width) in detected_objects:
cv2.rectangle(
frame, (x, y), ((x + height), (y + width)), (0, 255, 0), 5)
cv2.imshow(window_name, frame)
if cv2.waitKey(1) == 27:
break
video.release()
cv2.destroyAllWindows()
هنگامی که کد بالا را اجرا می کنید، یک پنجره از وب کم شما باز می شود و یک مستطیل می بینید که چهره شما را برجسته می کند! این کد به احتمال زیاد سریعتر از کد قبلی اجرا می شود، زیرا وب کم ها به طور کلی وضوح بسیار بالایی ندارند، بنابراین این تصاویر از نظر محاسباتی بسیار کم هزینه تر هستند.
اگر در اتاقی با نور مناسب بنشینید، یا اگر حداقل منبع نوری به سمت صورت خود دارید، کمک می کند.
نتیجه
در این راهنما، ما از OpenCV برای انجام تشخیص اشیا در پایتون با استفاده از طبقهبندی کننده Haar-Cascade استفاده کردهایم.
ما با طبقهبندیکننده، ویژگیهای Haar و تشخیص اشیا آشنا شدهایم روی تصاویر، فیلم ها در زمان واقعی و همچنین یک جریان ویدیویی از یک وب کم!
گام بعدی در تشخیص اشیا با استفاده از OpenCV، کشف طبقهبندیکنندههای دیگر است یولو و mobilenetv3 زیرا دقتی که از Haar Cascades دریافت می کنید در مقایسه با جایگزین های شبکه عصبی عمیق ضعیف است.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-07 09:00:06