Example 2 - Analyzing Images เปิดรูป เมล็ดข้าว
I = imread('rice.png'); imshow(I) |
สร้าง background
strel แบบ disk จะได้ เมตริกซ์ที่บริเวณมุม เป็น ศูนย์ ตรงกลางๆ เป็น 1 คล้ายวงกลม
อยู่กลางเมตริกซ์
imopen เป็น Erosion ตามด้วย Dilation มันจะตรงข้ามกับ closing
อ้างอิงbackground = imopen(I,strel('disk',15)); |
ลองวาดกราฟแบบ พื้นผิว ดูความขาวดำของสีพื้น
figure, surf(double(background(1:8:end,1:8:end))),zlim([0 255]); set(gca,'ydir','reverse'); |

ทำให้เมล็ดข้าวกับ background สีมันแตกต่างกันมากขึ้น
I2 = I - background; imshow(I2) |
แต่มันจะทำให้ภาพเมล็ดข้าวมืดลง

เพิ่ม contrast ใช้ imadjust(I) = imadjust(I,stretchlim(I)) คือมันจะแผ่ขยายสีให้เต็มช่วงเลย
อ้างอิงI3 = imadjust(I2); imshow(I3); |

ทำ threshold ให้เป็นภาพขาวกับดำเท่านั้น
level = graythresh(I3); bw = im2bw(I3,level);
|
level หาค่าที่เหมาะสมที่จะแบ่งระหว่างสีขาวกับสีดำ ด้วย graythresh(I)
im2bw แปลง grayscale เป็น binary

จะเห็นว่ามีบางจุดที่เป็น noise อยู่ เป็นจุดขาวๆเล็กๆ ทำopenเพื่อให้หายไป
bw = bwareaopen(bw, 50); imshow(bw) |
จากใน Tutorial ให้เราใช้คำสั่ง
cc = bwconncomp(bw, 4); ??? Undefined function or method 'bwconncomp' for input arguments of type 'double'.
|
ซึงแปลว่า มันไม่มี M File ของ
bwcommcompลองหาดูได้ใน C:\Program Files\MATLAB\R2008a\toolbox
ลองลง Image Processing Toolbox™ ดูใหม่ แต่เมื่อติดตั้งใหม่ version ล่าสุด ก็ไม่มี function bwconncomp ให้อยู่ดี
ทีนี้ลองหา function อื่นมาทดแทนที่ใช้หา CC = bwconncomp(BW) returns the connected
components CC found in BW. The
binary image BW can have any dimension. CC is
a structure with four fields.
[CC,NUM] = bwlabel(BW,4) >> num
num =
95
|
มันจะนับออกมาได้ 95 Object
Update 23 ส.ค. 2552
เพื่อให้หมดปัญหา ผมได้หา Matlab 2009a มาจาก ป้อสาธิต ต้องขอขอบคุณเลยนะครับ
ผมก็กลับมาใช้คำสั่งดังเดิมคือ
cc = bwconncomp(bw, 4); grain = false(size(bw)); |
ก็จะได้ grainขนาด เท่ากับ bw ดีดำทั้งรูปมา
ต่อไปเราจะ label เมล็ดข้าวด้วยสีต่างๆ
labeled = labelmatrix(cc); RGB_label = label2rgb(labeled,'jet', 'k', 'shuffle'); figure, imshow(RGB_label)
|
ซึ่งคำสั่ง label2rgb(L, map, zerocolor,
order)
ปรับแต่ง map ดังนี้

ใส่ zero color ดังนี้
ส่วน order มีแค่ 'noshuffle' กับ 'shuffle' เท่านั้น
ได้รูปที่ lable ออกมาดังนี้

หา พื้นที่ของแต่ละเมล็ด
ด้วยการหา property ของ พื้นที่
graindata = regionprops(cc,'basic'); |
สามารถเปลี่ยน 'basic' เป็น อย่างอื่นได้อีก
หาเมล็ดข้าวที่ใหญ่ที่สุด
grain_areas = [graindata.Area]; [max_area,idx] = max(grain_areas) grain(cc.PixelIdxList{idx}) = true; imshow(grain);
|
ค่า idx คือ สมาชิกที่ให้ค่าmax เช่น graindata(idx).Area จะได้ค่าคือ max_area เช่นเดียวกัน

จะเห็นได้ค่าไม่ได้เป็นเมล็ดข้าวเมล็ดข้าวที่ใหญ่ที่สุดจริงๆ เพียงแต่มันเป็น 2 เมล็ดติดกันเท่านั้นเอง
ซึ่งอาจต้องกลับไปปรับปรุงในช่วงที่ทำ opening กับ closeing
ซึ่งเราสามารถplot ความถี่ของขนาดของเมล็ดข้าวออกมาดูได้
nbins =20; figure, hist(grain_areas,nbins) title('Histogram of Rice Grain Area'); |
เราก็จะเห็น ค่าถี่ที่ผิดปกติได้

ซึ่งเมล็ดข้าวที่เต็มเมล็ด จะมีพื้นที่ประมาณ 200
ส่วนที่เล็กกว่า นั้นเป็นเมล็ดข้าวที่หัก
และส่วนที่ใหญ่กว่า ก็คือ เมล็ดข้าวที่อยู่ชิดกันเกินไป จนพื้นที่ของทั้งสองเมล็ดรวมกันเป็นอันเดียวนั่นเอง