- آشنايي با Matlab و Image Processing Toolbox
همه با Matlab آشنا هستيم و حداقل ميدانيم که چيز بدردخوري است. پس از صحبت دربارة اين ميگذريم. اما Image Processing Toolbox از امکانات جنبي اين برنامه است. براي اينکه مطمئن شويد که اين Toolbox روي Matlab شما نصب شده است؛ دستور ver را اجرا کنيد. اين دستور ليست هرچه که از Matlab روي رايانه شما نصب شده است را ارائه ميدهد. بين Matlab 5.x و Matlab 6 براي کار پردازش تصوير تفاوت چنداني وجود ندارد اما مثل هميشه نسخة جديدتر امکانات بيشتري دارد که البته فعلا با آنها کاري نداريم.
دستورهاي معرفي شدهver:
- چگونه يک فايل تصوير را در Matlab باز کنيم
Matlab میتواند فايلهاي گرافيکي با فرمتهاي JPEG, TIFF, GIF, BMP, PNG, HDF, PCX, XWD, ICO, CUR را به عنوان فايل گرافيکي بخواند. مثلاً براي وارد کردن تصويري به نام cameraman.tif به فضاي Matlab کافي است از دستور imread استفاده کنيم:
MyImage=imread(‘cameraman.tif’,’tif’);
توجه داشته باشيد که فايلي که دستور خواندنش را ميدهيد بايد براي برنامه قابل دسترس باشد. يعني يا بايد در مسير (Path) Matlab باشد يا اينکه در پروندهاي (folder) قرار داشته باشد که در حال حاضر برنامه به آن دسترسي دارد. براي اينکه بدانيد که Matlab براي پيدا کردن فايلي که دستورش را داديد کجا را خواهد گشت اينکارها را بکنيد: از دستور path براي اينکه بدانيد کدام پروندهها جزء مسير پيشفرض Matlab است و از دستور dir براي اينکه بدانيد که Current Directory چيست؛ استفاده کنيد.
خب تا اينجا يک فايل تصوير را در محيط Matlab وارد کردهايم. همانطور که ميدانيم يک تصوير ديجيتال بر روي کامپيوتر در قالب يک ماتريس ذخيره ميشود. پس MyImage مثل همه متغيرهاي Matlab يک ماتريس است. براي اينکه بدانيم فايل خوانده شده از چه فرمتي است(سياه سفيد، يا Gray Scale يا رنگي ) مينويسيم:
imfinfo(‘cameraman.tif’)
اين دستور را اجرا کنيد و ببينيد چه مينويسد… اما اگر بخواهيد بدانيد که ماتريس ذخيره شدة MyImage از چه نوعي است کافي است بنويسد: whos و ليست متغييرهاي مقيم شده در حافظه و نوع و اندازه آنها را ببينيد.
دستورهاي معرفي شده imread, imfinfo, whos, path, dir :
- چطور تصوير را ببينيم؟
خب حالا ميخواهيم تصوير را که در يک ماتريس ذخيره شده است را ببنيم. بنويسيد:
imshow(MyImage)
جالب است نه؟ فکر ميکنيد اگر بخواهيم دوتا تصوير را با هم ببنيم بايد چکار کنيم؟ اين را امتحان کنيد:
YourImage=imread(‘tire.tif’,’tif’);
figure
subplot(1,2,1), imshow(MyImage), title(‘MyImage’)
subplot(1,2,2), imshow(YourImage), title(‘YourImage’)
با اجراي اين دستورات به آن چيزي که اتفاق افتاد توجه کنيد؛ حتما متوجه ميشود که هرکدام از اين دستورات چکار ميکنند.
دستورهاي معرفي شده: imshow, subplot, title, figure
- تصوير را خوانديم حالا چکار کنيم؟
کمي نويز دستوپا ميکنيم و به تصوير اضافه ميکنيم که بعداً راهي پيدا کنيم حذفش کنيم:
imagen=imnoise(MyImage,’salt & pepper’);
imshow(imagen)
دستور imnoise نويزهاي مختلفي را در اختيار ما ميگذارد که به تصوير اضافه کنيم. افزودن نويز براي شبيه سازي اشکالاتي است که ممکن است به هر سيستم پردازش تصوير وارد شود. اينجا فرض کردهايم که نويز «نمک و فلفل» به تصوير اضافه شده است! اسمش عجيب غريب است؟ اين نويز را روي تصوير تلويزيونتان اگر آنتن درست تنظيم نباشد حتما ديدهايد. ميدانيم که وقتي نويز داريم با يک فيلتر حذفش ميکنيم. فيلتري که انتخاب ميکنيم بايد مناسب نويزي باشيد که روي تصوير سوار شده است. بهترين فيلتر براي نويز «نمک و فلفل» فيلتر ميانه است که در Matlab با دستور Medfilt2 قابل استفاده است:
figure
imagefilt=medfilt2(imagen);
imshow(imagefilt)
براي دستگرمي هم که شده سعي کنيد تصوير نويز و تصوير فيلتر شده را در يک صفحة واحد نمايش دهيد.
دوباره به تصوير MyImage نگاه کنيد. فرض کنيد ميخواهيم مارک دوربين درون عکس را از روي شکل آن تشخيص دهيم. بازهم فرض کنيد به روشي که بعدا بيشتر راجع بهش صحبت ميکنيم فهميديم که دوربين درون اين مختصات از تصوير قرار دارد. بين سطر ۵۹ تا ۸۴ و ستون ۱۳۱ تا ۱۷۰٫ پس از همين مختصات تصوير را با دستور imcrop ميبريم.
imagecrop=Imcrop(MyImage,[ 131 59 39 25]);
در اين دستور مختصات برش را اينطور مينويسم ] ارتفاع ,پهنا ,حداقل y ,حداقل x [. اين قسمت بريده شده را نمايش بدهيد و ببينيد. در مرحله بعد سيستم تشخيصدهندة نوع دوربين احتياج دارد که اندازه تصوير مقدار خاصي مثلاً ۱۲۰×۱۰۰ باشد. پس بايد اندازه تصوير برش داده شده را تغيير دهيم:
imagesz=imresize(imagecrop,[120 100]);
تصوير جديد را نگاه کنيد. ميبينيد که به اندازه جديد در آمده است.
دستورهاي معرفي شده: imnoise, medfilt2, imcrop, imresize
کمي خلاقيت مهندسي!
يک فايل جديد باز ميکنيم که عکسي از دانههاي برنج است. ميخواهيم دانههاي برنج را درون عکس بشماريم. اين عکس از قسمت برنج مرغوبِ خط توليد يک کارخانه است. شمارش دانههاي برنج به کارخانه برنج سازي کمک ميکند بداند چند درصد برنجهايش درجه يک هستند. اين دستورات را اجرا کنيد:
p=imread(‘rice.tif’);
re=edge(p,’sobel’);
imshow(re)
re2=edge(p,’canny’);
figure, imshow(re2)
البته اول تصوير اصلي برنجها را ببينيد و سپس مقايسه کنيد. دو روش Sobel و Canny براي پيدا کردن لبهها مورد آزمايش قرار گرفته است. مشخص است که روش Canny اينجا بهتر جواب داده است. دو کار به عهده شماست.
- الگوريتمي پيدا کنيد که تعداد برنجهاي درون عکس را بشمارد.(راهنمايي: اگر بتوانيد تعداد مسيرهاي بستهی درون تصوير لبهها را بشماريد تقريباً همه برنجها را شمردهايد)
- کشف کنيد که روش Canny براي مشخص کردن لبه چه روشي است و چطور عمل ميکند و چرا از روش سادة Sobel بهتر است.
براي بهتر شده نتيجه کار با روش Sobel بهتر است از عملگرهاي ريختشناسي (morphological) استفاده کنيم. سعي ميکنيم قسمتهاي نزديک به هم لبة هر برنج را به هم متصل کنيم. با اين کار لبة برنجها را کامل ميکنيم و خوردگيها را از بين ميبريم. اما قبل از ادامه کار دستور close all را امتحان کنيد. اين دستور همه figure هايي که باز هستند را ميبندد تا زياد شلوغ نشود! حالا اين دستورها را اجرا کنيد:
figure, imshow(re)
re4=bwmorph(re,’close’);
re5=bwmorph(re4,’bridge’);
figure, imshow(re5) , title(‘after morphological operations’)
آخرين تصوير لبهها را با تصوير اوليه لبهها که همان re است مقايسه کنيد. ميبينيد که در متصل کردن قطعات پيشرفت خوبي داشتيم. اولين دستور bwmorph عمل Closing را روي تصوير انجام ميدهد و دومين دستور عمل Bridge. براي اينکه بدانيد هرکدام از اين دستورات چکار ميکنند از help bwmorph استفاده کنيد.
براي اينکه بهتر کار با اين دستورها را ياد بگيريم سري به Demoهاي Matlab ميزنيم. در صفحه Matlab بنويسيد: demo و با اجرا کردن اين دستور ليست demoهاي مختلف ظاهر ميشود. Image Processing Toolbox را انتخاب کنيد. و در ليست کناري Edge Detection را انتخاب کنيد. بقيه ماجرا با خودتان! دستورهاي معرفي شده:edge, bwmorph, demo
هيستوگرام تصوير
تا به حال تصويرهاي Gray Scale را بررسي کرديم. از اين به بعد هم همين کار را ميکنيم! با اين تفاوت که اگر تصوير ورودي رنگي بود اول Gray Scaleاش ميکنيم و بعد کارها را ادامه مي دهيم.
تصوير flowers.tif را با دستور imread در ماتريس flowers ذخيره کنيد. از دستور rgb2gray براي تبديل فرمت رنگي تصوير به Gray Scale استفاده کنيد. حالا هيستوگرام تصوير را رسم کنيد. بعد يکي از قلههاي نمودار هيستوگرام را انتخاب کنيدکه بين دوتا دره باشد. کاري کنيد که فقط اين قله درون هيستوگرام باقي بماند. بعد با دستور im2bw تصوير را از Gray Scale به سياه سفيد تبديل کنيد و نتايج را مقايسه کنيد!
چطور شد؟ توضيح ميدهم، اينطوري:
flowers=imread(‘flowers.tif’,’tif’);
flowersgray=rgb2gray(flowers);
imhist(flowersgray)
من هيستوگرام را نگاه کردم و شما هم نگاه کنيد. (هيستوگرام تصوير را بادستور imhist کشيدم) قلة بين ۵۰ و ۱۰۰ را انتخاب ميکنم. حالا يک ماتريس جديد ميسازم طوري که فقط جاهايي که مقدار ماتريس flowersgray در محدودة ۵۰ تا ۱۰۰ است، در ماتريس جديد ۰ باشد و باقي جاها ۱ باشد.
(يعني يک ماتريس باينري يا سياه سفيد)
f=ones(size(flowersgray));
f(find(flowersgray>50&flowersgray<100))=0;
imshow(f)
دستورهاي بالا به اين معني است: ماتريس f را هماندازه ماتريس flowersgray بساز. همة درايههايش را يک بگذار. بعد دستور find درون ماتريس flowersgray جستجو ميکند و شماره درايههايي از ماتريس flowersgray را به من ميدهد که در شرط روبهرو برايش مشخص شده. (همان محدودة ۵۰ تا ۱۰۰). اين درايههاي بخصوص را در ماتريس f از ۱ به ۰ تبديل ميشود. نتيجه را باهم ببينيم!
اگر دقت کنيم ميبينيم که مجموعة گلدون از پس زمينه جدا شد. آنهم تنها با انتخاب يک قله درون هيستوگرام… حالا من از کجا فهميدم که اين قله مهم است؟… لابد علم غيب داشتم؟… بعدا راجع به انتخاب قلهها بيشتر خواهيم فهميد.
حالا دستور im2bw را – که تصوير را سياه سفيد ميکند – امتحان کنيد.
bwflowers=im2bw(flowersgray,gray);
imshow(bwflowers)
دستور im2bw حدي تعيين ميکند و درايههايي که از آن حد کمتر باشند را صفر و آنهايي که بيشتر هستند را يک ميکند. آيا متوجه تفاوت دو روش شدهايد؟ اگر به جاي گلدون در تصوير مورد نظر، عکس پرسنلي افراد بود چه اشکالي در روش im2bw وجود داشت؟
دستورات معرفي شده: rgb2gray, imhist, ones, find
اگر ما روبات بوديم…
خب فرض کنيد برنامهاي براي يک روبات مينويسيد که با استفاده از يک دوربين به يک بازوي دقيق فرمان ميدهد که سکههاي «اسکروچ» را بردارد و روي هم قرار دهد. براي اينکار لازم است محل دقيق سکهها را تشخيص دهيم تا فرمان مناسب براي بازو صادر شود. برنامة زير اين کار را انجام ميدهد. دقت کنيد ببينيد که چطور اينکار را انجام ميدهد:
coins = imread(‘eight.tif’);
BW=~im2bw(coins,.75);
imshow(BW)
L = bwlabel(BW);
stats = imfeature(L,’Centroid’);
stats(7)
خروجي همان متغيير stats است. اين متغيير ۷ عنصر دارد. درحالي که ۴ سکه بيشتر درون تصوير وجود ندارد! اشکال از کجاست؟…. راه حلي هم براي اين به ذهنتان ميرسد؟
دستورهاي معرفي شده: bwlabel, imfeature
با اينترنت ياد بگيريم:
به آدرس www.ph.tn.tudelft.nl/hpise/index.html مراجعه کنيد و در کلاس آنلاينِ مجانياش ثبتنام کنيد. من آنجا به اسم raminia عضو هستم. خيلي جالب است! حتما امتحانش کنيد.
لطفاً براي ارسال دیدگاه، ابتدا وارد حساب كاربري خود بشويد