MATLAB教程系列-台大-09 exercise

1. 不通过im2bw()函数完成图像二值化

通过graythreshold()函数,程序可以自动找到一个对于当前图片来说更加合适的阈值来进行二值化。通过im2bw()图像,可以完成二值化,把当前图像变为只有黑白两色的图片。例程如下:

I = imread('rice.png'); level=graythresh(I);
bw=im2bw(I, level); subplot(1,2,1); imshow(I);
subplot (1,2,2); imshow(bw);

结果:

MATLAB教程系列-台大-09 exercise_第1张图片

如果不借助matlab中的函数,自己如何完成呢?

程序:

I = imread('rice.png'); 
thershold = 140;
for i=1:size(I,1)
    for j= 1:size(I,2)
        if I(i,j) > thershold
            J(i,j) = 1;
        else
            J(i,j) = 0;
        end
    end
end
subplot(1,2,1); imshow(I);
subplot(1,2,2); imshow(J);

结果:

MATLAB教程系列-台大-09 exercise_第2张图片

可以看到两种结果相差不大。但这张图片的下半部分背景色整体较深,导致一些“米粒”消失,可以通过“Background estimation”的方法来得到背景,使得剩下的图片光线强度比较均匀,再通过“Background Subtraction”将背景分离,最后重新确定阈值并进行二值化。

程序:(在刚刚的基础上继续写~)

I = imread('rice.png'); 
thershold = 140;
for i=1:size(I,1)
    for j= 1:size(I,2)
        if I(i,j) > thershold
            J(i,j) = 1;
        else
            J(i,j) = 0;
        end
    end
end
subplot(1,3,1); imshow(I);
subplot(1,3,2); imshow(J);
BG = imopen(I, strel('disk', 15)); %Background Estimation
I2 = imsubtract(I,BG);  %Background Subtraction
level = graythresh(I2);
bw = im2bw(I2,level);
subplot(1,3,3); imshow(bw);

结果:

MATLAB教程系列-台大-09 exercise_第3张图片

可以看到,经过处理后,原图片中的“米粒”和背景可以得到较好的分离。

在得到比较完美的结果后,接下来我们可以数一数这张图片上究竟有多少米。用到了Connected-component Labeling: bwlabel()的方法。关于这种方法的讲解,具体可以参照老师的讲解视频和PPT。在数出一共有多少米后,课后练习要求求出最大的米粒的size和所有米粒的平均size。这里只简单记录自己的代码及结果。

代码:

I=imread('rice.png');
BG=imopen(I, strel('disk', 15));
I2=imsubtract(I, BG); level=graythresh(I2);
BW=im2bw(I2, level);
[labeled, numObjects]=bwlabel(BW, 8);
flag=0;
num=[];
for k=1:numObjects
    for i= 1:size(labeled,1)
        for j=1:size(labeled,2)
            if labeled(i,j) == k;
                flag=flag+1;
            end
        end
    end
num(end+1)=flag;
flag=0;
end
max(num);
int16(mean(num));
histogram(num); %下一个练习中要求将size的histogram画出

结果:

MATLAB教程系列-台大-09 exercise_第4张图片

这两个结果分别对应着max和mean的值。

其中,

I=imread('rice.png');
BG=imopen(I, strel('disk', 15));
I2=imsubtract(I, BG); level=graythresh(I2);
BW=im2bw(I2, level);
[labeled, numObjects]=bwlabel(BW, 8);

这部分代码为老师给出的例程,通过这个程序可以得到一个label matrix和numObjects, 直观理解的话,分别为标注出的“米粒”和数出的米粒总数。从workspace中可以得到这个label matrix以及很直观的米粒总数。

2. 将所有的米粒标为红色

由于二值图为单通道图像,而RGB三种颜色如果想要被呈现,必须是在图像为三通道的情况下才能实现。因此这一步,在刚才的基础上,继续对原图进行一些处理。

代码:

I=imread('rice.png');
BG=imopen(I, strel('disk', 15));
I2=imsubtract(I, BG); level=graythresh(I2);
BW=im2bw(I2, level);
[labeled, numObjects]=bwlabel(BW, 8);
flag=0;
num=[];
for k=1:numObjects
    for i= 1:size(labeled,1)
        for j=1:size(labeled,2)
            if labeled(i,j) == k
                flag=flag+1;
            end
        end
    end
num(end+1)=flag;
flag=0;
end
subplot(1,2,1); imshow(labeled);
for i= 1:size(labeled,1)
        for j=1:size(labeled,2)
            if labeled(i,j) ~= 0
                I(i,j,1)=255;
                I(i,j,2)=0;
                I(i,j,3)=0; %设置有米粒的地方为红色,由于只显示红色,
                             %故只有第一个通道值为255,其他均为0
            else
                I(i,j,1)=0;
                I(i,j,2)=0;
                I(i,j,3)=0; %背景色为黑色,三个通道均为0
            end
        end
end
subplot(1,2,2); imshow(I);

结果:

MATLAB教程系列-台大-09 exercise_第5张图片

(不知道老师想要的方法和效果具体是什么样的,根据视频和PPT,最后自己写出来的就是这样啦~) 

你可能感兴趣的:(Matlab学习)