ثبت تصویر image registration با استفاده از OpenCV

فرض کنید که یک تصویر هوایی از یک ناحیه شهر دارید و بعد از مدتی یک تصویر دیگر هوایی دریافت می‌کنید که بخش‌هایی از تصویر قبلی در آن موجود است. حالا می‌خواهید دو تصویر را به صورت اتوماتیک طوری روی هم قرار دهید که قسمت‌های متناظر روی هم بی‌افتند.  تصویر جدید و قدیم را باهم داشته باشید. یا فرض کنید از شهر یک سری عکس هوایی دریافت کرده اید که این عکس ها با هم اشتراک دارند و شما می‌خواهید آن‌ها را اتوماتیک به هم بچسبایند. یا فرض کنید از آسمان چندین عکس تهیه  کرده‌اید و می‌خواهید آن‌ها را کنار هم قرار دهید و یک تصویر واحد بسازید. به این کار ثبت تصویر یا image registration می‌گویند. در این پس می‌خواهیم این کار را با استفاده از پایتون و OpenCV انجام دهیم.

راه‌های مختلفی برای  این کار هست که امروز یکی از راه‌های ساده برای این کار را بررسی می‌کنیم و کدش را ارائه می‌دهیم. روش‌های بسیار متنوعی برای این کار وجود دارد و برای کابردهای مختلف روش‌های مختلفی وجود دارد. روش کلی برای انجام این کار وجود ندارد و باید برای کارهای مختلف روش های مختلفی ایجاد کرد تا بهترین نتیجه حاصل شود.

در پست بازشناسی یک شی در تصویر با استفاده از OpenCV در مورد نقاط کلیدی صحبت کردیم. یکی از بخش‌ها اصلی روش ارائه شده در این پست برای تبت تصویراستفاده از نقاط کلیدی و توصیفگر‌های ORB است.  تابع extract_orb برای تصویر یک سری نقطه کلیدی استخراج می‌کند و برای هر نقطه کلیدی یک توصیفگر ایجاد می‌کند.

 

تابع match_orb توصیفگرهای نقاط کلیدی دو تصویر مختلف را می‌گیرد و با استفاده از KNN دو نقطه کلیدی نزدیک به  هر نقطه کلیدی را پیدا می‌کند. در صورتی که فاصله توصیفگر نقطه کلیدی تا نقطه کلیدی اول به طرز قابل قبولی کمتر از فاصله نقطه کلیدی تا نقطه کلیدی دوم باشد، نشان می‌دهند که نقطه اول یک نقطه کلیدی متناظر خوب برای نقطه کلیدی است. در غیر این صورت از آن صرف نظر می‌شود و گفته می‌شود تطبیقی برای آن نقطه پیدا نشده‌است. خروجی این تابع اندیس نقاط کلیدی منطبق شده است.

 

فرض کنید که نقاط A را داریم و نقاط B نقاط متناظر با نقاط A در یک دستگاه مختصات دیگر هستند که با استفاده از نگاشت X[A]+Y = B به دست می‌آیند. حالا فرض کنید که نقاط A و نقاط B را داده‌اند و می‌خواهیم این نگاشت خطی را پیدا کنیم. برای این کار از تابع estimate_affine_transform استفاده می‌کنیم.

 

فرض کنید که نقاط A را در یک دستگاه مختصات داریم و می‌دانیم که اگر آن‌ها را با نگاشت خطی X[A] + ‌Y به یک دستگاه مختصات دیگر ببریم، نقطه متناظر نقاط A، نقاط B می‌شود. حالا فرض کنید که A و B را داریم ولی نگاشت خطی X[ ]+Y را نداریم. به ما یک نگاشت خطی P[ ] + Q می‌دهند و می‌خواهیم بدانیم که چقدر این  نگاشت خطی دقیق است و عمل نگاشت را درست انجام می‌دهد. برای این کار نقاط A را با استفاده از PA+Q به مختصات جدید می‌بریم و مجذور مربعات فاصله نقاط را با نقاط متناظرشان که B باشد می‌سنجیم. هر چه این مقدار کمتر باشد نشان می‌دهد نگاشت خطی داده شده بهتر است. این کاری است که تابع mse_error انجام می‌دهد.

 

 

همه نقاط متناظری که با استفاده از تطبیق نقاط کلیدی با استفاده از توصیفگر‌هایشان به دست آمد، تقاط متناظر خوبی نیستند و اشتباهاتی در آن‌ها موجود است. تابع RANSAC هر بار تعداد از نقاط را انتخاب می‌کند. سپس با استفاده از آن نقاط و تابع estimate_affine_transform یک نگاشت خطی پیدا می‌کند و سپس با استفاده mse_error دقت نگاشت به دست آمده برای سایر نقاط را می‌سنجد. اینگونه بهترین نگاشت را پیدا می‌کند و تناظر‌های خوب و بد را از هم تشخیص می‌دهد.

 

تابع affine_matrix نقاط کلیدی متناظر که توسط match_orb پیدا شده‌اند را می‌گیرد. سپس با استفاده از ransac تناظر‌های خوب از میان آن‌ها را پیدا می‌کند و تناظر‌های بد را کنار می‌گذارد. سپس با استفاده از تناظر‌های خوب پیدا شده توسط Ransac  و تابع estimate_affine_transform، ماتریس نگاشت خطی M را پیدا می‌کند.

 

تابع two_image_registraion_without_padding، دو تصویر را می‌گیرد و با استفاده از تابع‌هایی که گفته شده کار ثبت تصویر یا image registration را انجام می‌دهد. فقط مشکلی که این تابع دارد این است که بعد از انتقال تصویر اول به دستگاه مختصات تصویر دوم، ممکن است بخشی از تصویر اول بیرون بزند. این مشکل در تابع two_images_registraion_padding حل شده است.  تابع multiple_image_registration مانند تابع  two_images_registraion_padding است با این تفاوت که بیش از دو تصویر می‌گیرد.

 

کد کلی برنامه درانتهای مطلب آورده شده‌است. در ادامه به بعضی از نمونه‌های خروجی این برنامه می‌پردازیم:

 

نقشه تهران:

تصاویر ورودی:

 

 

خروجی الگوریتم:

 

تصویر هوایی تهران:

 

خروجی برنامه:

 

 

 

 

مقبره حکیم فردوسی:

 

 

خروجی برنامه:

 

راه شیری:

 

خروجی برنامه:

 

 

 

 

 

 

 

 

یک نظر

  • احمدرضا

    سلام وقت بخیر
    مطلب خیلی جالبی بود یادمه ترم ۲ ارشد، استاد پردازش تصویرمون یه فوق تمرین داده بود ۳ تا تصویر ماهواره‌ای ای بهمون داد که این ۳ تصویر بهم بچسبونید هرکاری کردم نشد!
    ممنونم استفاده بردیم

نظرتان را برای ما بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *