阈值分割与区域分割

Posted by jjx on January 1, 2017

本文主要包括以下内容

  • 阈值分割技术
  • 基于区域的图像分割技术
  • 本章的典型案例
    • 基于LoG和Canny算子的精确边缘检测
    • 基于Hough变换的直线检测
    • 图像的四叉树分解

阈值分割

我们曾在3.5节学习过灰度阈值变换的相关知识, 利用灰度阈值变换分割图像就称为阈值分割, 它是一种基本的图像分割方法。
阙值分割的基本思想是确定一个阈值, 然后把每个像素点的灰度值和阈值相比较,根据比较的结果把该像素划分为两类:前景或者背景,阈值分割可以分成以下3步:

  • 确定阈值.
  • 将阈值和像素比较,.
  • 把像素归类

其中第1步阈值最重要。阈值的选择将直接影响分割的准确性以及由此产生的图像描述,分析的正确性。

阈值分割方法

阈值分割常用的方法一般有以下几种。

实验法
实验法是通过人眼的观察, 对已知某些特征的图像, 只要试验不同的阈值, 然后看是否满足已知特征即可。这种方法的不足在于适用范围窄, 使用前必须了解图像的某些特征, 譬如平均灰度等,而且分割后图像质量的好坏受主观局限性很大。

根据直方图谷底确定阈值
如果图像的前景物体内部和背景区域的灰度值分布都比较均匀, 那么这个图像的灰度直方图将具有明显双峰, 此时可以选择两峰之间的谷底作为阈值。 其表达式为:

注意:由于直方图是各灰度的像素统计,其峰值和谷底特性不一定代表目标和背景.因此,如果没有图像其他方面的知识,只靠直方图进行图像分割不一定准确 .

迭代选择阈值法
迭代式阈值选择方法的基本思想是:开始选择一个阈值作为初始估计值,然后按照某种规则不断地更新这一估计值,直到满足给定的条件为止。这个过程的关键在于选择怎么样的 迭代规则。一个好的迭代规则必须既能够快速收敛,又能够在每一个迭代过程中产生优于上次迭代的结果。下面是一种迭代选择阈值算法:
(1)选择一个T的初始估计值。
(2)利用阈值T把图像分为两个区域R1, 和R2
(3)对区域R1和R2中的所有像素计算平均灰度值μ1和μ2
(4)计算新的阈值:
\(T=\frac{1}{2}(u_1+u_2)\)
(5)重复步骤2-4, 直到逐次迭代所得的T值小于事先定义的参数T。

最小均方误差法
最小均方误差法也是常用的阈值分割法之一。这种方法通常以图像中的灰度为模式特征,假设各模式的灰度是独立分布的随机变量,并假设图像中待分割的模式服从一定的概率分布。一般来说,采用的是正态分布,即高斯概率分布。
首先假设一幅图像仅包含两个主要的灰度区域前景和背景。令z表示灰度值,p(z)表示灰度值概率密度函数的估计值。假设概率密度函数一个对应于背景的灰度值,另一个对应于图像中前景即对象的灰度值。则描述图像中整体灰度变换的混合密度函数是:
\(p(z) = P_1p_1(z) + P_2p_2(z)\)
其中$P_1$是前景中具有值z的像素出现的概率,$P_2$是背景中具有值z的像素出现的概率,两者的关系为:
\(P_1+P_2=1\)

最大类间方差法
在对图像进行阈值分割时,选定的分割阈值应使前景区域的平均灰度、背景区域的平均灰度与整幅图像的平均灰度之间差别最大,这种差异用区域的方差来表示。由此,Otsu在1978年提出了最大方差法。该算法在判决分析最小二乘法原理的基础上推导得出,计算过程简单是一种稳定、常用的算法。

让T在[O,L-1]范围内依次取值, 使类间方差最大的T值便是最佳区域分割阈值。
该方法不需要人为设定其他参数,是一种自动选择阈值的方法,而且能得到较好的结果。它不仅适用于包含两个区域的单阈值选择,也同样适用于多区域的多阈值选择。

Matlab实现

最大类间方差法
Matlab中和阙值变换相关的两个主要函数是im2bw和graythresh。实际上,利用graythresh函数即可实现最大类间方差法。

迭代选择阈值法

function [Ibw, thres] = autothreshold(I)
% 迭代法自动阈值分割
%
% 输入:I - 要进行自动阈值分割的灰度图像
% 输出:Ibw - 分割后的二值图像
%      thres - 自动分割采用的阈值

thres = 0.5 * (double(min(I(:))) + double(max(I(:)))); %初始阈值
done = false; %结束标志
while ~done
	g = I >= thres;
	Tnext = 0.5 * (mean(I(g)) + mean(I(~g)));
	done = abs(thres - Tnext) < 0.5;
	thres = Tnext;
end;

Ibw = im2bw(I, thres/255); % 二值化

区域分割

前面所讲的图像分割方法都是基于像素的灰度来进行阈值分割, 本节将讨论以区域为基础的图像分割技术。传统的区域分割方法有区域生长和区域分裂与合井, 其中最基础的是区域生长法。

区域生长及其实现

区域生长是根据事先定义的准则将像素或者子区域聚合成更大区域的过程。其基本思想是从一组生长点开始(生长点可以是单个像素,也可以为某个小区域),将与该生长点性质相似的相邻像素或者区域与生长点合并,形成新的生长点,重复此过程直到不能生长为止。生长点和相邻区域的相似性判据可以是灰度值、纹理、颜色等多种图像信息。

区域生长算法
区域生长一般有3个步骤。
(1)选择合适的生长点。
(2)确定相似性准则即生长准则。
(3)确定生长停止条件。
一般来说, 在无像素或者区域满足加入生长区域的条件时, 区域生长就会停止。 上述方法比较的是单个像素与其邻域的灰度特征以实现区域生长,也有一种混合型区域生长把图像分割成若干小区域,比较相邻小区域的相似性,如果相似则合并。在实际中,区 域生长时经常还要考虑到生长的”历史”,还要根据区域的尺寸、形状等图像的全局性质来决定区域的合并。

matlab实现

function J = regionGrow(I)
% 区域生长,需要以交互方式设定初始种子点,具体方法为鼠标单击图像中一点后,按下回车键
%
% 输入:I - 原图像
% 输出:J - 输出图像

if isinteger(I)
    I=im2double(I);
end
figure,imshow(I),title('原始图像')
[M,N]=size(I);
[y,x]=getpts;             %获得区域生长起始点
x1=round(x);            %横坐标取整
y1=round(y);            %纵坐标取整
seed=I(x1,y1);           %将生长起始点灰度值存入seed中
J=zeros(M,N);          %作一个全零与原图像等大的图像矩阵J,作为输出图像矩阵
J(x1,y1)=1;             %将J中与所取点相对应位置的点设置为白
sum=seed;              %储存符合区域生长条件的点的灰度值的和
suit=1;                 %储存符合区域生长条件的点的个数
count=1;               %记录每次判断一点周围八点符合条件的新点的数目
threshold=0.15;         %阈值,注意需要和double类型存储的图像相符合
while count>0
    s=0;                   %记录判断一点周围八点时,符合条件的新点的灰度值之和
     count=0;
     for i=1:M
       for j=1:N
         if J(i,j)==1
          if (i-1)>0 & (i+1)<(M+1) & (j-1)>0 & (j+1)<(N+1)  %判断此点是否为图像边界上的点
           for u= -1:1                               %判断点周围八点是否符合阈值条件
            for v= -1:1
              if  J(i+u,j+v)==0 & abs(I(i+u,j+v)-seed)<=threshold& 1/(1+1/15*abs(I(i+u,j+v)-seed))>0.8
                           J(i+u,j+v)=1;
                    %判断是否尚未标记,并且为符合阈值条件的点
                    %符合以上两条件即将其在J中与之位置对应的点设置为白
                 count=count+1;
                 s=s+I(i+u,j+v);                      %此点的灰度之加入s中
              end
            end
           end
          end
         end
       end
     end
    suit=suit+count;                                   %将n加入符合点数计数器中
    sum=sum+s;                                     %将s加入符合点的灰度值总合中
    seed=sum/suit;                                    %计算新的灰度平均值
end

选择不同的生长点,结果不同。

区域分裂与合并

区域生长是从一组生长点开始的,另一种方法是在开始时将图像分割为一系列任意不相交的区域, 然后将它们合并或者拆分以满足限制条件, 这就是区域分裂与合并。 通过分裂, 可以将不同特征的区域分离开, 而通过合并, 可以将相同特征的区域合并起来。

区域分裂与合并算法
图像先分裂为如图9.22Ca)所示;第二次分裂时,如图(b)所示,由于左下角区域满足$P(R_i)=TRUE$,则不进行分裂操作;第三次分裂时,如图(c)所示,仅仅右边的突出部分 $P(R_i)=FALSE$, 需要进行分裂操作,其余不变,完成后,分裂停止;最后,对两个相邻区域 实行合并,一直得到最后的结果,如图(d)所示。
区域分裂与合并对分割复杂的场景图像比较有效,如果引入应用领域知识,则可以更好地提高分割效果。

区域分裂的Matlab实现
在Matlab中, 和区域分裂相关的3个主要函数分别是qtdecomp、qtgetblk和qtsetblk。

(1) qtdecomp函数
Matlab的IPT函数qtdecomp可以进行四叉树分解。该函数首先将图像划分成相等大4的4块,然后对每一个块进行一致性检查。如果该块不符合一致性标准, 则将该块继续分为4块; 否则不对其进行进一步的分割。这个过程将会一直重复直至每一个块都符合一致性标 准, 分解的结果可能会包含许多大小不同的块。
qtdecomp函数的常用调用形式为:
S = qtdecomp(I,threshold,[mindim,maxdim])

threshold是分割成的子块中允许的阈值,默认值为0.如杲子块中最大元素和最小元 素的差值小于该阈值就认为满足一致性条件.对于double型矩阵,threshold将直接作为阈值;而对于uinit8和uintl6类型的矩阵,threshold将被乘以255和65535以作为实际阈值.对于图像而言,threshold的取值范围是0到1.

[mindim maxdim]是尺度阈值.mindim参数可以屏蔽函数对尺度上小于mindim的子块的处理,而不论这个子块是否满足一致性条件;如果参数形式为[mindim maxdim], 则表示不产生小于mindim尺度的子块,也不保留大于maxdim尺度的子块,此时 maxdim/mindim必须是2的整数次幂

注意: qtdecomp函数主要适用于边长是2的整数次幂的正方形图像, 如128x128,512x512, 此时分解可一直进行至子块大小为1x1。对于长宽不是2的整数次幂的图像, 分解可能无法进行到底. 例如, 对于96x96 的图像, 将首先分解为48x48, 然后是24x24, 12*12, 6*6, 最后是3x3, 无法再继续分解. 此时必须指定mindim参数为3或是2的整数次幕与3的乘积.

(2) qtgetblk函数 在得到稀疏矩阵S后, 利用IPT函数qtgetblk可进一步获得四叉树分解后所有指定大小的子块像素及位置信息。常用调用形式为:
[vals,r,c]=qtgetblk(I,S,dim)
稀疏矩阵S是经过qtdecomp函数处理的输出结果.
dim是指定子块的大小

vals是dimdimk的三维矩阵,包含I中所有符合条件的子块数据。其中k为符合 条件的dim*dim的大小的子块的个数,vals(:.:,i)表示符合条件的第i个子块的内容.
r和c均为列向量,分别表示图像I中符合条件子块左上角的纵坐标(行索引)和横坐标(列索引).

(3) qtsetblk函数
在将图像划分为子块后, 还需要使用函数qtsetblk将四叉树分解所得到的子块中符合条件的部分全部替换为指定的子块。函数语法为:
J = qtsetblk(I,S,dim,vals)
S是I经过qtdecomp函数处理的结果.
dim是指定的子块大小.
vals是dimdimk的三维矩阵,包含了用来替换原有子块的新子块信息.其中K应为图像I中大小为dim*dim的子块的总数,vals(:,:,i)表示要替换的第i个子块.

I1 = imread('rice.png');

S = qtdecomp(I1,0.2);
S2 = full(S);

figure;
subplot(1,2,1),imshow(I1);
subplot(1,2,2),imshow(S2);

ct = zeros(6,1);
for ii = 1:6
    [vals{ii},r,c]=qtgetblk(I1,S2,2^(ii-1));
    ct(ii) = size(vals(ii),3);
end

小结
图像分割问题是一个十分困难的问题。因为分割后的图像是系统目标的一个函数, 所以根本不存在理想的或正确的分割。
物体及其组成部件的二维表现形式受到光照条件、透视畸变、观察点变化、遮挡等的影响。此外, 物体及其组成部件与背景之间在视觉上可能无法区分。因此, 人们无法预测能够从图像中抽取出哪些与物体识别相关的初始信息。
唯一可以肯定的是,这一过程将在本质上具有不可靠性。某些有用的信息能够被抽取出,且同时也会出现许多错误。因此,在任何应用领域中都不存在最优解。分割结果的好坏或者正确与否, 目前还没有一个统一的评价判断标准, 大都从分割的视觉效果和实际的应用场景来判断。