پردازش تصویر با OpenCV - مقدماتی برای علاقه مندان به بینایی ماشین

https://www.vecteezy.com/free-photos/computer-vision
https://www.vecteezy.com/free-photos/computer-vision

دنیای بینایی ماشین یکی از جالب ترین و هیجان انگیزترین بخش رشته کامپیوتر هست، حداقل برای خود من. در عین حال فکر کنم بیش ترین میزان دانش در این شاخه وجود دارند که باید یاد بگیریم تا حتی بتونیم کار بقیه رو متوجه بشیم. خوشبختانه یک کتابخانه بسیار کامل وجود داره که شروع عملی کار با مفاهیم پردازش تصویر و بینایی ماشین رو ساده تر می کنه!

OpenCV یک کتابخانه پردازش تصویر شامل تابع ها و عملیات ها از پیش تعیین شده مانند فعالیت ها اصلی مثل خواندن و نوشتن تصویر یا ویدیو، تغییر سایز تصویر و دسترسی به پیکسل ها تصویر گرفته تا الگوریتم ها ماشین لرنینگ مثل شبکه ها عصبی، تشخیص لبه و خیلی دیگه از این‌جور کار ها هست. شما هم می تونین با نصب کردنش، با توابعی که در اختیار می ذاره، کارها مربوط به پردازش تصویرتون رو انجام بدین.

در تمام پلتفرم هایی که می تونید برنامه نویسی کنید می تونید از این کتابخانه استفاده، چه ویندوز، مک، یا لینوکس. از زبان های زیادی هم پشتیبانی می کنه مثل جاوا، پایتون، سی++،‌ و غیره ولی خود کتابخانه تو سی++ نوشته شده.

عکس به عنوان ماتریس

اگر تاحالا براتون سؤال شده که عکس ها چطوری در کامپیوتر ذخیره سازی شدن، اول اینکه تسلیت می گم چون مثل خودم دبیرستان سخت، تنها و بدون دوستی داشتید. دوم اینکه تبریک می گم چون قراره الان بهتون جواب بدم. خلاصه بخوام بگم ماتریسه!

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

عکس هایی که رنگی هستن از این سه رنگ تشکیل می شن (RGB یا Red-Green-Blue). معمولاً هم برای توصیف این عکس ها از لفظ سه کاناله استفاده می کنند، یعنی از سه تا کانال که هر سه رنگ اون پیکسل رو مشخص می کنند تشکیل شده. تلویزیون های سیاه و سفیدی که قبلاً وجود داشتن؟ اونارو میتونیم فقط با یه عدد توصیف کنیم بین 0 تا 255 میشه. اون موقع عکس ما تک کاناله است.

حالا ماتریس کجای داستانه؟ خب منطقاً یک مجموعه ای از این پیکسل ها یک عکس رو تشکیل می دن، چطوری؟ مثلاً یک عکس 720p از 1280 سطر و 720 تا ستون پیکسل تشکیل شده که معمولاً به این شکل نشونش میدن: 1280x720

نصب و کار با OpenCV

من فرض می کنم که شما دوست دارید که با پایتون کار کنید. اگه دوست دارید با زبان ها دیگه کار کنید، می تونید برید مطالب مخصوص به همان زبان رو بخونید. بیش تر توابعی که استفاده می کنیم در همه زبان ها یکسان هست، فقط یک سری نکات خاص خودشون وجود داره.

من همینطور فرض می کنم با پایتون آشنایی دارین و می تونین یه فضا مجازی درست کنید. خوشبختانه opencv در pip وجود داره، پس صرفاً می تونین با pip install opencv-python نصبش کنید. فقط حواستون باشه که اسمش cv2 هست پس با import cv2 می تونید بهش تو کدتون دسترسی پیدا کنید.

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

ما می تونیم با تابع imread این عکس را بخوانیم و به عنوان متغیر ذخیره کنیم. Opencv این متغیر رو به نوع Mat می شناسه، پس هر جا دیدید به یک Mat نیاز داشت منظور همین عکسمونه.

حالا ما می تونیم به تک تک پیکسل هاش دسترسی داشته باشیم.

اگه توجه داشته باشین وقتی هر کدوم رو پرینت می کنیم، یک لیست 3 تایی می گیریم، این سه تا مقادیر قرمز، سبز و آبی عکس هست.

حتی می تونیم مقدار هر پیکسل رو دستی تغییر بدیم.

اما معمولاً کار با تک تک پیکسل ها کار بسیار زمانگیر و غیر بهینه است، برای همین در مواقع عادی همچین کار هایی انجام نمی دید.

خود عکس هم یه چند تا مقادیر داره که می تونیم نگاه بندازیم.

ما می تونیم عکس هامون رو هم ذخیره کنیم! با imread عکس رو خوندیم، حالا imwrite می تونیم عکس تغییر داده شده رو ذخیره کنیم.

برای نشون دادن این کار، می تونیم یک عکس رنگی رو بگیریم و سیاه و سفیدش کنیم. خیلی مواقع برای ساده کردن کار با عکس ها برای مواردی مثل تشخیص چهره و غیره، لازمه که سه کانال رنگ رو دور بریزیم تا کار با داده ها ساده تر بشه.

اینم نتیجه اش:

اگه دقت کنید در خروجی کنسول عکس بالاتر دیگه مقدار کانال رو نمی نویسه، این یعنی تعداد کانال هامون یک شده.

حالا تمام این کارهایی که انجام دادیم رو می تونستیم تو فتوشاپ هم انجام بدیم، داستان از اینجا جالب می شه که بتونیم کارها نسبتاً پیشرفته تر انجام بدیم. مثلاً بریم ببینیم opencv می تونه چهره نازنین من رو تشخیص بده؟

اینجا کدی ساده برای این کار نوشتم و تو کامنت ها مشخص کردم هر مرحله چه اتفاقی داره می اوفته.

اینم نتیجه اش:

نمی دونم درباره اینکه مو دستم رو به عنوان چهره تشخیص داد چی فکر کنم…
نمی دونم درباره اینکه مو دستم رو به عنوان چهره تشخیص داد چی فکر کنم…

خب دیدید این کتابخانه قابلیت ها خیلی زیادی در اختیارتون قرار می ده تا با عکس ها کار کنید. هر اون چیزیکه اینجا براتون گفتم حتی نوک انگشت قابلیت های این کتابخانه نیست. من هم بعد از این که نوشتن این مطلب رو تموم کردم، شروع می کنم به یادگیری و کار با قابلیت های دیگه اش. امیدوارم شما هم با من شروع کنید!

منتشر شده در شماره چهارم نشریه دانشجویی بیت