دستکاری تصاویر (۴) – عملیات ریاضی و ترکیب تصاویر رنگی در 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 شود حاصل ۰ خواهد بود پس در نتیجه تصویر به این شکل در خواهد آمد :

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

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

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

فوتر سایت

اسلایدر سایدبار

درباره ما

درباره ما

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

شبکه های اجتماعی

مطالب اخیر