تصاویر دودویی و حد آستانه

به طور کلی ، عکس ها به سه دسته تقسیم می شوند :

  • باینری یا دودویی(Binary)
  • مقیاس خاکستری (Gray scale)
  • رنگی (Color)

تحلیل تصاویر باینری

زمانی که یک تصویر را آنالیز می کنیم یک سری 0 و 1 به دست می آید.
0، پس زمینه را نشان می دهد.
1، پیش زمینه را نشان می دهد.

                                    

کاربرد های تحلیل تصاویر باینری :

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

 

(عکس سمت راست خوب باینری نشده است( مناسب نبودن مقدار حد آستانه))

 

 کارهایی که می توانیم با باینری کردن تصاویر انجام دهیم :

  • جدا کردن یک شی از پس زمینه
  • متراکم کردن پیکسل های یک شی
  • محاسبه و استخراج ویژگی های یک شی

مثال – تصویر سلول گلبول قرمز

کاربرد: برای مثال برای تسریع در شمارش گلبول‌های قرمز در تصاویر پزشکی می‌توان از پردازش تصویر استفاده کرد.

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

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

عملکرد های مفید

  • آستانه گذاری یک تصویر در مقیاس خاکستری ( gray scale )
  • تعیین کردن حد آستانه مناسب
  • تحلیل اجزای متصل به هم
  • مورفولوژی دودویی ریاضی
  • انواع استخراج ویژگی، ثابت ( محیطی، مرکزی، مداری، …)

آستانه گذاری

تعریف مختصر:

برای تبدیل یک تصویر gray scale یا مقیاس خاکستری به تصویر دودویی باید یک حد آستانه (Threshold) تعیین کنیم و تمام پیکسل‌های دارای مقدار کمتر از حد آستانه را 0 و تمام پیکسل‌های دارای مقدار بیشتر از حد آستانه را 1 (یا 255) کرد.

آستانه گذاری در OpenCV:

همان طور که بیان شد برای تبدیل تصویر gray scale به تصویر دودویی از آستانه گذاری استفاده میکنیم.

در OpenCV نیز این عملیات پیاده سازی شده و اگر مقدار پیکسلی بیشتر از مقدار threshold ( حد آستانه ) باشد، یک مقدار به آن تعلق می گیرد ( ممکن است آن مقدار سفید باشد. )
درغیر آن صورت مقدار دیگری به آن تعلق می گیرد ( ممکن است آن مقدار سیاه باشد. )

تابعی که در OpenCV برای آستانه گذاری  استفاده می شود، cv2.threshold می باشد

  • پارامتر اول آن تصویر منبع (  image ) می باشد که باید یک تصویر در مقیاس خاکستری ( gray-scale ) باشد.
  • پارامتر دوم، مقدار حد آستانه ( threshold ) می باشد، که برای دسته بندی مقادیر پیکسل ها استفاده می شود.
  • پارامتر سوم، بیشترین مقدار ( Max value ) می باشد، که مقداری را نشان می دهد که اگر پیکسلی از مقدار حد آستانه ( threshold value ) بیشتر ( در مواردی ممکن است کمتر ) باشد، Max value به آن مقدار تعلق میگیرد.
  • پارامتر چهارم مربوط به نوع است. OpenCV حالت های مختلفی برای آستانه گذاری تعیین کرده است :
  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

 

 مثال آستانه گذاری

آستانه گذاری به روش Ostu 

در آستانه گذاری سراسری ( global thresholding )، یک مقدار دلخواه برای مقدار حد آستانه ( threshold ) استفاده می شود.
سوالی که پیش می آید این است که مقدار انتخاب شده مناسب است یا خیر؟!
پاسخ : متد آزمایش و خطا
اما با فرض یک تصویر biomodel، ( به بیان ساده تر، تصویر biomodel  تصویری است که histogram دو قله ( یا حداکثر ) دارد. )
برای این تصویر ما می توانیم تقریبا حد وسط قله ها را برای مقدار حد آستانه در نظر بگیریم. یعنی کاری که در روش ostu انجام می شود. به صورت خودکار مقدار حد آستانه از تصویر histogram  برای  تصویر biomodel  محاسبه می شود.

مثال: پس زمینه مشکی است و گیلاس سالم روشن است و قسمت های ضرب دیده تیره متوسط است.

نمودار هیستوگرام (Histogram) دو قسمت از گیلاس را نشان می دهد. ( پس زمینه ی مشکی حذف شده است. )

 

 

در پردازش تصویر، (balanced histogram thresholding (BHT یک متد بسیار ساده است (مثل روش ostu ) و متد lterative selection thresholding یک histogram بر مبنای متد آستانه گذاری ( thresholding ) می باشد.
این رویکرد تصویر را به دو کلاس اصلی تقسیم می کند :

  • پس زمینه ( Background )
  • پیش زمینه ( Foreground )

BHT سعی دارد سطح آستانه ( threshold ) را بهینه کند و histogram را به دو کلاس تقسیم می کند.
این متد histogram را می سنجد که بررسی می کند کدام بخش سنگین تر است و وزن را از بخش سنگین تر حذف کند تا روشن تر شود.

آستانه گذاری تطبیقی

در موارد قبلی، ما از مقدار های سراسری ( global ) به عنوان مقدار حد آستانه ( threshold value ) استفاده کردیم. اما در همه ی شرایط ممکن نیست این مقدار مناسب باشد؛ مثلا در مکانی که عکس شرایط روشنایی متفاوتی دارد، در این موارد ما به آستانه گذاری تطبیقی ( Adaptive theesholding ) رجوع می کنیم که الگوریتم، مقدار حد آستانه را برای نواحی کوچک تصویر محاسبه می کند. بنابراین ما به حد آستانه های متفاوتی برای نواحی مختلف همان تصویر می رسیم.
نتیجه: آستانه گذاری تطبیقی ( adaptive thresholding )، نتایج بهتری برای تصاویر با روشنایی متفاوت به نمایش می گذارد.

متد تطبیقی

  • cv2.ADAPTIVE_THRESH_MEAN_C  مقدار حد آستانه ( threshold )، میانگین مقادیر نواحی همسایه می باشد.
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C  مقدار حد آستانه ( threshold )، جمع وزنی مقادیر نواحی همسایه می باشد.

آستانه گذاری در پایتون و OpenCV

آستانه گذاری در پایتون و numpy

در ابتدا با numpy تصویر را باینری می‌کنیم.

در این کد با بارگذاری کردن تصویر gray scale، به رنگ های کمتر از حد آستانه ( 127 ) را صفر تعلق می گیرد ( سفید ) و به رنگ های بیشتر از حد آستانه ( 127 )  255 تعلق می گیرد.( سیاه )

نکته :
دلیل اینکه از np.copy استفاده می کنیم این است که اگر به این صورت باشد : ( Newimage = image )
در واقع به یک مکان از حافظه دو اشاره گر اشاره می کند که در این صورت عکس اصلی ( اولیه) خراب می شود.

آستانه گذاری در OpenCV

برای اینکار می‌توانیم از تابع threshold در opencv نیز استفاده کنیم

پس از بارگذاری عکس، این بار به کمک تابع threshold که در آن حد آستانه 127 تعیین شده است، به مقادیر کمتر از این مقدار 0 تعلق می گیرد و به مقادیر بیشتر از این مقدار 1 تعلق می گیرد و نوع آن به صورت باینری (سیاه و سفید) تعیین شده است. ( در اینجا ret نشان دهنده ی حد آستانه است. )

پارامترهای مختلف تابع threshold

در این کد پارامتر چهارم (threshold types) بررسی شده است.

  : cv2.THRESH_BINARY

به مقادیر کمتر از حد آستانه (  127 )،  0 تعلق می گیرد ( سفید ) و به مقادیر بیشتر از حد آستانه،  255 تعلق می گیرد ( سیاه ).

 : cv2.THRESH_BINARY_INV

به رنگ های کمتر از حد آستانه (  127 )، 255 تعلق می گیرد ( سیاه ) و به رنگ های  بیشتر از حد آستانه،  0 تعلق می گیرد ( سفید ).(برعکس مورد قبل)

 : cv2.THRESH_TRUNC

مقادیر بیشتر از حد آستانه بریده می شوند. ( 255 بدون استفاده می ماند. )

 : cv2.THRESH_TOZERO

مقادیر بیشتر از حد آستانه تغییر نمی کنند. و به مقادیر کمتر از حد آستانه، 0 تعلق می گیرد.

 : cv2.THRESH_TOZERO_INV

مقادیر کمتر از حد آستانه تغییر نمی کنند.و به مقادیر بیشتر از حد آستانه، 0 تعلق می گیرد.

یک مثال عملی از دودویی کردن تصویر در OpenCV

در ابتدا به کمک فیلتر ها نویزها را برطرف می کنیم زیرا thresholding ها local هستند باعث ایجاد نویز در تصویر می شوند.در آخر از ostu استفاده می کنیم چون ostu حد آستانه را مشخص می کند تصویر بهتری در خروجی نشان می دهد. ( ممکن است در روش های قبل threshold حد آستانه را درست تعیین نکرده باشیم. )

خروجی ها به صورت زیر است :

نتیجه گیری : ostu تصویر بهتری در خروجی نشان می دهد.

 

threshold Binary

: Adaptive thresholding

: Gaussian ostu thresholding 

 : ostu thresholding

 : Adaptive thresholding with Gaussian

دستکاری تصاویر (۶) – فیتلرها در Open CV و حذف نویز تصاویر

در قسمت قبلی با کرنل‌ها و نحوه کارکرد آن‌ها و استفاده از آنها برای ایجاد فیلتر روی تصاویر آشنا شدیم؛ حال با اعمال فیلتر روی تصاویر با استفاده از کتابخانه Open CV و توابع مربوطه آشنا می‌شویم.

اعمال فیلتر‌های دو بعدی رو تصویر

با استفاده از Open CV اعمال فیلتر‌های دو بعدی توسط کرنل بر روی تصاویر توسط تابع زیر انجام می‌شود:

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

فیلتر محوی (Blur Filter)

همانطور که در پست قبل دیدیم برای محو کردن تصویر می‌توانیم یک کرنل Moving Average را بر روی تصویر اعمال کنیم. این کرنل یک ماتریس با مجموع جملات ۱ است و هرچه کرنل بزرگ‌تر باشد میزان تاری تصویر بیشتر خواهد شد.

کرنلی که در دفعه قسمت اول برای تاری استفاده شده است یک ماتریس ۳*۳ با عناصر ۱ است که از آنجا که مجموع عناصر ماتریس باید ۱ باشد تقسیم بر ۹ شده است. همچنین برای قسمت دوم از ماتریس بزرگتر ۵*۵ استفاده شده و تقسیم بر ۲۵ شده است.

برای اعمال فیلتر Blur می‌تواند از تابع اختصاصی زیر نیز استفاده کرد:

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

دیگر فیلتر‌های Blur

در Open CV علاوه بر کرنل Box (کرنل Moving Average مورد استفاده تا الان) برای محو کردن تصویر لکرنل‌های گوسین (Gaussian)، مدین (Median) و دوجانبه (Bilateral) نیز پشتیبانی می‌شوند.

فیلتر Gaussian Blur

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

فیلتر Median Blur

این فیلتر متوسط مقدار پیکسل‌هایی که درون کرنل قرار می‌گیرند را به عنوان مقدار نهایی پیکسل قرار می‌دهد.

فیلتر Bilateral Blur

این فیلتر سعی می‌کند درحالی که تصویر را محو می‌کند لبه‌های تصویر را تیز و دست نخورده نگاه دارد. به دلیل همین ویژگی این فیلتر در حذف نویز کاربرد زیادی دارد.

 

حذف نویز تصویر

برای حذف نویز تصویر می‌توان از تابع زیر که از روش میانگین گیری استفاده می‌کند کمک گرفت:

پارامتر‌های تابع عبارت‌اند از:

  • src : عکس مورد نظر برای حذف نویز
  • dst : متغیری برای ذخیره کردن عکس خروجی – با دادن none به این پارامتر، خروجی تابع عکس خروجی خواهد بود.
  • h : این پارامتر قدرت فیلتر را برای میزان شدت نور تنظیم می‌کند. هرچه مقدار این پارامتر بزرگتر باشد علاوع بر حذف نویز ممکن است از جزئیات تصویر نیز بکاهد و هرچه کوچکتر باشد جزئیات تصویر را نمی‌کاهد اما ممکن است نویزها را به درستی کاهش ندهد (بازه ۵ تا ۱۰ برای این پارامتر مناسب است).
  • hcolor : همانند h برای مولفه‌های رنگی
  • templateWindowSize : سایز گیره محاسبه کننده وزن‌ها (باید عددی فرد باشد).
  • searchWindowSize : سایز کرنل محاسبه کننده میانگین وزن‌دار برای هر پیکسل (باید عددی فرد باشد).

 

بر اساس نوع تصویر چهار تابع محتلف برای کاهش نویز توسط روش میانگین گیری وجود دارد

  • ()cv2.fastNlMeansDenoising : یا یک تصویر Grayscale کار می‌کند.
  • ()cv2.fastNlMeansDenoisingColored : با یک تصویر رنگی کار می‌کند.
  • ()cv2.fastNlMeansDenoisingMulti : با رشته‌ای از عکس‌های Grayscale که با فاصله زمانی کم گرفته شده‌اند کار می‌کند.
  • ()cv2.fastNlMeansDenoisingColoredMulti : مانند قبلی برای عکس‌های رنگی.

دستکاری تصاویر (۵) – فیلترها و کرنل‌ها

در قسمت قبل با عملیات‌های ریاضی ماتریس‌ها آشنا شدیم. در این قسمت می‌خواهیم به نحوه اعمال فیلتر‌های مختلف روی تصاویر با استفاده از عملیات‌های ریاضی روی ماتریس تصاویر بپردازیم.

برای شروع به چند تعریف نیاز داریم:

تصویر

همانطور که می‌دانید تصویر یک ماتریس است که در هر خانه مقادیر رنگ آن خانه (با توجه به سیستم رنگی مورد استفاده) قرارگرفته اند.

کانولوشن (Convolution)

کانولوشن درواقع یک عملگر ریاضی است که بر روی دو تابع اعمال شده و تابع سومی را به صورت انتگرال حاصلضرب دو تابع که یکی از آنها برعکس شده و روی یکدیگر می‌لغزند تعریف می‌کند.

کراس‌کرولیشن (Cross-correlation)

کراس‌کرولیشن میزان شباهت و ارتباط دو دسته اطلاعات را می‌سنجد. این عملگر همانند عملیات کانولوشن بوده با این تفاوت که در این عملیات تابع عبوری برعکس نمی‌شود.

 

در پردازش تصاویر، توابع ما درواقع ماتریس‌های تصاویر هستند. به ماتریس عبوری (اعمال شده) به تصویر کرنل می‌گوییم. همچنین در پردازش تصاویر (در عموم کتابخانه‌‌های مطرح و همینطور Open CV) از عملیات کراس‌کرولیشین استفاده می‌شود.

کرنل

کرنل، ماتریس عموما کوچکی است که روی تصویر اعمال می‌شود. از کاربردهای آن می‌توان در پردازش تصویر برای اعمال فیلتر‌های مختلف برروی عکس و در یادگیری ماشین برای ویژگی‌یابی اشاره کرد.

 

حال که با تعاریف اولیه مورد نیاز آشنا شدیم به نحوه استفاده و نتیجه آن روی تصاویر می‌پردازیم:

اعمال کرنل روی تصویر

 

در اعمال کرنل روی تصویر نیاز داریم تا با عبور کرنل بر روی تصویر و انجام عملیات کراس‌کرولیشن نتیجه عملیات در خانه‌ای از خانه‌‌های کرنل (که روی تصویر قرار‌گرفته اند) نگاشته شود. برای این‌کار عموما خانه وسط ماتریس کرنل را در نظر می‌گیرند؛ درنتیجه عموم کرنل‌های مورد استفاده ماتریس‌هایی فرد-فرد هستند.

برای عبور کرنل بر روی تصویر می‌توان دو رویه داشت:

  • کانولوشن بدون حاشیه‌گذاری (Valid Padding Convolution)
    عبور کرنل به صورتی که خانه اول ماتریس کرنل (خانه [۰.۰]) بر روی خانه اول ماتریس تصویر بیافتد و کرنل از تصویر خارج نشود.
    این روش باعث از دست رفتن قسمت‌هایی از حاشیه تصویر می‌شود.
نحوه عبور یک ماتریس کرنل بر روی یک ماتریس تصویر و انجام عملیات کراس‌کرولیشن
نحوه عبور کرنل روی ماتریس تصویر و انجام عملیات کراس‌کرولیشن در حالت Valid Padding

 

  • کانولوشن با حاشیه‌گذاری (Same Padding Convolution)
    عبور کرنل به صورتی که خانه مرکز کرنل (خانه‌ای که برای نوشتن مقادیر عملیات در هر مرحله انتخاب شده) بر روی خانه اول ماتریس تصویر بیافتد.
    در این حالت کرنل می‌تواند از تصویر خارج شود که مقادیر خارج از تصویر عموما صفر در نظر گرفته می‌شوند.
نحوه عبور کرنل روی ماتریس تصویر و انجام عملیات کراس‌کرولیشن در حالت Same Padding

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

 

به جز دو روش فوق برای جلوگیری از کوچک شدن تصویر می‌توان از روش‌های تکرار حاشیه تصویر (Edge Value Replication) و یا گسترش آینه‌وار (Mirror Extension) نیز استفاده کرد:

از راست به چپ: گسترش آینه‌وار، تکرار حاشیه تصویر و حاشیه‌گذاری

استفاده از کرنل‌ها

چند مثال از کرنل‌ها با فرض اینکه خانه وسط هر کرنل برای نوشتن مقادیر استفاده شود و همچنین خانه وسط بر روی هر پیکسل قرارگیرد و کرنل در هر مرحله یک پیکسل جابه‌جا شود :

کرنل تطابق

با توجه به کرنل با جابه‌جا شدن روی تصویر تغییری روی تصویر اعمال نمی‌کند چرا که با قرارگیری روی هر پیکسل تنها مقدار همان پیکسل بدون تغییر روی خودش نوشته می‌شود.

کرنل انتقال به چپ

با توجه به کرنل با جابه‌جا شدن روی تصویرو قرار گیری روی هر پیکسل مقدار پیکسل سمت راستش را جایگزین آن می‌کند. درنتیجه تصویر ۱ پیکسل به سمت چپ میرود.

 

 

حال که با نحوه اعمال کرنل‌ها و نتیجه حاصل از آن آشنا شدیم، به بررسی استفاده از کرنل‌ها برای ایجاد فیلتر روی تصاویر می‌پردازیم:

استفاده از کرنل‌ها برای ایجاد فیلتر روی تصاویر

فیلتر محوی (Blur Filter)

با عبور یک کرنل Moving Average (کرنل تصویر پایین) که کرنلی با مجموع مقادیر ۱ است و مقدار هر خانه را با میانگین مقدار خانه‌های همسایه‌اش جایگذین می‌کند، می‌توان تصویر را محو کرد.

 

این کرنل تغییرات ناگهانی در رنگ تصویر را ملایم‌تر می‌کند. به تصویر زیر که عبور کرنل بالا بر روی یک ماتریس است دقت کنید:

 

همچنین با افزایش سایز کرنل می‌توان میزان تاری تصویر را افزایش داد:

 

فیلتر تیزی (Sharpen Filter)

کرنل زیر را در نظر بگیرید:

می‌توان این کرنل را به صورت زیر باز کرد:

ماتریس سمت راست همان کرنل مربوط به فیلتر محوی (Blur) است که تصویر را بدون جزئیات تولید می‌کند؛ با تفریق این ماتریس از خود تصویر (ماتریس وسط) جزئیات تصویر اصلی حاصل می‌شود؛ حال با اضافه کردن این ماتریس به خود تصویر می‌توان جزئیات تصویر را به آن افزود و تصویری با جزئیات نمایان‌تر شده تولید کرد.

نتیجه حاصل از جدا کردن جزئیات و اضافه کردن آن به عکس را می‌توان به ترتیب در سطر‌های تصویر زیر مشاهده کرد:

درنتیجه فیلتر تیزی (Sharpen Filter) به صورت زیر است:

 

دستکاری تصاویر (۴) – عملیات ریاضی و ترکیب تصاویر رنگی در OpenCv

یادآوری چگونگی سر ریز شدن متغیر ها 

با توجه به اینکه برای تصاویر در OpenCV از نوع داده‌ای unit8 یعنی عدد صحیح بدون علامت ۸ بیتی استفاده میکنیم . پس این نوع ۳ به توان ۸ یعنی ۲۵۶ مقدار مختلف میتواند داشته باشد و مقادیر خارج از ۰ تا ۲۵۵ امکان پذیر نبود و در صورتی که عددی بزرگتر قرار نسبت داده شود متغیر سر ریز می‌شد.

به قطعه کد زیر توجه کنید.

در کد بالا ماتریس دو عنصری a که عناصر آن همه ۱ هستند ، بعد از اینکه عناصرش ۱۰۰ برابر میشوند و به علاوه ۲۵۵می شنود ماتریس [۲۵۵ ۲۵۵] ساخته میشود ولی بعد از افزایش به اندازه ی ۱۶۰ واحد در هر عنصر از ماتریس b ماتریس [۴ ۴] ساخته میشود چون سرریز صورت گرفته ( مقدار بیش از ۲۵۵) و دوباره مقدار مربوطه از ۰ شروع شده است .

خروجی کد فوق :

طبیعتا این موضوع برای جمع دو ماتریس هم اندازه نیز صادق است:

در کد بالا m1 و m2 دو ماتریس به ترتیب به مقادیر :

هستند.که بعد از عملیات جمع این دو ماتریس دو درایه ی سطر دوم به دلیل سرریز مقادیر ۰ و ۱ را میگیرند.

خروجی کد:

برای حل این مشکل ( خراب نشدن عناصر بر اثر overflow ) راه حل هایی از جمله راه حل زیر وجود دارد :

در کد مشاهده شده ماتریس m1 را داریم که می خواهیم مقدار را به تمام درایه های آن بیفزاییم . براثر این عملیات مقادیری از ماتریس اصلی که بیشتر از ۱۵۰ یا مساوی ۱۵۰ هستند وقتی با ۱۰۰ جمع شوند سر ریز میشوند . برای جلوگیری از این موضوع میتوانیم درایه هایی که مقدارشان بیشتر یا مساوی ۱۵۰ هستند برابر با بیشترین مقدار ممکن یعنی ۲۵۵ قرار داده و عملیات جمع را برای بقیه ی درایه ها انجام دهیم .

خروجی کد:

 

حل مشکل با  OpenCV :

اگر از توابع cv2.add و cv2.subtract استفاده کنیم این مشکل را مشاهده نخواهیم کرد و مقادیر کمتر از ۰ همان ۰ و مقادیر بیش از ۲۵۵ همان ۲۵۵ باقی خواهد ماند.
به کد مقابل توجه کنید :

در این قطعه کد تصویری را خواندیم و سپس ماتریسی با اندازه ی تصویر خوانده شده ساختیم که تمام عناصرش ۱۰۰ هستند ، سپس این ماتریس را با تصویرمان جمع کردیم و چون ازتابع add در opencv استفاده کردیم خرابی در تصویر نهایی مشاهده نشد ، و به طور مشابه عمل subtract را انجام دادیم .

تصویر Orginal  :

orginal

تصویر Add شده :

تصویر Subtract شده :

 

مثال عملی ترکیب تصاویر رنگی :

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

 img1 :                                                        img1  img2 :
img2

result :

حل این مشکل با ترکیب دو تصویر با جمع وزن‌دار :

برای حل این مشکل میتوانیم با نسبت های مختلف ، مثلا  ۰.۵ و ۰.۵ یا ۰.۳ و ۰.۷  و یا…. نسبت هایی که مشابها جمعشان  ۱ گردد تصاویر را جمع کنیم .

تابع مورد نظر به شکل زیر می باشد :

addWeighted(src1, alpha, src2, beta, gamma)

که آلفا و بتا در فرمول دوم مشاهده میشود.

g(x)=(1−α)f0(x)+αf1(x)
dst=α⋅img1+β⋅img2+γ

 با این عمل میتوانیم تاثیر هر تصویر را بعد از عملیات جمع در تصویر نهایی دستکاری کنیم :

 

 img1 :                                                        img1  img2 :
img2

result :

 

عملیات بیتی (Bitwise Operations) و نقاب‌گذاری تصویر (Masking) :

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

همانطور که قابل مشاهده است ، در صفحه ای به اندازه ی ۳۰۰ در ۳۰۰ که تمام عناصر ماتریس آن صفر هستند ( صفحه ی تمام سیاه ) یک مربع سفید در وسط صفحه از مختصات (۵۰ ، ۵۰) تا (۲۵۰ ، ۲۵۰) رسم میکنیم ، سپس در صفحه ای مشابه به رسم نیم دایره میپردازیم.

تصاویر به این شکل خواهند بود :

عملیات بیتی تصویر در OpenCV :

حال به بررسی ۴ عملیات

  • bitwise_and
  • bitwise_or
  • bitwise_xor
  • bitwise_not

روی تصاویر خواهیم پرداخت :

عملیات bitwise_and :

در نتیجه ی عملیات and بین دو تصویر قسمت هایی که پیکسل در هر دوی آن تصاویر ۱  ( سفید ) است ، سفید ( مقدار 1 ) باقی خواهد ماند ، و بقیه ی پیکسل ها صفر ( سیاه ) خواهند بود و نتیجه به این شکل خواهد بود :

عملیات bitwise_or :

در نتیجه ی این عملیات قسمت هایی از تصویر نهایی سفید ( مقدار یک ) خواهد بود که مربع یا نیم دایره در آن نقاط سفید باشند.
و نتیجه به این شکل خواهد بود :

عملیات bitwise_xor :

در نتیجه ی عملیات xor ، قسمت هایی از تصویر که مربع و نیم دایره تفاوت بیتی ( یکی صفر و دیگری یک ؛ یکی سیاه و دیگری سفید ) دارند ، سفید می شود.
نتیجه شکل زیر خواهد بود :

عملیات bitwise_not :

این تابع نیز قسمت هایی از تصویر که بیت ۰ دارند ۱ میکند و بلعکس ( پیکسل های سیاه را سفید میکند و پیکسل های سفید را سیاه )

مثال عملی با تصویر رنگی :

اگر تصویر گاو اصلی را crop کنیم و سپس با این تصویر  and کنیم :

با توجه به اینکه میدانیم هر چیزی که با ۱ ، and شود ، حاصل خود آن میشود ، و هرچیزی که با ۰ ، and شود حاصل ۰ خواهد بود پس در نتیجه تصویر به این شکل در خواهد آمد :

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

برای درک عملگر بیتی دو تصویر به مثال زیر توجه کنید :

خروجی به شکل زیر خواهد بود :

نصب کتابخانه Keras بر پایه ی کتابخانه TensorFlow

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

اول از همه، برای یادآوری باید بگم که طبق تیتر مطلب، کتابخانه Keras (زین پس کراس) بر پایه ی کتابخانه های مختلفی نوشته شده که به دلیل تازه تر بودن، قوی تر بودن و همگانی تر شدن کتابخانه TensorFlow (زین پس تنسرفلو) ما قصد نصب برپایه این کتابخانه را داریم.

* برای شروع حتما نسخه 64 بیتی پایتون های 3.6 و یا 3.5 را نصب کنید. (آیا پایتون من 64 بیتی است؟)


نصب مبتنی بر CPU : 

نصب تنسرفلو به کمک Pip :

نصب تنسرفلو  به کمک Conda :

 

* مشکل در نصب : اگر با دستورات فوق موفق به نصب نشدید به این لینک رجوع کنید.

آیا تنسرفلوی من نصب شده است؟ برای اطمینان این کد را اجرا و از نصب درست کتابخانه مطمئن شوید.

نصب ابزار های مورد نیاز :

و در نهایت نصب کراس به کمک Pip :

نصب کراس به کمک Conda :

آیا کراس من نصب شده است؟ برای اطمینان این کد را اجرا و از نصب درست کتابخانه مطمئن شوید.

In :

Out :

 

 


نصب مبتنی بر GPU : 

برای اینکه بتونیم محاسبات رو با کارت گرافیک خودمون انجام بدیم نیاز به کارت گرافیک NVIDIA هست که در ادامه متوجه خواهید شد آیا شما می توانید از این روش استفاده کنید یا خیر!

 

نصب ابزار CUDA (پیش نیاز) :

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

برای شروع با طی کردن این مسیر از مدل کارت گرافیک خود آگاه بشوید :

Windows + R > control /name Microsoft.DeviceManager >  Display Adapters

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

سپس حتما نسخه 9.0 را دانلود و نصب نمایید و آدرس آن را در %PATH% قرار دهید. (لینک)

* مشکل در نصب : به این لینک مراجعه کنید.

نصب ابزار cuDNN (پیش نیاز) :

حتما نسخه 7.0 را دانلود و نصب نمایید و آدرس آن را در %PATH% قرار دهید. (لینک)

* توجه : حتما نسخه ذکر شده را نصب کنید و از وجود فایل cuDNN64_7.dll مطمئن شوید!

* مشکل در نصب : به این لینک مراجعه کنید.

نصب تنسرفلو به کمک Pip :

نصب تنسرفلو  به کمک Conda :

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

به زودی تکمیل می شود ..


محیط مجازی (virtualenv) : 

به طور خلاصه، برای جدا و ایزوله سازی وابستگی های یک پروژه از سایر پروژه ها از این قابلیت استفاده می شود. در ادامه به کمک این امکان، یک ورژن خاص از پایتون را بر روی محیط مجازی خودمون نصب می کنیم. (راه حلی برای نصب تنسرفلو از طریق کوندا بر روی پایتون 3.5 در حین داشتن ورژن 3.6)

* توجه : قبل از این عملیات ها، ورژن پایتون مورد استفاده خود را نصب نمایید.

نصب ابزار virtualenv :

ایجاد محیط جدید :

فعال کردن محیط در لینوکس :

 

فعال کردن محیط در ویندوز :

 

تبریک! حالا شما می تونید پکیج های مورد نظر خودتون رو در محیط ایجاد شده بدون ایجاد هیچگونه اختلالی در محیط های دیگر نصب نمایید.

برای deactive کردن، حذف و سایر اطلاعات مربوطه به این منبع مراجعه کنید.


  محیط مجازی در کوندا (virtualenv) : 

ایجاد محیط جدید :

فعال کردن محیط در لینوکس :

فعال کردن محیط در ویندوز :

حال می توانید پکیج های خود را بر روی محیط جدید نصب کنید.

نصب مستقیم پکیج در هنگام ساخت محیط جدید (راه دوم)

نصب ادیتور مخصوص محیط جدید

حال شما ادیتور لازم در کوندا و برای محیط جدید خودتون رو ایجاد و باز کرده اید

* توجه : در صورت عدم دسترسی cmd را در مود administrator باز کنید.

برای deactive کردن، حذف و سایر اطلاعات مربوطه به این منبع مراجعه کنید.

 


لینک منبع تنسرفلو : https://www.tensorflow.org/install/#pip_installation_on_windows

لینک منبع کراس : https://www.pyimagesearch.com/2016/11/14/installing-keras-with-tensorflow-backend/

 

دستکاری تصویر (3) – مثال‌های عملی در OpenCV

تبدیلات همگن (Affine Transform) 

انتقال (Translation) :

برای پیاده سازی این تبدیلات  از cv2.warpAffine استفاده میکینم.

به طور مثال در کد زیر :

پس از خواندن عکس  و دریافت عرض و طول تصویر:

یک نسبت دلخواه برای انتقال طول و عرض تصویر در نظر گرفتیم :

با استفاده از ضرب ماتریس انتقال در مختصات تصویر ،تصویر انتقال پیدا میکند :

از warpAffine برای تبدیل عکس استفاده میکنیم که ورودی های آن به صورت زیر است :

چرخاندن  (Rotations) :

*یادآوری

ماتریس دوران:

 

 

 

دوران در opencv

  • از نقص های این روش میتوان به ایجاد فضاهای سیاه اطراف تصویر اشاره کرد که در ادامه فضاهای سیاه ایجاد شده اطراف تصویر را با کراپ از بین میبریم.

روشی دیگر برای دوران :

ترانهاده ماتریس

ماتریس ترانهاده  با تغییر جای سطر ها با ستون ها باعث چرخش تصویر میشود و فضای سیاه اطراف تصویر ایجاد نمی کند .

flip  تصویر

تصویر را در جهت افق و خط عمود آینه می کند.

پارامتر دوم :

صفر یا false عکس را حول محور x  ها قرینه میکند.

یک یا True عکس را حول محور y ها قرینه میکند.

تغییر اندازه (scaling, resizing) و درون‌یابی (interpolations)

  • fx  و fy  پارامتر های  نام دار هستند میتوان آنها را به تابع پاس نداد.

روش های درون یابی :

  1.  Bilinear Interpolation (درج وابسته به ۴ پیکسل ۴ طرف)
  2.  Bicubic interpolation (درج وابسته به ۴ پیکسل ۴ طرف به علاوه ۴ پیکسل اریب)
  3.  Nearest Neighbor (نزدیکترین همسایه)

استفاده از ماتریس تبدیل

جهت هایی را که میخواهیم  scale شوند را در قطر ماتریس قرار میدهیم.

معایب :

  1. مشکل سیاهی تصویر را دارد.
  2. عکس بعد از اعمال interpolations باید crop شود .

Image Pyramids

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

در این روش عکس را به صورت پلکانی به سایز های مختلف  می بریم :

کاربرد: آموزش به هوش مصنوعی برای تشخیص اشیاء

Cropping

Opencv تابع مشخص برای کراپ کردن ندارد.

روش های جایگزین :

یکی از روش های کراپ کردن slicing است که با دادن بازه ی دقیقی از  x ,y (برای ساده تر شدن عکس را بصورت دو بعدی و سیاه سفید تصور میکنیم)همان بازه ی مشخص شده را کراپ می کنیم.

نکات :

مختصات شروع و پایان حتما  باید اعداد صحیح باشند.

در بازه نویسی به صورت   [ x1 : x2 , y1:y2 ] :

x1 شامل بازه میشود اما x2 نوشته نمیشود .

روش دیگر اسلایس کردن ماتریس  ها به کمک  numpy است.

مثال:

a=np.array([[100,200,400],[1,2,3]])

میخواهیم  عناصر سطر اول [0] و ستون دوم [1]  را انتخاب کنیم.

a [0: , 1:] => array([[200, 400],[ 2, 3]])

 

دستکاری تصویر (2) – دوران، انتقال، مقیاس و درون‌یابی

Rotation (دوران)

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

تابعی که در opencv برای این کار گمارده شده است به صورت زیر است:

 

که آرگومان اول و دوم به ترتیب x و y مرکز دوران را میگیرند و آرگومان بعدی زاویه چرخش و آرگومان اخر آپشن اضافه ای در اختیار ما قرار داده است و عددی برای بزرگنمایی یا کوچک نمایی تصویر میگیرد و بدون درگیر کردن ما با ماتریس چرخش و سینوس و کسینوس این تبدیل را به خوبی انجام میدهد.=)

خروجی این تابع؛ ماتریس چرخش یا دوران می باشد.که میتوان با تابع پرینت آن را نمایش داد.

اما برای بدست آوردن تصویر دوران یافته کافیست از تابع زیر استفاده کرده و این ماتریس چرخش را به آن بدهیم و در خروجی این تابع عکس دوران یافته را بگیریم.

 

2D Translation (انتقال دوبعدی)

برای انتقال یک نقطه از مکانی به مکان دیگر از ماتریس زیر استفاده میکنیم:

که در اینجا:

x´ = x + Tx = 1 * x + 0 * y + Tx

y´ = y + Ty =  0 * x + 1 * y + Ty

و به این صورت میتوانیم تصویر را جابجا کنیم.

به صورت خلاصه تر این ماتریس به این صورت بیان میشود:

1 ها مقدار مقیاس گذاری را مشخص میکنند یعنی 1 خانه ی (0 و 0) نشان دهنده scale در راستای ایکس و 1 خانه ی (1 و 1) نشان دهنده scale  در راستای ایگرگ میباشد.که چون در اینجا مقادیر 1 هستند یعنی اندازه ی تصویر بدون تغییر میماند  و بزرگ نمایی یا کوچک نمایی انجام نمیشود.

تابعی که برای این کار در opencv در نظر گرفته اند بدین صورت است:

 

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

و خود ماتریس انتقال را میتوانیم بدین صورت بسازیم:

Np.float32([[1 , 0 , tx] , [0 , 1 , ty]])

Scalling (مقیاس گذاری)

ما اگر بخواهیم مثلا یک ماتریس 2 در 2 را به ماتریس 6 در 6 تبدیل کنیم یک سری نقاط(پیکسل) را نداریم.

با این 4 روش میخواهیم این نقاط را بسازیم.

  1.  Nearest Neighbor (نزدیکترین همسایه)
  2.  Bilinear Interpolation (درج وابسته به ۴ پیکسل ۴ طرف)
  3. Bicubic interpolation  (درج وابسته به ۴ پیکسل ۴ طرف به علاوه ۴ پیکسل اریب)
  4. استفاده از ماتریس تغییر شکل (با استفاده از تابع warpaffine با ارقام دلخواه و ترتیب گفته شده در ماتریس scalling، که در ابتدا آمده است)

این مقیاس گذاری دو حالت دارد:

  • بزرگ نمایی
  • کوچک نمایی

روش نزدیکترین همسایه(ساده ترین روش):

در این روش مثلا فلان پیکسل را نسبت می بندیم که آن روی یک پیکسل متناظرش در ماتریس جدید می افتد پس همان مقدار پیکسل را به آن میدهیم.سپس پیکسل دیگری را بررسی میکنیم که مثلا هیچ پیکسلی را متناظرش در ماتریس جدید نمی یابیم و در آن پیکسل مقدار نزدیکترین پیکسل را قرار می دهیم.

روش درج وابسته به۴ پیکسل ۴ طرف:نسبت به روش قبلی دقیقتر است.همانطور که مشخص است مقادیر 4 پیکسل اطراف را میانگین گرفته و پیکسل های خالی را پر میکنیم.

روش درج وابسته به ۴ پیکسل ۴ طرف به علاوه ۴ پیکسل اریب: همانطور که مشخص است مقادیر 16 پیکسل اطراف را میانگین گرفته و پیکسل های خالی را پر میکنیم. این روش از همه دقیقتر و کندتر است(به دلیل محاسبات بیشتر).

حال میخواهیم تابعی در opencvکه این کار را انجام میدهد بیان کنیم:

 

آرگومان اول تصویر مورد نظر است.آرگومان بعدی سایز عکس خروجی ست و دو آرگومان بعدی مقدار یا درصد مقیاس گذاری را مشخص میکند.(مثلا اگر عدد ۲ را به هردو آنها پاس دهیم یعنی میخواهیم تصویر در راستای طول و عرض ۲ برابر شود) و آرگومان اخر روش مقیاس گذاری(که در بالا توضیح دادیم) را تعیین میکند.خروجی این تابع نیز تصویر scale شده میباشد.

توجه:اگر هم اندازه تصویر خروجی را پاس دهیم هم مقادیر مقیاس گذاری؛ تابع اندازه را بر عدد یا درصد مقیاس ترجیح داده و آن را عملی میکند.

در آخر مقایسه انواع  روش های scaleرا باهم میبینیم:

دستکاری تصویر (1) – ماتریس‌های تبدیل

در جلسات قبل با مفهوم فضاهای رنگی آشنا شدیم و خواندیم که هر عکس رنگی از سه کانال رنگی (R,G,B) تشکیل شده است که هر کدام می توانند از صفر تا 255 مقدار بگیرند .

و اگر ما دستور image.shape  را برای یک عکس رنگی چاپ کنیم خروجی اینچنین خواهد بود

(height,width,3)

که عدد 3 نشان دهنده ی وجود هر سه کانال رنگی قرمز، سبز و آبی است اما اگر عکس را در حالت سایه و سفید (gray scale) ببریم خروجی دستور تنها طول و عرض عکس خواهد بود و دیگر تنها یک کانال رنگی وجود دارد که به صورت باینری است و صفر نشان دهنده ی نبود رنگ و 1 بیش ترین مقدار وجود رنگ را نشان میدهد(صفر نشان دهنده رنگ سیاه و یک نشان دهنده ی رنگ سفید است).

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

 

که خروجی آن برای هر کانال به صورت زیر خواهد بود:

 

 

تا اینجای کار با مفاهیم اولیه ی open cv  آشنا شدیم اکنون میخواهیم وارد مبحت image manipulations بشیم که لازمه ای این مبحث این هستش که یه دوره ی سریعی روی مباحث جبر خطی که عمدتا در هندسه تحلیلی عنوان شده داشته باشیم .

انواع روش های image manipulations  یا دستکاری تصویر:

  • انتقال های همگن یا غیر همگن ( (Transformations, affine and non affine
  • تبدیلات (Translations)
  • Rotations (دوران)
  • Scaling, re-sizing and interpolations  ( درون یابی یا interpolations به معنای این است که در هنگام تغییر سایز عکس پیکسل هایی که خالی میماند را با چه الگوریتمی میخواهیم پر کنیم.)
  • Image Pyramids

انتقال

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

تبدیلات همگن

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

بدین ترتیب در نتیجه یک تبدیل همگن، تمامی نقاط روی یک خط در ورودی، در خروجی نیز روی یک خط خواهند ماند.

  • انتقال، تجانس، تشابه و چرخش نمونه هایی از تبدیل های همگن هستند.

نکته هر تبدیل خطی همگن هست اما هر تبدیل همگنی خطی نیست.

 

معرفی وکتور

یک بردار یک بعدی است. که دو نوع دارد وکتور ستونی و سطری:

1)وکتور ستونی    2) وکتور سطری

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

نحوه محاسبه نرم اقلیدسی:

اگر دو وکتور به نام های A,B  داشته باشیم نرم اقلیدسی آن برابر است با

ماتریس

ماتریس همان بردار mxn است که در برنامه نویسی نیز همین معنا را دارد و یک عکس سیاه و سفید درواقع یک ماتریس  است که به میزان عرض عکس سطر و ارتفاع آن ستون دارد و هر درایه نمایانگر یک پیکسل است که میتواند ازصفر تا 255 مقدار بگیرد.

عکس رنگی نیز در واقع شامل سه ماتریس است که هر کدام از آنها مقدار یکی از کانالهای رنگی را نگه میدارد.

عملیات های ماتریسی در پایتون

جمع ماتریس ها با یکدیگر

جمع یک ماتریس با عدد ثابت

که در آن تک تک خانه های ماتریس با عدد جمع خواهند شد.

ضرب ماتریس در یک عدد ثابت یا scale

که در آن تک تک خانه های ماتریس در عدد ضرب خواهند شد.

 

نرم اقلیدسی در ماتریس ها

که دارای ویژگی های زیر است

  • مقدار آن همواره بزرگتر مساوی صفر است.
  • اگر صفر شود تک تک درایه های ماتریس باید صفر شوند .
  • به ازای هر
  • به ازای هر 

 

برای یاد آوری ضرب ماتریس ها میتوانید اینجا را کلیک کنید.

معرفی چند ماتریس خاص

ماتریس همانی:  یک ماتریس مربعی است کهتمامی درایه های روی قطر اصلی یک و سایر آنها صفر هستند.

ماتریس قطری: یک ماتریس مربعی است که درایه های روی قطر اصلی عدد دارند و سایر آنها صفر هستند.

ماتریس ترا نهاده: ماتریسی است که جای سطر و ستون هایش باهم عوض شده باشند.

ماتریس انتقال: ماتریسی است که برای انتقال بردار ها از طریق ضرب استفاده میشود.

نکاتی درباره ی ضرب ماتریس ها:

  • ضرب ماتریس ها خاصیت جابه جایی ندارد AB!=BA.
  • تنها میتوان ماتریس های مربعی را به توان رساند.

مقدمات OpenCV، خواندن و نمایش تصاویر، فضاهای رنگی

برای استفاده از پکیج opencv در برنامه خود باید عبارت  “import cv2” را در اول برنامه نوشته شود و همچنین برای استفاده از کتابخانه numpy دربرنامه خود باید عبارت  “import numpy as np” نوشته شود برای اینکه کلمه numpy کمی طولانی میباشد از کلمه np به جای آن استفاده میشود که کوتاه تر است . که با اضافه کردن as np  این کار صورت میگیرد.

برای اینکه از پکیج opencv استفاده شود باید cv2. نوشته شود و بعد آن توابعی را که از آن کتابخانه احتیاج داریم را بنویسیم .

برای اینکه از پکیج opencv استفاده شود باید cv2. نوشته شود و بعد آن توابعی را که از آن کتابخانه احتیاج داریم را بنویسیم .

برای load (بارگذاری)  یک عکس در برنامه باید از عبارت ()cv2.imread  استفاده کنیم که در پکیج opencv قراردارد.

در آرگومان اول باید آدرس کامل آن عکس که میخواهید بارگذاری شود را بدهید و دقت کنید که باید فرمت عکس هم نوشته شود که در مثال بالا عکس دارای فرمت jpg میباشد.

آرگومان دوم آن یک flag میباشد که راهی که عکس باید خوانده شود را تعیین میکند.

  • Cv2.IMREAD_COLOR : عکس رنگی را بارگذاری میکند.از شفافیت عکس غفلت خواهد شد. این یک flag پیش فرض میباشد.
  • Cv2.IMREAD_GRAYSCALE : عکس سیاه سفید را بارگذاری میکند.
  • Cv2.IMREAD_UNCHANGED :عکس را به صورتی که کانال alpha را داراست بارگذاری میکند.

میتوان به جای این سه flag از پاس دادن عدد 1 و 0 و 1- به ترتیب استفاده کرد.

برای مثال کد زیر را ببینید:

برای نمایش یک عکس در یک پنجره باید ازتابع ()cv2.imshow استفاده کرد که این پنجره به صورت اتوماتیک  با اندازه عکس متناسب میشود برای مثال:

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

آرگومان دوم آن نام عکسی است که میخواهیم نمایش داده شود.

عبارت “cv2.waitKey”  یک تابع اجباری است که به ما اجازه میدهد تا زمانی که پنجره عکس باز است اطلاعات را دریافت کنیم.

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

اگر به این تابع 0 پاس دهید این تابع تا زمانی که کلیدی فشرده شود منتظر میماند.

تابع “cv2.destroyAllWindows” تمام پنجره های ساخته شده را خراب میکند که اگر یادتان برورد این عبارت را بنویسید برنامه شما هنگ میکند.

اگر شما بخواهید فقط یک پنجره مشخص را خراب کنید باید از تابع “cv2.destroyWindow”  استفاده کنید .

برای ذخیره کردن عکس در کامپیوتر خود باید ازتابع ()cv2.imwrite استفاده کرد که آرگومان اول آن نام فایل و آرگومان دوم آن عکسی است که میخواهید ذخیره شود برای مثال با نوشتن عبارت “cv2.imwrite(‘output.jpg’, input)” عکس input با اسم output و با فرمت jpg در کامپیوتر ذخیره میشود.

اگر با اجرای این خط کلمه true  چاپ شد یعنی این عکس با موفقیت ذخیره شده.

برای فهمیدن سایزعکس باید از “print (input.shape)” استفاده کنیم که عبارت print هر چه که در پرانتز از آن خواسته شده باشد را چاپ میکند که چون ما سایز عکس خود را میخواهیم باید input.shape را به آن پاس بدهیم. برای مثال این عبارت را چاپ میکند (600, 800, 3) که پارامتر اول آن ارتفاع عکس بر حسب پیکسل و دومی عرض عکس بر حسب پیکسل و سومی کانال های عکس میباشد که در اینجا کانال های عکس 3 میباشد به این معنی است که عکس رنگی میباشد یعنی سه کانال RGB را داراست و اگر کانال سوم 0 بود یعنی عکس سفید سیاه (grayscale) میباشد به صورت زیر:

 

تغییر فضای رنگی

در opencv بیشتر از 150 متد تبدیل فضای رنگی وجود دارد.

برای تبدیل کردن فضای رنگی از تابع “cv2.cvtcolor(input_image , flag)” استفاده میشود که flag نوع تبدیل را تعیین میکند.

برای تبدیل BGR به Gray از  فلگ “cv2.COLOR_BGR2GRAY”  استفاده میشود و همچنین برای تبدیل Gray به BGR از فلگ “cv2.COLOR_GRAY2BGR”  استفاده میشود.

 

یک فضای رنگی مفید دیگر HSV میباشد.

برای HSV رنج Hue برابر [0,179] و رنج  saturation برابر [0,255] و رنج Value برابر [0,255] میباشد.

برای تبدیل BGR به HSV از فلگ  “cv2.COLOR_BGR2HSV”  استفاده میشود.

با این تبدیل ما میتوانیم یک شی رنگی استخراج کنیم.در HSV فهمیدن یک رنگ خیلی آسون تر از فضای رنگی RGB میباشد.

تصویر زیر یک تصویر HSV میباشد.

تصویر زیر کانال Hue میباشد.

تصویر زیر کانال saturation میباشد.

تصویر زیر کانال Value میباشد.