محاسبات روی ماتریس ها در OpenCV

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

بنابراین می توانیم عملیات های چهار گانه جمع، تفریق، ضرب و تقسیم را بر روی ماتریس تصویرها انجام دهیم. می توانیم یک عدد ثابت را در ماتریس تصویر ضرب و یا می توانیم یک عدد ثابت را به ماتریس تصویر اضافه کنیم. در مطالب بعدی در مورد چگونگی افزاش کنتراست (Contrast) و روشنایی (Brighness) تصویر صحبت کرده ایم.

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

در کنار چهار عملیات اصلی ریاضی، می توان عملگرهای بیتی AND, OR و NOT را بر روی ماتریس تصویر انجام دهیم. همچنین عملگرها را می توانیم بر روی پیسکل به پیکسل انجام دهیم. در مطلب های بعدی در مورد مفهوم کرنل ها یا ماتریس های کانولوشن (Convolution Matrix) صحبت می کنیم و توضیح می دهیم ه در عملیات کانولوشن که به عملیات Mask (یا Mask Operation) نیز شناخته می شود، هر درایه بخشی از تصویر در درایه نظیر ماتریسی به نام ماتریس کرنل یا ماتریس کانولوشن ضرب می شود.

مثال – بدست آوردن تصویر نگاتیو

به عنوان نمونه ای از کاربرد عملیات های ریاضی روی (ماتریس) تصویر، می خواهیم یک تصویر را اصطلاحا نگاتیو (Negative) کنیم. نگاتیو کردن تصویر به معنی تبدیل پیکسل های روشن به تاریک و تبدیل پیکسل های تاریک به روشن است. در کد زیر ابتدا یک تصویر رنگی سه کانالی RGB را به صورت Grayscale خوانده و بارگذاری کرده ایم.

سپس در خط ۱۸ ماتریس تصویر را از عدد ۲۵۵ کم و در متغیر جدیدی ذخیره کرده ایم. در واقع چون ماتریس به صورت تک کانالی خاکستری (Grayscale) است، پس هر پیکسل به صورت یک ۸ بیتی بی علامت است که می تواند اعداد صفر تا ۲۵۵ را داشته باشد. عدد صفر به معنی تاریکترین و عدد ۲۵۵ به معنی روشن ترین است. پس وقتی مقدار پیکسلی صفر باشد و عبارت ۰ – ۲۵۵ انجام شود، پس مقدار پیسکل از صفر به عدد ۲۵۵ تغییر می کند و به همین ترتیب برای دیگر مقادیر

همچنین مطابق قطعه کد زیر،می توانیم از تابع <>at نیز برای ایجاد تصویر نگاتیو شده استفاده کنیم. در کد زیر در هر پیمایش مقدر یک پیکسل از تصویر خاکستری معکوس می شود. توجه کنید که نگاتیو کردن به معنی معکوس کردن مقدار پیکسل است. به عبارت دیگر اگر مقدار پیکسل برابر با ۶۳ باشد، پس معکوس آن ۱۹۲ است و بلعکس زیرا ۶۳ + ۱۹۲ = ۲۵۵.

تصویر و ماتریس در OpenCV – پویش با اشاره گر

ترکیب دو تصویر

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

تابع ()add

مطابق کد زیر این تابع چهار آرگومان دریافت می کند که آرگومان های اول و دوم، یعنی src1 و src2 دو ماتریس ورودی و آرگومان سوم، یعنی dst تصویر خروجی است. این تابع عمل جمع را میان هر عنصر از src1 با عنصر متناظر آن در src2 انجام می دهد و نتیجه آنرا در پیکسل متناظر در dst ذخیره می کند.

کد زیر مثالی از کاربرد تابع ()add را نشان ممی دهد که عملکردی شبیه به کد بالا (عملیات جمع) دارد. شکل زیر، خروجی دو کد، عملیات جمع بر روی دو ماتریس تصویر را نشان می دهد.

تابع addWeighted

مطابق معادله زیر از تابع ()addWeighted برای محسابه مجموع وزن دار () بر روی دو ماتریس تصویر استفاده می شود. در صورتی که تصویرها به صورت چند کانالی باشند، مانند تصویرهای سه کانالی RGB، هر کانال به صورت مجزا پردازش می شود.

 

معادله بالا را می توانیم به صورت زیر در نظر بگیریم. در تابع ()addWeighted و معادله زیر، src1 ماتریس تصویر اول، alpha وزن عناصر ماتریس اول، src2 ماتریس تصویر دوم، beta ورن عناصر ماتریس دوم و gamma یک کمیت نرده ای (اسکالر Scalar) است که به مجموع دو حاصل ضرب src1*alpha + src2.beta اضافه می شود.

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

مثال – ترکیب تصویرها با تابع ()addWeighted

عملگرهای بیتی روی تصویر

عملگرهای بیتی شامل AND, OR, NOT و XOR می شود. عملگرهای بیتی زمانی مفید هستند که می خواهیم بخشی از تصویر را جدا کنیم. در مطالب بعدی مفهومی به نام ناحیه مورد علاقه (Region of Intrest) و یا به اختصار ROI را مطرح می کنیم و خواهیم گفت که می توانیم توسط کلاسی به نام Rect بخشی از تصویر اصلی و به شکل چهارگوش را انتخاب کنیم و سپس یک تصویر کوچکتر را درون این ناحیه قرار دهیم. ازعملگرهای بیتی می توانیم برای ناحیه مورد علاقه غیر چهارگوشی استفاده کنیم.

۱ – تابع ()bitwise_and

مطابق کد زیر این تابع چهار آرگومان دریافت می کند که آرگومان های اول و دوم، یعنی src1 و src2 دو ماتریس ورودی و آرگومان سوم، یعنی dst تصویر خروجی است. به عبارت دیگر نتیجه اعمال تابع بر روی آٰگومان های src1 و src2 درون dst ذخیره می شود. آرگومان چهارم، یعنی mask به صورت اختیاری است. این تابع عملگر بیتی AND (عملگر & در سی و سی پلاس پلاس) را میان هر عنصر از src1 با عنصر متناظر آن در src2 انجام می دهد و نتیجه آنرا در پیکسل متناظر در dst ذخیره می کند.

کاربرد تابع ()bitwise_and: تشخیص اشیا توسط رنگ در تصویر با OpenCV

۲ – تابع ()bitwise_not

مطابق کد زیر این تابع دو آرگومان دریافت می کند که آرگومان های اول، یعنی src ماتریس ورودی و آرگومان دوم، یعنی dst تصویر خروجی است. به عبارت دیگر نتیجه اعمال تابع بر روی آٰگومان src، درون dst ذخیره می شود.  این تابع عملگر بیتی NOT (عملگر ~ در سی و سی پلاس پلاس) را میان هر عنصر از src با عنصر متناظر آن در src2 انجام می دهد و نتیجه آنرا در پیکسل متناظر در dst ذخیره می کند.

۲ – تابع ()bitwise_or

مطابق کد زیر این تابع دو آرگومان دریافت می کند که آرگومان های اول، یعنی src ماتریس ورودی و آرگومان دوم، یعنی dst تصویر خروجی است. به عبارت دیگر نتیجه اعمال تابع بر روی آٰگومان src، درون dst ذخیره می شود.  این تابع عملگر بیتی OR (عملگر | در سی و سی پلاس پلاس) را میان هر عنصر از src با عنصر متناظر آن در src2 انجام می دهد و نتیجه آنرا در پیکسل متناظر در dst ذخیره می کند.

۲ – تابع ()bitwise_xor

مطابق کد زیر این تابع دو آرگومان دریافت می کند که آرگومان های اول، یعنی src ماتریس ورودی و آرگومان دوم، یعنی dst تصویر خروجی است. به عبارت دیگر نتیجه اعمال تابع بر روی آٰگومان src، درون dst ذخیره می شود.  این تابع عملگر بیتی NOT (عملگر ^ در سی و سی پلاس پلاس) را میان هر عنصر از src با عنصر متناظر آن در src2 انجام می دهد و نتیجه آنرا در پیکسل متناظر در dst ذخیره می کند.