تبدیل Affine و Perspective در OpenCV

get Perspective Transform

اگر بخواهیم یک تبدیل affine رو یک تصویر انجام بدهیم می توانیم از getPerspectiveTransform استفاده کنیم. به این صورت که مختصات چهار گوشه قسمتی از تصویر که می خواهیم تبدیل رو آن انجام شود را مشخص می کنیم (points_A) و همچنین مشخص می کنیم که می خواهیم این چهار نقطه رو چه نقاطی در تصویر جدید نگاشت شوند(points_B). تابع getPerspectiveTransform یک ماتریس 3*3 بر می گرداند که درواقع اگر هر کدام از چهار نقطه رو تصویر اصلی به فرم [xi, yi, 1] در این ماتریس ضرب شوند حاصل نقاط مورد نظر روی تصویر جدید خواهند بود که به فرم [ti*x’i, ti* y’i, ti] خواهد بود(مختصات تصویر جدید ‘x و ‘y می باشد و ti عدد ثابت است). حال برای اینکه تصویر جدید را ایجاد کنیم از getPerspectiveTransform استفاده می کنیم که به عنوان ورودی عکس اولیه و ماتریس تبدیل و اندازه عکس جدید را می گیرد و عکس جدید را برمی گرداند.

get Affine Transform

 

با استفاده از  getAffineTransform نیز می توان یک تبدیل affine انجام داد با این تفاوت که از سه نقطه استفاده می کنیم. طبق رابطه ی مشخص شده, حاصل getAffineTransform یک ماتریس 2*3 می باشد که اگر هر کدام از سه تقطه اولیه به فرم      [xi, yi, 1] در این ماتریس ضرب شوند حاصل نگاشت این نقاط در تصویر جدید به فرم [x’i, y’i] خواهد بود. با استفاده از warpAffine تصویر جدید به دست می اید که ورودی ان همان طول و عرض تصویر اصلی و تابع تبدیل(M) و تصویر اولیه می باشد.

دستکاری تصویر (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.
  • تنها میتوان ماتریس های مربعی را به توان رساند.