MATLAB学习笔记(五、图像处理——下)

一、Image thresholding : imread()、graythresh()、im2bw()

1. 读入图像

I = imread(‘filename’):通过文件名导入图像I(注意必须在同一文件夹)

level = graythresh(I): 找出并返回图像I(必须是灰度图) 的合适阈值level

I_bw = im2bw(I, level): 将图像I(必须是灰度图)通过计算好的阈值level 转化为二值图 I_bw

二、Background Estimation

1. Estimate for the gray level of the background : strel()

给你一张图,让你找出这张图的背景,就需要用到:
SE = strel(shape, parameters)
举例:se = strel('disk',15) 创建半径15的圆盘

tips: 由于该函数有些复杂且学习笔记篇幅有限,有关该函数更多信息可移步下面两个链接:
https://ww2.mathworks.cn/help/images/ref/strel.html#bu7pnvx-1
https://blog.csdn.net/hyaqian123/article/details/79924627

2. background subtraction : imsubtract()、imopen()、strel()

Z = imsubtract(X, Y):简单说就是图像X每个像素灰度值 减去图像Y每个像素灰度值,返回一个图像Z。
更详细信息可移步 https://ww2.mathworks.cn/help/images/ref/imsubtract.html?s_tid=doc_ta

J = imopen(I,SE) :在灰度或二值图像上执行形态开放图像I,返回打开的图像J。 SE是由返回的单个结构元素对象 strel或offsetstrel功能。形态学开放操作是侵蚀,随后是扩张,使用相同的结构元素进行两种操作。

那么imopen()、strel()这两个函数如何结合呢
imopen(I, strel(shape, parameters))
举例:下面的一张图片摘自MATLAB中国,链接 https://ww2.mathworks.cn/help/images/ref/imopen.html
tips: 代码 imshow(原件); 是翻译问题,应是 imshow(original);
;在这里插入图片描述
大概了解其工作原理后,我们看下面的应用:
BG = imopen(I, strel('disk', 15)) 即取出 原图I 的 背景BG。
在这里插入图片描述

3. Thresholding on Background Removed Image

我们图像处理一般要将 rice.png 这种灰度图转化为二值图(即black-white黑白图)。
那么我们联系之前学过的可以想到两种处理方法;
(1)一种是之前直接阈值处理函数
k = graythresh(I); I_bw = im2bw(I, k);

(2)另一种是2. background subtraction 提到的先背景减法处理,再转化为二值图
BG = imopen(I, strel(‘disk’, 15)); % 取BG
I2 = msubtract(I, BG); % 做减法,得到图像I2
level = graythresh(I2); % 得到阈值level
I_bw = im2bw(I2, level) % 得到二值图I_bw

绘出图像进行对比——
在这里插入图片描述
tips:
我们可以看到 I直接阈值处理 的图像有一些米粒部分由于像素值较小,低于阈值而被误认为是背景而被二值化成黑色,只留下了白色点;先做背景减法再二值化 的图像中米粒则比较完好。

代码如下:

I = imread('rice.png'); 
subplot(2,2,1);
imshow(I); title('原图I');

%内置function直接处理
level = graythresh(I);
bw = im2bw(I, level); 
subplot(2,2,2);
imshow(bw); title('I直接阈值处理');

%提取背景
BG = imopen(I, strel('disk', 15));
subplot(2,2,3);
imshow(BG); title('I的BG');

%原图 - 背景
I2 = imsubtract(I, BG);  level = graythresh(I2);
bw2 = im2bw(I2, level);
subplot(2,2,4);
imshow(bw2); title('I - BG');

三、Connected-component labeling

连接和边界问题是图像问题的重点。
我们先认识一下label是什么,它不仅仅是坐标轴的标签,还可以是一幅二值图中像素连通集的标号(从上到下,从左到右给连通集标号1,2,3,……)(连通区域可能可以联合成连通集)
比如我们如果按照8连通的标准去给 rice.png 的米粒数数,那就是有99个连通集,你可以认为有99个米粒(若米粒连在一起、图像边缘处米粒size过小算不算一粒米等的细分问题另当别论)

1. Built in Connected-component labeling Algorithm : bwlabel()、find()、mean()、size()

(1)L = bwlabel(BW, conn):返回图像BW的标签矩阵L, conn指定连接方式。
conn指定的连接方式有两种:4连通、8连通(若无第二个参数conn,则默认8连通)
[L, num] = bwlabel(BW, nonn):这里num就是返回的BW中连通集的个数。

老规矩,更详细信息请见 https://ww2.mathworks.cn/help/images/ref/bwlabel.html?s_tid=doc_ta
在这里插入图片描述
(2)location = find(V == key):在矩阵V中寻找值key,返回其位置(位置按照从左到右、从上到下的顺序)。

该函数用法多样,提供下面链接供参考:
https://ww2.mathworks.cn/help/matlab/ref/find.html?s_tid=doc_ta

(3) M = mean(A): 返回 A 沿大小不等于 1 的第一个数组维度的元素的均值。

如果 A 是向量,则 mean(A) 返回元素均值。
如果 A 为矩阵,那么 mean(A) 返回包含每列均值的行向量。
如果 A 是多维数组,则 mean(A) 沿大小不等于 1 的第一个数组维度计算,并将这些元素视为向量。此维度会变为 1,而所有其他维度的大小保持不变。

该函数用法多样,提供下面链接供参考:
https://ww2.mathworks.cn/help/matlab/ref/mean.html?s_tid=doc_ta

(4) sz = size(A, n):n 取1或者2,返回矩阵A的第一维度(行cow)或者第二维度(列column)。

该函数用法多样,提供下面链接供参考:
https://ww2.mathworks.cn/help/matlab/ref/size.html

OKOK~
上面我们已经找到了较好的将rice.png转化为二值图的方式
现在我们有两个问题:
one 米粒的最大size是多少?
two 米粒的平均size是多少?

解决的代码如下:

I = imread('rice.png');
BG = imopen(I, strel('disk', 15));
I2 = imsubtract(I, BG); level = graythresh(I2);
BW = im2bw(I2, level);
%%%%%%%%    上面是找背景BG的代码    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[labeled, numObjects] = bwlabel(BW, 8);   % labeled是BW的标记矩阵,numObjects是连通集的数量
num=zeros(1,numObjects);     % 创建1 x numObjects大小的全零矩阵num
for i=1:size(BW,1)                % for 行i(图BW的)
    for j = 1:size(BW,2)          %   for 列j(图BW的)
        for k = 1:numObjects
            if labeled(i,j)==k    % 如果矩阵labeled坐标(i,j)处 == k,就将矩阵num的k位置的值++
                num(k)=num(k)+1;    % 想一想,其实该位置的值是遍历中该label出现的次数,也就代表了size
            end
        end
    end
end
largest=find(num==max(num));      % 矩阵num中找出最大值的位置,即最大size的位置
s=mean(num);                      % s是平均size

得出的数据如下:
在这里插入图片描述
在这里插入图片描述

2. Object Properties : regionprops()

STATS = regionprops(L, properties):若properties为字符串’basic’,则属性:‘Area’,'Centroid’和’BoundingBox’将被计算。
rice.png 解释一下三个属性:
Area: 米粒大小
Centroid: 米粒中心坐标
BoundingBox: 能框住米粒的最小矩形的左上角坐标、右下角坐标 [x_left,y_left,x_right,y_right]

该函数用法多样,提供下面链接供参考:
https://ww2.mathworks.cn/help/images/ref/regionprops.html?requestedDomain=zh

我们用该函数对之前rice.png 的label 进行查看信息

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);
%%%%%   上面的都是前面的代码  %%%%%%%%%
graindata = regionprops(labeled, 'basic');    % 根据矩阵labeled 绘制一张basic信息表
graindata(51);      % 查看信息表中标号为51的basic信息

下面是得到的graindata——(1-28)
在这里插入图片描述

3. Interactive Selection : bwselect()

bwselect(BW):可以与二值图进行互动,挑选你想要的元素。

先上一段代码——

I = imread('rice.png');
BG = imopen(I, strel('disk', 15));
I2 = imsubtract(I, BG);
BW = im2bw(I2, graythresh(I2));

ObjI = bwselect(BW);
imshow(ObjI);

接下来看好了:
这是原图
在这里插入图片描述

我们用鼠标左键点击我们想要的米粒,下图米粒上有彩色米字形的,即我们选中的米粒:
在这里插入图片描述
接下来我们鼠标移到图像外边,但还在Figure里面的灰色区域并用鼠标右击灰色区域,接下来就是见证奇迹的时刻!
在这里插入图片描述


本笔记多采自YouTubeMATLAB教学视频

猜你喜欢

转载自blog.csdn.net/weixin_43469047/article/details/86703326