آشکارسازی لبه(2)

در کد بالا از فیلتر Sobel  با کرنل 5*5 یک بار در راستای x  و یکبار در راستای y اعمال کردیم و یکبار هم با استفاده از bitwise_or( ) در هردو جهت x, y این کار را انجام دادیم. با استفاده از Laplacian( ) از فیلتر Laplacian استفاده کردیم و با استفاده از Canny( ) از فیلتر Canny استفاده کردیم که دو عددی که به عنوان ورودی مشخص شده در واقع threshold های بالا و پایین می باشد.

آشکارسازی لبه(1)

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

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

از لبه یابی می توان برای تشخیص تغییرات شدید در روشنایی که معمولا نشانه رویدادی مهم یا تغییر در محیط است، استفاده کرد. همچنین  می توان از لبه یابی در object recognition (تشخیص اشیا) و segmentation(جدا سازی عکس و تبدیل آن به چند عکس) و بینایی ماشین استفاده کرد.

 

برای مدل کردن لبه ها، می توان عکس ها را تابع فرض کرد.

ایده ی ابتدایی برای لبه یابی این است که همسایه هایی با تغییرات شدید را پیدا می کنیم. که برای این کار مشکلاتی وجود دارد.  از جمله اینکه تا چه فاصله ای پیکسل های هماسیه را جزو همسایگی در نظر بگیریم و چگونه تغییرات را تشخیص دهیم.

همانطور که گفته شد لبه ها محلی هستند که در آن تابع شدت روشنایی دچار تغییرات شدید می شود. در تصویر بالا، شکل وسط، تغییرات روشنایی عکس سمت چپ در محور افقی را نشان می دهد. شکل سمت راست مشتق اول شکل وسط را نشان می دهد. و لبه ها در واقع همان قله ها در تابع مشتق اول است.

Differential Operators

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

Image Gradient

گرادیان به جهتی اشاره می کند که بیشترین تغییرات شدید در روشنایی به وجود آمده. در عکس سمت چپ در محور افقی تغییرات داریم پس مشتق جزیی نسبت به x وجود دارد و مشتق جزیی نسبت به y صفر است. در عکس وسط در محور عمودی تغییرات داریم پس مشتق جزیی نسبت به y وجود دارد و مشتق جزیی نسبت به x صفر است و در عکس سمت راست در هردوجهت تغییرات داریم پس هردو مشتق جزیی وجود دارد.

Discrete Gradient

برای تابع دو بعدی f(x,y) مشتق جزیی برای x به صورت بالا می باشد

برای داده های گسسته می توان از فاصله های محدود و متناهی استفاده کرد(بجای ε)(با پیکسل کار می کنیم که یک داده گسسته است. یعنی فاصله را یک در نظر می گیریم)

Partial Derivatives of an Image

در تصویر بالا اگر مشتق جزیی نسبت به x باشد درواقع لبه ها در محور x را بر می گرداند. شکل کرنل هم بصورت یک متریس 1*2 می باشد که -1 بر روی پیکسل مورد نظر قرار می گیرد و 1 بر روی پیکسل جلویی(پیکسل فعلی – پیکسل جلویی). اگر هم که مشتق جزیی نسبت به محور y گرفته شود لبه ها در محور y را بر می گرداند. شکل کرنل  بصورت ماتریس 2*1 می باشد. -1 و 1 می تواند جا به جا شود.

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

معمولا فیلتر ها symmetric (به این مفهوم که تعداد سطر و ستون آن برابر و فرد می باشد ) هستند. در حالی که فیلتر سمت چپ در عکس بالا اینگونه نیست. در فیلتر سمت راست که symmetric است, میزان تغییرات نسبت به پیکسل قبلی و بعدی محسابه می شود و از آن میانگین گرفته می شود.

Sobel Operator

در این حالت اثر پیکسل های همسایه هم با کمک اعداد -1 و 1 در نظر گرفته می شود.

Sobel Operator On Block Images

در عکس بالا سمت راست، با مشخص کردن آستانه، بعضی از لبه ها که حاصل از تغییرات کمتر بودند حذف شده اند

But In The Real World…

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

Finite Differences Responding to Noise

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

Gradients -> Edges

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

  • Smoothing: حذف نویز ها با کمک فیلترهایی مانند gaussian
  • Threshold: چه مقداری به بعد لبه حساب شود.
  • Thinning: اگر چند لبه در کنار هم و با فاصله کم وجود داشته باشد همه را یک لبه در نظر می گیریم.
  • Connect edge pixles
Canny Edge Operator
  1. استفاده از فیلتر Gaussian
  2. محاسبه گرادیان
  3. non-maximum suppression: همان عملیات thinning
  4. اگر که یک لبه را مانند یک خط در نظر بگیریم ممکن است که میزان تغییرا در طول این خط برابر نباشد و مثلا قسمتی از این خط پررنگ تر باشد یا بخاطر آستانه تعریف شده قسمتی از خط حذف شده باشد. می توانیم از دو آستانه استفاده کنیم که مثلا اگر میزان تغییرات از آستانه بزرگتر، بیشتر باشد حتما لبه است و اگر از آستانه کوچکتر، کمتر باشد اصلا لبه نیست ولی اگر بین دو آستانه باشد، بسته به اینکه پیکسل های اطراف آن، لبه هستند یا نه خودش می تواند لبه باشد یا نباشد. مثلا در همان خطی که گفته شد اگر جایی از خط قطع شده، آن را پر می کند.
The Canny Edge Detector’

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

دستکاری تصاویر (۶) – فیتلرها در 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) به صورت زیر است: