模糊阈值
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
原始图像:直方图:
从上图可以看出,经过模糊化后,直方图变的平滑了很多,下一步主要进行曲线最小值的搜索。
另外,模糊缺陷的保值性与窗宽nWinWidth 有很大的关系,窗宽取的合适,获得的模糊曲线就更容易分割。而所谓自适应模糊化分割,就是找到合适的nWinWdith,目前,找合适的nWinWdith有很多方法,大部分都是搜索法,然后按照设定的准则停止(比如文中讲到的极点法、还有区间法等)搜索,最后获得合适的nWinWidth。
我将再后续的工作中,尝试不同的搜索方法,并把代码奉上。
模糊阈值分割(2)
根据模糊阈值分割的原理,本文在“模糊阈值分割代码(1)"的基础上进行了拓展,主要是利用图像直方图,搜索最佳波谷阈值,实现多阈值分割。
其过程主要如下:
1. 获取图像直方图
2. 进行直方图平滑,以去毛刺
3. 进行波峰搜索。这部分比较复杂,需要考虑的问题也多。包括波峰的判定准则、伪峰值的去除、半峰值的判断等等。一般来说,一个峰值包括起始位置(上坡段)、终止位置(下坡段)和峰值位置。本文上、下坡段判断是通过连续增长(下降)的数量来判断的,比如连续超过10个增长的就认为是上坡段,而连续10个下降的就是下坡段。当然了,有些峰值非常小,这个就需要缩小判定阈值。峰值的位置是在上下坡段的区间内取重心的方式得到的(见函数GetPeaks)。
4. 在波峰之间采用S函数的模糊化(MemshipFunc),获得模糊曲线。我们知道,模糊化的过程窗口的宽度很重要,一般窗宽取峰值距离的0.3~0.8。由于上一步把峰值取到了,所以这一步就可以根据峰值间的距离设定窗宽,达到自适应的目的。
5. 获得模糊率曲线后,搜索不同峰值间的最小值就可以获得分割阈值。
[cpp]view plaincopy
1.struct Peack
2.{
3.int nStat;
4.int nEnd;
5.int nValue;
6. Peack():nStat(0),nEnd(0),nValue(0)
7. {}
8.};
9./*
10.名称:BlurCure
11.参数:lpBmp - 图像数据指针
12. lSrcWidth - 图像宽度
13. lSrcHeight - 图像高度
56.else//if(nTistogram[i] < nPreValue)
57. {
58.static int s_nLowNum = 0;
59.if(pTistogram[i] < nPreValue)
60. {
61. s_nLowNum ++;
62.if(s_nLowNum == i && s_nLowNum > 10)
63. arrPos[0] = 1;
64. }
65.else if(nContinueNum > 2)
66. nContinueNum ++;
67.else
68. nContinueNum = 0;
69. }
70. }
71./////////////////////////////////
72. nPreValue = pTistogram[i];
73. }
74.//============峰值计算==============
75.int nSum = 0,nTistoSum = 0;
76. vector
77.while (it != vctPeak.end())
78. {
79. nSum = nTistoSum = 0;
80.for (int i=(*it).nStat; i<=(*it).nEnd; i++)
81. {
82. nSum += i*pTistogram[i];
83. nTistoSum += pTistogram[i];
84. }
85. (*it).nValue = nSum/nTistoSum;
86. it++;
87. }
88.}
下面是“模糊阈值分割代码(1)”中的瓶底图像获得的峰值信息:
三个阈值信息:
最终的分割结果:
从图上可以看出,该种方法还是比较准确的得到了分割的阈值,结果还是比较理想的。
当然,这是针对的多峰值的情况,对于单峰值的情况也是适用的。
其实这种算法在上世纪80年代就已经推出了,之所以没有推广开,问题是在求解的过程中有很多不确定性。比如峰值的确定,本身峰值怎么求的准确就是一个困难的问题,特别是在复杂的情况下,比如弱灰度、有噪音的情况,峰值往往并不明显。而要获得自私应的模糊阈值的,其窗宽又依赖于峰值选取的结果,结果可想而知,通用性就大大降低了!要解决这类算法的通用性问题,首先要减小不确定性,这也是现在依旧在探讨的问题。
Crtbp 函数源代码:(由谢菲尔德大学Andrew Chipperfield编写)
% CRTBP.m - Create an initial population%
% This function creates a binary population of given size and structure.
%
% Syntax: [Chrom Lind BaseV] = crtbp(Nind, Lind, Base)
%
% Input Parameters:
%
% Nind - Either a scalar containing the number of individuals % in the new population or a row vector of length two % containing the number of individuals and their length. %
% Lind - A scalar containing the length of the individual
% chromosomes.
%
% Base - A scalar containing the base of the chromosome
% elements or a row vector containing the base(s)
% of the loci of the chromosomes.
%
% Output Parameter
s:
%
% Chrom - A matrix containing the random valued chromosomes
% row wise.
%
% Lind - A scalar containing the length of the chromosome.
%
% BaseV - A row vector containing the base of the
% chromosome loci.
% Author: Andrew Chipperfield
% Date: 19-Jan-94
function [Chrom, Lind, BaseV] = crtbp(Nind, Lind, Base)
nargs = nargin ;
% Check parameter consistency
if nargs >= 1, [mN, nN] = size(Nind) ; end
if nargs >= 2, [mL, nL] = size(Lind) ; end
if nargs == 3, [mB, nB] = size(Base) ; end
if nN == 2
if (nargs == 1)
Lind = Nind(2) ; Nind = Nind(1) ; BaseV = crtbase(Lind) ;
elseif (nargs == 2 & nL == 1)
BaseV = crtbase(Nind(2),Lind) ; Lind = Nind(2) ; Nind = Nind(1) ;
elseif (nargs == 2 & nL > 1)
if Lind ~= length(Lind), error('Lind and Base disagree'); end
BaseV = Lind ; Lind = Nind(2) ; Nind = Nind(1) ;
end
elseif nN == 1
if nargs == 2
if nL == 1, BaseV = crtbase(Lind) ;
else, BaseV = Lind ; Lind = nL ; end
elseif nargs == 3
if nB == 1, BaseV = crtbase(Lind,Base) ;
elseif nB ~= Lind, error('Lind and Base disagree') ;