【数字图像处理】【Matlab】【实验四】图像分割


author:zox
实验环境:Matlab2019a


一、实验目的

  1. 理解图像分割的基本概念。
  2. 理解图像边缘提取的基本概念。
  3. 掌握用阈值法和边缘提取方法进行图像分割。

二、实验题目

  1. 采用阈值法实现图像分割,分别采用两种阈值选取方法实现。
  2. 分别用Roberts,Sobel和拉普拉斯高斯算子对图像进行边缘检测,比较三种算子处理的不同之处。
  3. 实现肺的分割,结果包括两部分:肺(白色显示)和背景(黑色显示)。
    在这里插入图片描述
图1 肺原图

三、实验内容

3.1 相关知识

1.基于阈值的图像分割方法

  图像分割就是将一幅图像分成若干个部分、区域,然后将其中自己感兴趣的部分,或对自己有意义的区域提取出来,由此获得一些有用的图像特征和信息的过程。
  图像分割有很多方法,其中基于阈值的分割方法最常使用。主要是利用图像中要提取的目标和背景在灰度上的差异,选择一个合适的阈值。
  ①直方图阈值法:通过图像的灰度直方图来选择阈值,图象被处理为二值图像。
  ②半阈值选择法:根据直方图或其他方法选择合适的阈值,但只对背景部分进行处理,这样目标物体就还是多值图像,背景是二值图像。
  ③迭代阈值法:通过程序不断迭代出所需要的阈值,再对图像二值化处理。
  ④Otsu算法:也叫最大类间差法,取一个最优阈值把原图像分为前景色(A部分)与背景色(B部分),两部分的类间方差越大,说明两部分差别越大,便能有效的分割图像。
  ⑤最大熵阈值分割法:计算所有分割阈值下的图像总熵,找到最大的熵,将最大熵对应的分割阈值作为最终的阈值,图像中灰度大于此阈值的像素作为前景,否则作为背景。

2.迭代阈值法

  迭代阈值法产生阈值,可以通过程序自动计算出比较合适的分割阈值。其计算步骤如下:
(1)选择灰度图的平均灰度值作为初始阈值 T 0 T0 T0 ,通过 T 0 T0 T0将图像的平均灰度值分为两组;
(2)计算小于等于 T 0 T0 T0的平均值 T 1 T1 T1, 和大于 T 0 T0 T0的平均值 T 2 T2 T2;
(3)新的阈值为 T = ( T 1 + T 2 ) / 2 T = (T1 + T2)/ 2 T=T1+T2/2;
(4)比较 T T T T 0 T0 T0,若相等,则返回 T T T,即为迭代阈值; 否则 T 0 = T T0 = T T0=T,重复(1)-(3)
最终的 T 0 T0 T0就是我们所需要的阈值,再根据阈值可对图像进行二值化处理。

3.Otsu算法

   O t s u Otsu Otsu(大津法或最大类间方差法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分,使得两个部分之间的灰度值差异最大,每个部分之间的灰度差异最小,通过方差的计算来寻找一个合适的灰度级别来划分。该算法的具体流程如下:
(1)根据某个阈值t,把原图像分为A部分(每个像素值>=t)与B部分(每个像素值<t);
(2)由方差计算公式可计算得到需要的下列值:总均值(all_ave),A部分所有比例(PA),B部分所占比例(PB),A部分均值(A_ave),B部分均值(B_ave);
(3)根据公式计算:类间方差 ( I C V ) = P A ∗ ( a v e A − a v e a l l ) 2 + P B ∗ ( a v e B − a v e a l l ) 2 (ICV)=PA*(ave_A-ave_all)^2+PB*(ave_B-ave_all)^2 ICV=PA(aveAaveall)2+PB(aveBaveall)2
(4)不断改变t,进行以上步骤,不断判断,得到最大类间方差的最优阈值。
   O t s u Otsu Otsu算法被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。因此,使类间方差最大的分割意味着错分概率最小。

4.算子原理及特点

1) R o b e r t s Roberts Roberts算子: 利用局部差分算子寻找边缘, 边缘定位精度较高, 但容易丢失一部分边缘, 同时由于图像没经过平滑处理, 因此不具备能抑制噪声能力。 对陡峭边缘且含噪声少的图像效果较好。
  首先使用以下模板分别对图像进行卷积操作:
   m o d e l x = [ 0 0 0 0 − 1 0 0 0 1 ]                   m o d e l y = [ 0 0 0 0 0 − 1 0 1 0 ] \ \ modelx=\left[\begin{matrix}0&0&0\\0&-1&0\\0&0&1\\\end{matrix}\right]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ modely=\left[\begin{matrix}0&0&0\\0&0&-1\\0&1&0\\\end{matrix}\right]   modelx=000010001                 modely=000001010
得到 Z x   , Z y Z_x\ ,Z_y Zx ,Zy
  接着根据公式对图像的所有点进行处理: Z = Z x 2 + Z y 2 Z=\sqrt{Z_x^2+Z_y^2} Z=Zx2+Zy2
2) S o b e l Sobel Sobel算子: 先做加权平滑处理, 再做微分运算, 平滑部分的权值有些差异, 对噪声具有一定的抑制能力, 但不能完全排除虚假边缘。 虽然这两个算子边缘定位效果不错, 但检测出的边缘容易出现多像素宽度。
  首先使用以下模板分别对图像进行卷积操作:
   m o d e l x = [ − 1 − 2 − 1 0 0 0 1 2 1 ]                   m o d e l y = [ 1 0 − 1 2 0 − 2 1 0 − 1 ] \ \ modelx=\left[\begin{matrix}-1&-2&-1\\0&0&0\\1&2&1\\\end{matrix}\right]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ modely=\left[\begin{matrix}1&0&-1\\2&0&-2\\1&0&-1\\\end{matrix}\right]   modelx=101202101                 modely=121000121
得到 Z x   , Z y Z_x\ ,Z_y Zx ,Zy
  接着根据公式对图像的所有点进行处理: Z = Z x 2 + Z y 2 Z=\sqrt{Z_x^2+Z_y^2} Z=Zx2+Zy2
3) L O G LOG LOG算子: 先用高斯函数平滑滤波, 后用 L a p l a c i a n Laplacian Laplacian算子检测边缘, 克服 L a p l a c i a n Laplacian Laplacian算子抗噪声差的缺点, 但同时也平滑掉比较尖锐的边缘, 尖锐边缘无法检被测到。
  使用以下模板对图像进行卷积操作:
m o d e l = [ − 2 − 4 − 4 − 4 − 2 − 4 0 8 0 − 4 − 4 8 24 8 − 4 − 4 0 8 0 − 4 − 2 − 4 − 4 − 4 − 2 ] model=\left[\begin{matrix}-2&-4&-4&-4&-2\\-4&0&8&0&-4\\-4&8&24&8&-4\\-4&0&8&0&-4\\-2&-4&-4&-4&-2\\\end{matrix}\right] model=24442408044824844080424442
  通过以上四种算子对图像进行处理可以得到图像的边缘信息。实验时直接使用的是实验二中所编写的函数。

5.肺的分割过程

  根据对已有的图片分析,得到图片的各个部分如下图2所示:
在这里插入图片描述

图2 原图分析

  为了将肺部区域分割出来,要进行如下的操作:
(1)首先采用阈值分割法分割出粗略的肺部分,使用前面编写的myotsu函数来获取图像阈值,对图像进行二值化处理。
(2)分析得到的图片中胸腔部分为白色,而我们需要的是肺部分为白色,其他背景为黑色,所以对图像进行反色处理。
(3)然后通过系统函数bwlabel()标记连通区域,再统计各个连通区域的面积来对气管部分和背景置黑色来统一背景。
  标记的原则如下:二值图像中值为 0 的区域 ( 对应于反色后图像中的胸腔内非肺区域 ) 作为背景,不予标记; 值≥1的区域 ( 对应于反色后图像中的目标肺组织区域、胸腔外区域和气管部分 ) 进行联通标记 , 并从数值 1 开始计数, 即标记 1 为第一个联通区域,标记2为第二个联通区域,以此类推。
  由于反色后标记区域的面积不同,所以计算各个连通区域的面积,根据连通区域的标号规则得到背景和气管部分所在的标号。
  再将根据面积大小找到的部分的像素点(即非肺区域)对应的原二值图像处赋值成 0,标记值大于 1 的像素点(即目标肺区域)对应的原二值图像处赋值成 1。

6.实验中直接使用的函数

(1)imread(path)函数:从图像所在路径读取图像的数据信息存为矩阵。
(2)imshow(image)函数:将读取到的图像显示到figure中。
(3)subplot(m,n,p)函数:subplot函数是将多个图画到一个平面上的工具。其中m、n表示一个m行n列的大画框,可显示 m ∗ n m*n mn个图 ,p表示图所在位置。
(4)构造函数
function[输出形参]=函数名([输入形参])
函数体
(5)size()函数
[m,n] = size(X)
返回矩阵X的尺寸信息, 并存储在m、n中。其中m中存储的是行数,n中存储的是列数。
(6)zeros(m,n)函数:产生 m ∗ n m*n mn的double类型零矩阵。
(7)im2double(x):数据变为双精度,便于计算,且使计算更加准确。
(8)min():获得最小元素
(9)max():获得最大元素
(10)abs():求数组平均值
(11)find(A):获得符合条件A的元素
(12)mean():求数组平均值
(13)bwlabel():获取连通区域
(14)myconvolve():实验二中编写的实现卷积操作的函数
(15)mysharpen():实验二中编写的根据选择的算子获取图像的边缘的函数

3.2 实验代码

【sy4.m】

clear all;close all;clc;
%% 1、采用阈值法实现图像分割,分别采用两种阈值选取方法实现。
I=imread('Fig1006(a).tif');
threshold1=myiteration(I);
threshold2=myotsu(I);
J1=im2bw(I,threshold1);
J2=im2bw(I,threshold2);
figure,suptitle('基于阈值的图像分割');                %Figure 1
subplot(131),imshow(I),axis on,title('原图') ; 
subplot(132),imshow(J1),axis on,title('迭代阈值法');
subplot(133),imshow(J2),axis on,title('otsu阈值法') ; 
%% 2、分别用Roberts,Sobel和拉普拉斯高斯算子对图像进行边缘检测,比较三种算子处理的不同之处。
E1=mysharpen(I,'Roberts');
E2=mysharpen(I,'Sobel');
E3=mysharpen(I,'Log');
figure,suptitle('边缘检测');                          %Figure 2
subplot(221), imshow(I), title('原图');
subplot(222), imshow(E1), title('Roberts算子');
subplot(223), imshow(E2), title('Sobel算子');
subplot(224), imshow(E3), title('Log算子');
%% 3、实现肺的分割,结果包括两部分:肺(白色显示)和背景(黑色显示)。 
Lung=imread('lung.jpg');
threshold=myotsu(Lung);
S1=im2bw(Lung,threshold);%二值化,将肺和胸腔等其他部分分隔开
S2=~S1;%反色,使肺部变为白色
X8=mycut(S2);%去掉胸腔外的背景和气管
figure,suptitle('肺的分割');                          %Figure 3
subplot(221),imshow(Lung),axis on,title('原图') ; 
subplot(222),imshow(S1),axis on,title('二值化');
subplot(223),imshow(S2),axis on,title('反色') ;
subplot(224),imshow(X8),axis on,title('分割后');

【myiteration.m】

% 函数myiteration:迭代阈值法
% 输入参数:I:原图像
% 输出参数:阈值threshold
% 使用函数:im2double(I):变为双精度
%         min():最小元素
%         max():最大元素
%         find(A):符合条件A的元素
%         mean():求数组平均值
%         abs():求绝对值
function threshold=myiteration(I)
I=im2double(I);     %变为双精度,即0-1
T0=0.01;            %参数T0
T1=(min(I(:))+max(I(:)))/2;%选取图像中最大像素和最小像素的中阈值作为T1
r1=find(I>T1);%灰度值大于T1的
r2=find(I<=T1);%其他
T2=(mean(I(r1))+mean(I(r2)))/2;%新的阈值T2    %mean函数是一个求数组平均值的函数
while abs(T2-T1)<T0
    T1=T2;
    r1=find(I>T1);%灰度值大于T1的
    r2=find(I<=T1);%其他
    T2=(mean(I(r1))+mean(I(r2)))/2;%新的阈值T2
end
threshold=T2;

【myotsu.m】

% 函数myotsu:最大类间差法
% 输入参数:I:原图像
% 输出参数:阈值threshold
% 使用函数:size(I):求矩阵大小
%         rgb2gray():rgb转化为灰度图像
%         im2double():变为双精度,即0-1
function threshold=myotsu(I)
[M,N,i]=size(I);     %得到图像行列值
if i>1
    I=rgb2gray(I);%若不是灰度图像则先处理为灰度图像
end
I=im2double(I);  %变为双精度,即0-1
number_all=M*N;  %总像素值
hui_all=0;       %预设图像总灰度值为0
ICV_t=0;        %预设最大方差为0
for i=1:M
    for j=1:N
        hui_all=hui_all+I(i,j);%得到图像总灰度值
    end
end
all_ave=hui_all*255/number_all;   %图像灰度值的总平均值
 
%t为某个阈值,把原图像分为A部分(每个像素值>=t)与B部分(每个像素值<t)
for t=0:255                       %不断试探最优t值
    hui_A=0;                      %不断重置A部分总灰度值
    hui_B=0;                      %不断重置B部分总灰度值
    number_A=0;                   %不断重置A部分总像素
    number_B=0;                   %不断重置B部分总像素
    for i=1:M                     %遍历原图像每个像素的灰度值
        for j=1:N
            if (I(i,j)*255>=t)    %分割出灰度值>=t的像素
                number_A=number_A+1;  %得到A部分总像素
                hui_A=hui_A+I(i,j);   %得到A部分总灰度值
            elseif (I(i,j)*255<t) %分割出灰度值<t的像素
                number_B=number_B+1;  %得到B部分总像素
                hui_B=hui_B+I(i,j);   %得到B部分总灰度值
            end
        end
    end
    PA=number_A/number_all;            %得到A部分像素总数与图像总像素的比列
    PB=number_B/number_all;            %得到B部分像素总数与图像总像素的比列
    A_ave=hui_A*255/number_A;          %得到A部分总灰度值与A部分总像素的比例
    B_ave=hui_B*255/number_B;          %得到B部分总灰度值与B部分总像素的比例
    ICV=PA*((A_ave-all_ave)^2)+PB*((B_ave-all_ave)^2);  %Otsu算法
    if (ICV>ICV_t)                     %不断判断,得到最大方差
        ICV_t=ICV;
        k=t;                           %得到最大方差的最优阈值
    end
end
threshold=k/255;                           %输出阈值

【mycut.m】

% 函数mycut:根据连通性去掉图片胸腔外的背景和气管
% 输入参数:I:原图像
% 输出参数:OUT:处理后的图片数据
% 使用函数:size(I):求矩阵大小
%         zeros():建全零矩阵
function OUT=mycut(I)
[x,y]=size(I);
[X8,N] = bwlabel(I,8);%8连通
% s=regionprops(X8,'Area');
% X8=ismember(X8,find([s.Area]>=7000&[s.Area]<=40000));
%% 计算各个连通区域的面积
Area=zeros(N,1);
for i=1:x
    for j=1:y
        for k=1:N
            if X8(i,j)==k
                Area(k,1)=Area(k,1)+1;
            end
        end
    end
end
%% 将白色部分连通区域的背景部分、气管部分置黑
for k=1:N
	if Area(k,1)>=7000 && Area(k,1)<=40000
        for i=1:x
            for j=1:y
                if X8(i,j)==k-1
                X8(i,j)=0;
                end
            end
        end
	end
end
OUT=logical(X8);

3.3 实验结果

在这里插入图片描述

图3 阈值分割法

在这里插入图片描述

图4 算子边缘检测

在这里插入图片描述

图5 肺的分割过程

四、实验心得

  1. 通过实现迭代阈值法和 O t s u Otsu Otsu算法获取阈值更深刻地理解阈值的概念;
  2. 通过对肺部分的分割了解了根据连通区域统一背景的方法,学会了对图片细节的处理;
  • 14
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zoxiii

越打赏越生长

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值