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


前言

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


一、实现样例

1. 黑白图


1.1.1 原图

原图

1.1.2 阈值分割后得到的图像

阈值分割后的图片

2. 彩色图


1.2.1 原图

在这里插入图片描述

阈值分割后的图像

在这里插入图片描述

二、代码注释

代码及注释如下:

%% 
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(:))分别为返回行向量中最小和最大的元素。
    元素变量转换为648字节)双精度浮点值。
    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比较,最后得到一个由01组成的矩阵
    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 行)
如果输入项为逻辑值(二进制),则必须是二维的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值