پردازش تصوير با مطلب (قسمت2)
دوستان عزیزم سلام
. یه خورده دیر کردم واقعا ببخشید! اما به قول یکی از دوستان که نظر گذاشته بود٬ یه موقعه هایی آدم نوشتنش نمیاد دیگه! تازه ۱ هفته هم کامپیوترم قات زده بود (امان از دست این ویروسا) راستی با اینکه هنوزم درصد بالایی از بازدیدهای وبلاگ بخاطر مقالات ربات مسیریاب هستش٬ اما واقعا خوشحالم که عده کسانی که از پردازش تصویر استقبال کرده بودن هم کم نبود (بگو ماشاءالله). امروز می خوام یه مبحثی از پردازش تصویر در مطلب رو بگم که البته از تمام توابعش در پروژه خودمون قرار نیست استفاده کنیم اما از اونجایی که هم یکی از مثالهای مهم خود مطب هست و هم خیلی جذابه یادگرفتنش خالی از لطف نیست...
Morphological Opening قابلیتی هستش که با استفاده از اون می تونید اجزاء کوچک یا ضائد موجود در یک تصویر رو از بین ببرید در حالی که به اجزاء بزرگتر و یا باشکل مورد نظر شما هیچ خدشه ای وارد نشه! برای مثال می تونید در تصویر نقشه فیبر یک مدارچاپی خطوط سیمهای اتصال رو از بین ببرید در حالی که جای قطعات بزرگتر مثل آیسی های و... لطمه ای نزنید. (خیلی گنگه؟ یه مثال دیگه) فرض کنید تصویر یه قطره خون زیر میکروسکوپ را دارید که مثلا داخلش انواع گلوبول سفید و قرمز هزار جور ذره دیگه با سایزهای کوچیک و بزرگ هستش. حالا اگر بخواید تعداد گلوبول سفیدارو بشمارید مجبورید اول ذرات کوچکترو حذف کنید و بعد تعداد کل ذرات باقیموندرو بشمارید! اصلا بیاید با همین مثال شروع کنیم:
.codebox {BORDER: black 1px dashed; WIDTH: 90%; BACKGROUND-COLOR: #eeeeee;font-size:9pt;line-height:1; DIRECTION:ltr; text-align:left; padding:5px; font-family: Courier New}1. I = imread('nodules1.tif');
2. level = graythresh(I)
3. bw = im2bw(I,level);
4. bw = ~bw;
5. imshow(bw);
خوب توضیحات رو با شماره خطوط پیش می برم. خط اول کد رو که جلسه پیش توضیح دادم برای خواندن یک تصویر از آدرس مورد نظر در یک متغیر هستش. نصویر مورد نظر ما در اینجا یک تصویر grayscale یا سیاه و سفید هستش. حتما قبل از اجرای دستور دوم یکبار (Imshow(I رو اجرا کنید تا این تصویر سیاه و سفید رو ببینید. خط دوم و سوم از دو تابع im2bw و graytresh به صورت پشت سرهم استفاده شده که نحوه کار هریک
در این مثال به صورت زیر هستش:
(BW = im2bw(I,level : همونطور که در مقاله قبل توضیح دادم تصاویر در مطلب انواع مختلف دارن از جمله رنگی یا RGB و سیاه سفید Grayscale و یا باینری و... توابع مختلفی جهت تبدیل این نوعها به هم تعبیه شده که از جمله اونها im2bw هست که جهت تبدیل انواع تصاویر به نوع باینری که تنها دارای نقاط سیاه و سفید هستش بکار میره. این تابع تصویر ورودی رو اول به نوع سیاه سفید تبدیل می کنه و در مرحله بعدی اون رو به یک تصویر باینری تبدیل می کنه. تصویر باینری خروجی BW به ازاء تمام پیکسل هایی که مقدار روشنایی آنها کمتر از مقدار level باشد مقدار ۰ (یا سیاه) و برای بقیه پیکسلها مقدار ۱ (یا سفید) اختیار خواهد کرد.
(level = graythresh(I : همیشه برای بدست آوردن این حدآستانه level که در تابع بالایی استفاده می شود از تابع graythresh با ورودی تصویر مورد نظر استفاده می کنیم و بعد این level را در توابعی همچون im2bw استفاده نماییم.
قبل از اجرای دستور خط چهارم حتما یکبار دستور (imshow(BW را جهت مشاهده تصویر باینری تولید شده اجرا کنید. مشاهده می کنید تمام نقاط به رنگ سیاه و بقیه تصویر سفید می باشد (تصویر باینری فقط دارای نقاط ۰ سیاه و ۱ سفید می باشد). حالا فرض کنید بخوایم این حالتو برعکس کنیم یعنی نقاط سفید و زمینه سیاه باشه باید از دستور خط ۴ استفاده کنیم. می بینید که علامت ~ در مطلب مثل NOT منطقی عمل کرده و تمام نقاط صفر رو یک و یک رو صفر کرده. با اجرا دستور خط ۵ یکبار دیگه تصویر تولید شدرو ببینید.
یه مراحلی رو طی کردیم که خود این مراحل هم فقط جنبه آموزش داشتن وگرنه همون تصویر سیاه و سفید اول رو هم می تونستیم ذرات ریزش رو باهمین روشی که در زیر توضیح می دم٬ حذف کنیم. اما چون ما در بعضی مثل همینجا به اطلاعات اضافی تصویر احتیاجی نداریم و همچنین چون سرعت پردازشات روی تصاویر باینری بسیار بالاتر هستش٬ در صورت لزوم یه همچین مراحلی رو ابتداعا طی می کنیم و تصویر باینری ایجاد می کنیم. خوب حلا بریم سر اصل قضیه که حذف کردن ذرات ریز باشه:
1. se = strel('disk',5);
2. bw2 = imopen(bw,se);
3. imshow(bw);
4. figure, imshow(bw2);
(IM2 = imopen(IM,SE : اصل قضیه Morphological Opening همین تابع imopen هستش که دارای دو ورودی٬ یکی تصویر مورد نظر (IM) و دیگری یک المان ساختاری (SE) هستش که مشخص کننده خصوصیات اجزایی که باید از تصویر حذف بشن٬ از جمله شکل و بزرگی آنها هستش.
(SE = strel(shape,parameters : این تابع تولید کننده همون المان ساختاری مصرف شده در تابع بالاس. این تابع بر اساس ورودی هایی که بهش داده میشه یک ماتریس دوبعدی از صفر و یک ها میسازه که نقاط ۱ در کنار یکدیگر یک جزء کوچک رو میسازن و تابع imopen با توجه به این ساختار اجزایی که کوچکتر از این جزء هستند رو از تصویر حذف می کند. پس بایستی دقت کنیم ساختار تولید شده در این دستور نه خیلی کوچک باشد که اجزاء ضاید را در بر نگیرد و نه خیلی بزرگ باشد که برخی از اشکال تصویر که قصد حذف شدن آنها را نداریم نیز از بین بروند!
ورودی shape یک رشته است که یکی از چند حالت 'disk', 'ball, 'octagon,.. را که مشخص کننده شکل ساختار تولید شده است٫ می باشد. بر اساس رشته shape وارد شده پارامترهای متفاوتی را جهت مشخص کردن سایز آن بایستی در ورودیهای بعدی وارد کنید که جزئیات بیشتر را با جستجو کردن نام تابع 'strel' در راهنمای مطلب بیابید. اما برای نمونه
(SE = strel('disk',R باعث ایجار یک ساختار دیسک شکل با شعاع R به صورتی که در شکل مشاهده می کنید می شود.
خوب با صدا زدن دو دستور خط ۱ و ۲ المان ساختاری مورد نظر تولید شده و تمام اجزایی که کوچکتر از این ساختار باشند توسط دستور imopen حذف می شوند و خروجی در متغیر bw2 قرار می گیرد. کد خط چهارم همانطور که می دانید تصویر bw را نمایش می دهد و کد خط ۵ باعث ایجاد یک پنجره تصویر جدید و نمایش bw2 در آن می شود. پس همزمان می توانید تصویر اصلی و اصلاح شده آن را مشاهده نمایید. که خروجی چیزی شبیه شکل زیر خواهد شده.
دوستان این مقاله زیادی طولانی شد اما به نتایج جالبی داریم می رسیم. حتما به راهنمای مطلب سر بزنید که از اینجور مثالا توش زیاده! یادتون نره از این تکنیک در جاهای مختلفی می تونید استفاده کنید.