Matlab课后笔记——阈值分割之迭代选择阈值法

文章目录

前言

在Matlab中图像分割是一个很重要的手段,其中迭代选择阈值法的阈值分割算是入门代码。这一次老师给的作业是去补全其中代码的注释,在补全代码的过程中自己了解到了一些新知识,尽管知识很简单,代码也很短,但是自己还是花费了一段时间去了解其中每个代码运行的含义,所以想记录一下这个过程。

一、实现样例

1. 黑白图

1.1.1 原图

Matlab课后笔记——阈值分割之迭代选择阈值法

1.1.2 阈值分割后得到的图像

Matlab课后笔记——阈值分割之迭代选择阈值法

; 2. 彩色图

1.2.1 原图

Matlab课后笔记——阈值分割之迭代选择阈值法

阈值分割后的图像

Matlab课后笔记——阈值分割之迭代选择阈值法

二、代码注释

代码及注释如下:

%%
clc;
clear;
close all;

%% 导入所需图片并设置为所需格式
% filename = 'fingerprint';  %导入图片
filename = 'wood_dowels';   %导入图片
im = imread([filename, '.tif']);
    % 文件类型为.tif,这个文件是一个大小为531x675的矩阵
    % 可以用size(im)等命令或者直接点击原资源查看
% im=rgb2gray(im);
    % 将RGB通道的三维图(即彩色图)转为二维图(黑白图),在进行阈值分割。在传入的图片为二维图时,此行代码需要注释
%% 更新到合理的阈值,方便之后进行基于阈值的图像分割
thres = 0.5*(   double(min(im(:))) + double(max(im(:)))  );
    %{
    初步设定一个阈值,在阈值分割里面,像素点大于这个阈值的,为目标,小于的为背景。
    max(im(:))=255,max(im(:))=2
    im(:)为先把im文件由矩阵形式转换为一个行向量。
    min(im(:))和max(im(:))分别为返回行向量中最小和最大的元素。
    元素变量转换为64(8字节)双精度浮点值。
    thres为一个double类型的值
    参考资料:  https://zhidao.baidu.com/question/335941648.html
    https://blog.csdn.net/mxr2026588745/article/details/108990666
    %}
done = false;   % 预设逻辑值
while ~done    % ~ 为计算逻辑NOT,即while ture
    g = im >=thres;
    %{
    矩阵im里面的元素依次与thres比较,最后得到一个由0和1组成的矩阵
    g的结果为一个维度数与矩阵im维度数一样的矩阵,数据类型是logical(逻辑值)
    即g = (im >=thres);
    %}
    Tnext = 0.5 * (   mean(im(g)) + mean(im(~g))  );
        %{
        im(g)为大于等于阈值的值,是一维矩阵,假设有im中有a个元素大于等于阈值,im(g)这个一维矩阵便有a行1列
        同理im(~g)为小于阈值的值,也是一维矩阵,假设im中有b个元素小于阈值,im(~g)这个一维矩阵便有b行1列
        mean为取平均值,经过运算得到新的阈值Tnext
        因为im(g)和im(~g)都是一维矩阵,所以通过mean函数求平均值时,可以各自得到唯一一个平均值,而不像二维向量一样,每一列都有一个平均值。
        可以在控制台通过输入mean(im),mean(im(g)),mean(im(~g))验证
        %}
    done = abs(thres - Tnext)<0.5;
        %{
        done为false时循环一直进行,在这个过程中不断更新阈值,直到取到较为理想的阈值,即新得到的阈值与上一轮的阈值结果相差不大,类似聚类算法里面寻找新的聚类中心。
        结束时Tnext与thres的差距的绝对值控制在了0.5之内
        %}
    thres = Tnext;
        % 不断更新,得到新的阈值。
end
Ibw = imbinarize(im,thres/255);
    % imbinarize,im2bw函数是基于阈值将图像转换为二值图像,在这里大于阈值的为值1(白色),小于阈值的为值0(黑色)

%% 输出结果
imshow(Ibw)
    % 图像分割之后得到的图像
    % inshow是显示二维图片的,如果传入的是三维图片会无法显示
    % 二维图片是黑白的,三维图片是彩色的(RGB通道)
    % 三维图片可通过rgb2gray()函数将三维图片转换为二维图片,再进行阈值分割。
fprintf('The threshold vakue is %8.5f\n', thres);
    % 显示阈值

 %% 过程中观察变量输出结果
 %{
    % fprintf('The max(im(:)) is %8.5f\n', max(im(:)));
    % fprintf('The min(im(:)) is %8.5f\n', min(im(:)));
    % fprintf('The thres is %8.5f\n', thres);
    fprintf('The im is %8.5f\n', im);
    fprintf('The im(g) is %8.5f\n', im(g));
    fprintf('The im((~g) is %8.5f\n', im(~g));
    fprintf('The mean(im(g)) is %8.5f\n', mean(im(g)));
    fprintf('The mean(im(~g)) is %8.5f\n', mean(im(~g)));
    fprintf('The Tnext is %8.5f\n', Tnext);
    %}

三、总结

1. 自己所理解的原理

1.基于迭代选择阈值法的阈值分割,是把二维图像输入,通过理想的阈值和二值化明确分割目标与背景。
2.理想的阈值是基于图像本身的像素点,灰度值,通过多次迭代得到的。
3.阈值得到之后,使用im2bw或imbinarize函数进行二值化(新版本的matlab倾向于让用户选择imbinarize),灰度值大于阈值的像素点变为1,成为目标;灰度值小于阈值的像素点变为0,成为背景。
4.最终输出结果。

2. 过程中观察到的有趣现象

1.过程中矩阵维数的变化,函数运用之后变量数值的变化,在控制台单独输出查看,加深了对这个过程的理解。
2.三维图像(即彩色图像),进行基于迭代选择阈值法的阈值分割需要先通过

二维图=rgb2gray(三维图)

函数来转换,之后的步骤一样。之所以需要转换是因为

imshow()

函数输入的参数并不支持三维的。不进行转换的话汇报以下错误:

错误使用 images.internal.imageDisplayValidateParams>validateCData (第 xx 行)
如果输入项为逻辑值(二进制),则必须是二维的。

Original: https://blog.csdn.net/TheTao007/article/details/121881521
Author: TheTao007
Title: Matlab课后笔记——阈值分割之迭代选择阈值法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/633533/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球