نمایش/عدم نمایش سایدبار
رفتن به بالای صفحه
أَللّهُمَّ ارْزُقْنی شَفاعَةَ الْحُسَیْنِ یَومَ الْوُرُودِ
مهدی دمیرچیلو

آموزش ماژول Background Subtraction در OpenCV

495

به نام خدا : تو این مطلب یه سری از الگوریتم ها رو خواهیم دید که برا پیدا کردن تصویر پس زمینه ( background ) و پیش زمینه ( foreground ) در شرایطی که دوربین ثابت هستش ( و حرکتی نداره ) بکار میرن؛ سایت OpenCV توضیحات زیادی ( تقریبا هیچی ) درباره این الگوریتم ها نداده و فقط چند مثال قرار داده! ما هم فعلا به همین اکتفا میکنیم تا مطالب بعدی ببینیم چی پیش میاد ( یعنی اگه نیاز شد، این مطلب رو تکمیل میکنیم وگرنه که هیچی )؛ ماژول Background Subtraction، زیر مجموعه ای از ماژول Video Analysis هستش.

آموزش ماژول Background Subtraction در OpenCV

 

Background Subtraction

Background Subtraction

در این مطلب با الگوریتم های تفریق پس زمینه ( background subtraction algorithms = BGS ) آشنا خواهیم شد.

تفریق پس زمینه یک مرحله پیش پردازش اصلی در بسیاری از برنامه های کاربردی پردازش تصویر است؛ به عنوان مثال، دوربین ثابتی را در نظر بگیرید که تعداد بازدیدکنندگانی را که وارد اتاق می شوند یا از آن خارج می شوند را شمارش میکند، یا دوربین ترافیکی که اطلاعات مربوط به وسایل نقلیه و... را استخراج میکند؛ در تمام این موارد، ابتدا باید فرد یا وسایل نقلیه را به تنهایی استخراج کنید؛ برای اینکار، شما باید پیش زمینه متحرک ( moving foreground ) را از پس زمینه ثابت ( static background ) استخراج کنید.

اگر تصویری از background به تنهایی دارید، مانند تصویری از اتاق بدون بازدیدکننده، تصویری از جاده بدون وسایل نقلیه و...، کار آسان است!؛ فقط تصویر جدید را از background کم کنید ( برای این کار از تابع cv::subtract میتونید کمک بگیرید )؛ نمونه کد برای استفاده از تابع cv::subtract :

Background Subtraction

اما در بیشتر موارد ممکن است تصویری از background نداشته باشیم، بنابراین باید background را از هر تصویری که داریم استخراج کنیم! ( که موضوع این مطلب هم همینه، معرفی توابع و کلاس ها -الگوریتم ها- یی برای انجام این کار )؛ وقتی سایه‌هایی ( shadows ) از وسایل نقلیه ( و افراد و ... ) وجود داشته باشد ( که همیشه وجود دارد! )، وضعیت پیچیده‌تر میشود!؛ از آنجایی که سایه ها نیز حرکت میکنند، تفریق ساده آن را نیز به عنوان پیش زمینه مشخص میکند و این، کار رو پیچیده میکند.

چندین الگوریتم برای این منظور معرفی شده؛ که خب یک سریاشون به بسته OpenCV راه پیدا کردن که در فایل background_segm.hpp قرار دارند؛ OpenCV یه صفحه جداگانه برای این قسمت با عنوان "Motion Analysis" ( تجزیه و تحلیل حرکت ) ایجاد کرده؛ فایل فوق، شامل کلاس های زیر هستش :

  • cv::BackgroundSubtractor ( کلاس پایه هستش؛ تمامی الگوریتم های این مطلب، از این کلاس مشتق شدن )
  • cv::BackgroundSubtractorKNN
  • cv::BackgroundSubtractorMOG2

یک سری دیگه از الگوریتم ها هنوز به بسته OpenCV راه پیدا نکردن و هنوز در بسته Contrib Modules قرار دارند که در فایل bgsegm.hpp قرار دارند؛ فایل فوق، شامل کلاس های زیر هستش :

  • cv::bgsegm::BackgroundSubtractorCNT
  • cv::bgsegm::BackgroundSubtractorGMG
  • cv::bgsegm::BackgroundSubtractorGSOC
  • cv::bgsegm::BackgroundSubtractorLSBP
  • cv::bgsegm::BackgroundSubtractorLSBPDesc ( الگوریتم نیست! )
  • cv::bgsegm::BackgroundSubtractorMOG
  • cv::bgsegm::SyntheticSequenceGenerator ( الگوریتم نیست! )

در عکس زیر لیست الگوریتم های این مطلب رو میبینید ( در این مطلب با الگوریتم های cuda کاری نداریم. ) :

OpenCV BackgroundSubtractor

 

ایجاد شیء و مقادر دهی اولیه

برای ایجاد شیء از کلاس های مربوط به الگوریتم ها , مقدار دهی اولیه شون، به صورت زیر عمل میکنیم، که برای هر الگوریتمی 2 حالت وجود داره! که خب روش اول ساده تره :

 

توابع اصلی این مطلب ( apply و getBackgroundImage )

تابع apply : محاسبه foreground mask؛ این تابع توسط تمام الگوریتم ها پشتیبانی میشود.

توضیح پارامترها :

  • image : فریم بعدی ویدئو.
  • fgmask : خروجی تصویر foreground mask با فرمت 8 بیتی باینری.
  • learningRate : مقدار بین 0 و 1، نشان دهنده سرعت یادگیری مدل background است؛ مقادیر منفی باعث میشود که الگوریتم از نرخ یادگیری انتخابی خودکار استفاده کند؛ 0 به این معنی است که مدل background اصلا به‌روزرسانی نمیشود؛ 1 به این معنی است که مدل background کاملاً از آخرین فریم دوباره مقداردهی اولیه شده است.

 

تابع getBackgroundImage : محاسبه تصویر background؛ این تابع توسط تمام الگوریتم ها  ( بجزء GMG و MOG ) پشیبانی میشود.

توضیح پارامترها :

backgroundImage : تصویر خروجی background، در این پارامتر ذخیره میشود.

 

توجه : تمامی الگوریتم ها، تابع apply رو پشتیبانی میکنند که foreground mask رو برای هر فریمی که بهشون بدیم رو محاسبه میکنند؛ به کمک این ماسک به راحتی میتونید پیش زمینه و پس زمینه هر فریم رو محاسبه کنید؛ اما تابع getBackgroundImage، میاد تصویر background رو تخمین میزنه با خوندن تعداد مشخصی از فریم ها؛ در ادامه مطلب ( در کد نمونه )، background های تولید شده الگوریتم های مختلف رو مقایسه میکنیم.

 

کد نمونه : در این کد یه فایل ویدئویی رو انتخاب میکنید، سپس الگوریتم رو انتخاب میکنید و در نهایت رو دکمه Start کلیک میکنید؛ برای تمامی الگوریتم ها تابع apply رو استفاده میکنیم و به کمکش foreground mask رو محاسبه میکنیم ( در زیر، عکسی از ماسک قرار ندادم دیگه، خودتون کد رو تست کنید و ببینید )، و تابع getBackgroundImage رو هم برای تمام الگوریتم ها  ( بجزء GMG و MOG ) استفاده کردم که نتیجه خروجی این تابع رو در انتهای همین کد مشاهده میکنید. ( در زیر فقط کدهای فایل CPP رو مشاهده میکنید، کدهای کامل در انتهای مطلب برا دانلود گزاشتم )

نتیجه کد بالا :

Background Subtraction

Background Subtraction

تصاویر زیر، برا فریم 100 ام و الگوریتم هم MOG2 باید باشه ( فک کنم ) :

2) foregroundMask 1) frame
OpenCV Background Subtraction OpenCV Background Subtraction
4) backgroundImage 3) foregroundImage
OpenCV Background Subtraction OpenCV Background Subtraction

توجه : همین کد تو C++ و Console، در مسیر زیر قرار داره :

[opencv]/samples/cpp/tutorial_code/video/bg_sub.cpp

 

 

تکمیل شود

  • mask چیست ؟ ( اصطلاحات مورد نیاز مطلب )
  • فرق background و foreground ؟! ( اصطلاحات مورد نیاز مطلب )
  • توضیح کلاس های الگوریتم ها و توابعشون
  • توضیح مختصری درباره هر الگوریتم
  • توضیح کامل الگوریتم ها
  • مقایسه الگوریتم ها
  • پروژه های بیشتر از الگوریتم ها

 

منابع :

 

مطالعه بیشتر : 

 

برچسب ها : برچسب/تگ یی پیدا نشد!
تعداد مطالب : 367 تا
جنگ ما فتح قدس را به همراه خواهد داشت. [ امام خمینی (ره) ]
بقیه جلسات : آموزش OpenCV
ارسال دیدگاه
0