مقدمه ای بر پردازش تصویر

به نام خدا و با سلام

در این مطلب قصد دارم توضیحاتی پیرامون نحوه شروع و یادگیری پردازش تصویر برای آن دسته از علاقه مندان بدهم. شاید عبارت بینایی ماشین به گوش برخی از افراد خورده باشد. در نگاه اول این موضوع قابل درک نیست که چگونه می توان برای یک ماشین یا ربات برنامه ای نوشت که بتوان به عنوان چشم برای آن عمل کند. حتی سوالات بنیادی تری مانند “انسان چگونه می بیند و اشیا را تشخیص می دهد؟” نیز ممکن است رخ بدهد. اجازه بدهید ابتدا مقایسه ای بین بینایی انسان و ماشین داشته باشیم.

   عضوی که در بدن انسان وظیفه دریافت تصاویر از محیط را دارد چشم است که معادل این عضو در ربات می تواند دوربین باشد. پس مشکلی در مورد این قطعه نداریم. سوال اصلی نحوه تشخیص و درک محیط پیرامون است!! اشیای فراوانی در پیرامون انسان وجود دارد. ممکن است یک انسان برخی از اشیا را تا به حال ندیده باشد ولی این بدان معنی نیست که نتواند محدوده ای برای آن شی تعیین کند (شی ناشناخته شبیه به چه شی شناخته شده برای انسان است). بیایید و خیلی ساده در مورد این موضوع حرف بزنیم. فرض کنید برای اولین بار یک مداد به شما می دهند و شما تابحال مشابه این وسیله را ندید. خب چه چیزی را از این شی در ذهن خودتان باید ذخیره کنید تا در آینده بتوانید دوباره این جسم را تشخیص بدهید؟

  1. ابعاد مداد (نسبتاً باریک است، سطح مقطع تقریباً گرد، طولی به اندازه ۱۵ سانتی متر و یا کمی بیشتر یا کمتر)
  2. شکل ظاهری (سر مداد باریک تر و تیز تر از بقیه جاهای مداد است)
  3. کاربرد (با فشار دادن آن بر روی کاغذ خط هایی پدید می آید)
  4. مکانی که شی را در آن دیده اید (مکان هایی که احتمال وجود چنین شی زیاد است)
  5. رنگ شی

   شاید عوامل دیگری هم وجود داشته باشد ولی در همین حد بسنده می کنیم. اگر به ویژگی های بالا نگاه کنید می توان این گونه برداشت کرد با در اختیار داشتن ویژگی های ظاهری اشیا، آنها را دسته بندی کرد. بنابراین به هنگام برخورد با اشیای دیگر در صورتی که تشابه زیادی به یک دسته باشد، آن را عضوی از آن دسته در نظر می گیریم. مثلاً میوه ها، ماشین، میز، صندلی و… . ویژگی شماره ۴ در مورد مکانی که شی در آن قرار دارد بود. یعنی چه؟؟ فرض کنید یک نوع از میوه را تابحال ندیده و در مورد آن چیزی نشنیده اید. اما آن را در ظرف میوه ها و به همراه برخی از میوه های شناخته شده می بینید. بنابراین از آن جایی که این میوه مجهول در ظرف میوه و کنار ویه های شناخته شده است، می توان با احتمال بالایی حدش شد که شی مجهول میوه باشد. اما ویژگی شماره ۵ چی؟ اکنون تصور کنید که به باغ میوه ای رفته اید و فاصله شما تا درختان آنقدر زیاد است که نمی توانید دقیق در مورد نوع میوه ها اظهار نظر کنید. پس ویژگی های ظاهری را نمی توان تشخیص داد ولی رنگ را می شود شناسایی کرد. پس اگر رنگ های در محدوه قرمز مشاهده کردید احتمال می دهید که ممکن است میوه مجهول سیب، شلیل، هلو و یا میوه هایی با این رنگ باشد. پس با احتمال نسبتاً خوبی میوه های نامربوط حذف و تعداد اندکی به عنوان گزینه تقریباً درست باقی می ماند. سوال دیگری ممکن است در این جا مطرح شود. انسان چگونه حرکت جسام را تشخیص می دهد؟ پاسخ این سوال نیز ساده است. به صفحه نمایش کامپیوتر خود نگاه کنید. همه چیز در جای خودشان هستند. چیزی تغیرر وضعیت نمی دهد. حال ماوس را تکان دهید. در کسر کوچکی از ثانیه حرکت ماوس را تشخیص داده و با چشمان خود آن را دنبال خواهید کرد. اما چگونه توانستید به این سرعت حرکت ماوس را تشخیص دهید؟ به این سوال هم پاسخ خواهم داد. در صفحه نمایشگر کامپیوتر شما هیچ چیزی تغییر وضعیت نمی دهد و مغز یک تصویر از نمایشگر را در خود ذخیره می کند. حال با تکان دادن ماوس تغییری در این تصویر رخ خواهد داد (تغییر در پیکسل های تصویر است) و ذهن سریعاً می تواند مکانی که تغییر در آن رخ داده شناسایی و چشم ها را به آن سمت هدایت کند. اکنون سوال دیگری که پیش می آید این است: “ربات چگونه این کارها را انجام می دهد؟”.

   انجام پردازش تصویر همانند هر نرم افزار دیگری نیازمند یک محیط برنامه نویسی، کتابخانه ها و پکیج های لازم است. نرم افزارها و کتابخانه های زیادی برای این منظور آماده شده است. به عنوان نمونه، شما می توانید از زبان های C و یا Python برای برنامه نویسی استفاده کنید. با انتخاب یک محیط برنامه نویسی حال نوبت به تهیه پکیج ها و کتابخانه های لازم برای انجام پردازش تصویر می رسد. شاید معروف ترین پکیجی که در این زمینه وجود دارد OpenCV باشد (Open source computer vision)؛ چرا که دارای بیشترین و کامل ترین دستورات و توابع برای انجام کارهای پردازش است. برای مثال توابع آماده ای برای تشخیص یک رنگ مشخص، تشخیص لبه ها، فیلترهایی برای حذف نویزهای فرکانس بالا، مشخص کردن محیط های (Contours) بسته یا باز، استفاده از دستورات اشباع (Threshold) به منظور حذف سایه و تولید یک تصویر باینری (سیاه و سفید)، دستوراتی برای دنبال کردن اشیا و تعداد بسیار زیادی از توابع مفید دیگر. از دیگر پکیج های مفید در این زمینه می توان به Scikit-learn اشاره کرد که دارای توابعی هست که برمبنای یادگیری ماشین نوشته شده اند. یعنی کاربر نیازی به دانستن یادگیری ماشین و یا کدنویسی برای آن ندارد و فقط کافیست از توابع این پکیج استفاده کند. در پست های پیشین (دسته بندی رنگ های تصویر توسط الگوریتم K-means) مثالی برای این مورد زدیم که رنگ های موجود در تصویر را به دسته هایی تقسیم بندی کنیم و برای این کار از تابع means که بر پایه یادگیری ماشین است استفاده کردیم.

   پس به سوال آخر هم جواب دادیم. یک ربات برپایه توابع از پیش نوشته شده می تواند تا حدودی شبیه به چشم انسان کار کند. اما “چگونه پردازش تصویر را یاد بگیریم؟”. بگذارید مجدداً با یک مثال توضیح بدهم. هنگامی که شما تصمیم به یادگیری یک زبان برنامه نویسی می کنید یک خط مشخی را دنبال می کنید. اول نحوه تعریف تابع و مقداردهی به آن، در مرحله دوم کار با اعداد و عملگرهای ریاضی و منطقی، سپس کار با رشته ها، تعریف تابع و… . اما پردازش تصویر این چنین نیست (حداقل برای من اینطور نبود). در پردازش تصویر بسیاری از توابع به خودی خود کاربرد ندارند بلکه در کنار توابع دیگر اهمیت پیدا می کنند. یک مثال خوب بزنیم. در پست (اسکن مدارک با استفاده از OpenCV و Python)، کدی نوشتیم تا عکس گرفته شده از یک سند را به حالت اسکن شده تبدیل کند. برای این منظور دو کار مهم باید انجام می دادیم:

  1. عکس گرفته شده را از حالت پرسپکتیو خارج کنیم
  2. عکس را از رنگی حالت سیاه و سفید تبدیل کنیم

   مرحله اول را توضیح می دهم. تابعی برای برگرداندن تصویر از حالت پرسپکتیو می نویسیم. اما این کار چگونه انجام خواهد شد؟ پاسخ ساده است، استفاده از ماتریس انتقال. برای این کار لازم است که شما مختصات اولیه و نهایی هر نقطه (پیکسل) از تصویر را داشته باشید. مختصات نهایی را خودمان می توانیم بدست آوریم اما مختصات اولیه نقاط چی؟ برای این کار باید گوشه های تصویر را پیدا کنیم. برای پیدا کردن گوشه ها باید یک چند ضلعی مشایه تصویر اصلی تخمین بزنیم. برای تخمین زدن چند ضلعی لازم محیط های بسته (Contours) درون تصویر را پیدا کنیم. برای پیدا کردن محیط های بسته باید لبه های تصویر پیدا شوند. برای آن که لبه ها پیدا شوند باید جسم به حالت سیاه و سفید در بیاید. پس ملاحظه می کنید که برای انجام یک کار ساده، مجموعه ای از توابع دست به کار می شوند و هر کدام وظیفه خاصی را بر عهده می گیرند.

   هدف اصلی من از مثال بالا این بود که اگر شما فقط توضیحات مربوط به تابع cv2.findContours را بخوانید اصلاً مفید نخواهد بود (این تابع محیط های بسته یا باز را چیدا می کند)؛ بلکه لازم است برخی از توابع مرتبط به این تابع هم به یاد داشته باشید. مثلاً اگر قبل از پیدا کردن محیط های بسته، تصویر را از یک فیلتر عبور دهید، نتیجه خیلی بهتر می شود. و یا اینکه دستور cv2.findContours، فقط بر روی تصاویر باینری (سیاه و سفید) عمل می کند. پس شاید بهترین روش برای یادگیری پردازش تصویر، مطالعه مثال های عملی و کاربردی باشد؛ چرا که نحوه ارتباط توابع با یکدیگر را مشخص می کنند. و این امر به شما کمک می کند تا در مورد هر کاری کی الگوی مشخص در ذهنتان ذخیره شود. یعنی دفعه بعدی که بخواهید محیط بسته ای در یک تصویر بیابید می دانید که پیش از آن چه کارهایی باید انجام دهید.

   مطمئناً این کار سختی های خودش را دارد ولی به شما اطمینان می دهم که با این کار خیلی حرفه ای تر پردازش تصویر را یاد خواهید گرفت.

mehdi sehati

در این سایت پروژه و آموزش های انواع ماژول ها و میکروکنترلر ها و نحوه ارتباط سخت افزار با نرم افزار (برنامه نویسی اندروید برای گوشی و برنامه نویسی سی شارپ برای کامپیوتر) و برنامه نویسی پایتون و رسبری پای و ماژول های وای فای قرار میگیرد همچنین دوستان برای توضیحات بیشتر و سفارش پروژه میتوانند به آی دی تلگرام بنده مراجعه کنند

مطالب مرتبط

Subscribe
Notify of
guest

0 نظرات
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x