图像分割文档格式.docx
《图像分割文档格式.docx》由会员分享,可在线阅读,更多相关《图像分割文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
(c)凸缘型
图一边缘灰度变换的几种类型
由于边缘是图像上灰度变化最剧烈的地方,传统的边缘检测就是利用了这个特点,对图像各个像素点进行微分或求二阶微分来确定边缘像素点。
一阶微分图像的峰值处对应着图像的边缘点;
二阶微分图像的过零点处对应着图像的边缘点。
根据数字图像的特点,处理图像过程中常采用差分来代替导数运算,对于图像的简单一阶导数运算,由于具有固定的方向性,只能检测特定方向的边缘,所以不具有普遍性。
为了克服一阶导数的缺点,我们定义了图像的梯度为梯度算子为
,它是图像处理中最常用的一阶微分算法,式子中
表示图像的灰度值,图像梯度的最重要性质是梯度的方向是在图像灰度最大变化率上,它恰好可以放映出图像边缘上的灰度变化。
图像边缘提取的常用梯度算子有Robert算子、Sobel算子、Prewitt算子、Krisch算子等。
下面以边缘检测Sobel算子为例来讲述数字图像处理中边缘检测的实现:
对于数字图像,可以用一阶差分代替一阶微分;
△xf(x,y)=f(x,y)-f(x-1,y);
△yf(x,y)=f(x,y)-f(x,y-1);
求梯度时对于平方和运算及开方运算,可以用两个分量的绝对值之和表示,即:
Sobel梯度算子是先做成加权平均,再微分,然后求梯度,即:
△xf(x,y)=f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1)-f(x-1,y-1)-2f(x,y-1)-f(x+1,y-1);
△yf(x,y)=f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)-f(x+1,y-1)-2f(x+1,y)-f(x+1,y+1);
G[f(x,y)]=△xf(x,y)+△yf(x,y);
上述各式中的像素之间的关系见图二
F(x-1,y-1)F(x,y-1)F(x+1,y-1)F(x-1,y)F(x,y)F(x+1,y)F(x-1,y+1)F(x,y+1)F(x+1,y+1) 图二Sober算子中各个像素点的关系图
我在视图类中定义了响应菜单命令的边缘检测Sobel算子实现灰度图像边缘检测的函数(图像数据的获取可以参见我在天极网上发表的的相关文章):
voidCDibView:
:
OnMENUSobel()
{
CClientDCpDC(this);
HDChDC=pDC.GetSafeHdc();
//获取当前设备上下文的句柄;
SetStretchBltMode(hDC,COLORONCOLOR);
HANDLEdata1handle;
LPDIBHDRTMAPINFOHEADERlpDIBHdr;
CDibDoc*pDoc=GetDocument();
HDIBhdib;
unsignedchar*lpDIBBits;
unsignedchar*data;
hdib=pDoc->
m_hDIB;
//得到图象数据;
lpDIBHdr=(LPDIBHDRTMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);
lpDIBBits=lpDIBHdr+*(LPDWord)lpDIBHdr+256*sizeof(RGBQUAD);
//得到指向位图像素值的指针;
data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpDIBHdr->
biWidth*8)*lpDIBHdr->
biHeight);
//申请存放处理后的像素值的缓冲区
data=(unsignedchar*)GlobalLock((HGLOBAL)data1handle);
AfxGetApp()->
BeginWaitCursor();
inti,j,buf,buf1,buf2;
for(j=0;
jbiHeight;
j++)//以下循环求(x,y)位置的灰度值
for(i=0;
ibiWidth;
i++)
{
if(((i-1)>
=0)&
&
((i+1)biWidth)&
((j-1)>
((j+1)biHeight))
{//对于图像四面边界处的向素点不处理
buf1=(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->
biWidth*8)+(j-1))
+2*(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->
biWidth*8)+(j))
+(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->
biWidth*8)+(j+1));
buf1=buf1-(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->
-2*(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->
-(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->
//以上是对图像进行水平(x)方向的加权微分
buf2=(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->
biWidth*8)+(j+1))
+2*(int)(int)*(lpDIBBits+(i)*WIDTHBYTES(lpDIBHdr->
+(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->
buf2=buf2-(int)(int)*(lpDIBBits+(i-1)*WIDTHBYTES(lpDIBHdr->
-2*(int)(int)*(lpDIBBits+(i)*WIDTHBYTES(lpDIBHdr->
-(int)(int)*(lpDIBBits+(i+1)*WIDTHBYTES(lpDIBHdr->
biWidth*8)+(j-1));
//以上是对图像进行垂直(y)方向加权微分
buf=abs(buf1)+abs(buf2);
//求梯度
if(buf>
255)buf=255;
if(buf<
0)buf=0;
*(data+i*WIDTHBYTES(lpDIBHdr->
biWidth*8)+j)=(BYTE)buf;
}
else*(data+i*lpDIBHdr->
biWidth+j)=(BYTE)0;
}
j++)
for(i=0;
*(lpDIBBits+i*WIDTHBYTES(lpDIBHdr->
biWidth*8)+j)=*(data+i*WIDTHBYTES(lpDIBHdr->
biWidth*8)+j);
//处理后的数据写回原缓冲区
StretchDIBits(hDC,0,0,lpDIBHdr->
biWidth,lpDIBHdr->
biHeight,0,0,
lpDIBHdr->
biHeight,
lpDIBBits,(LPDIBHDRTMAPINFO)lpDIBHdr,
DIB_RGB_COLORS,
SRCCOPY);
上述的数学分析读者可能看起来有些吃力,不过不要紧,对与边缘检测,大家只要知道有若干个检测模板(既边缘检测矩阵)可以直接实现检测功能就行了,现在将常用的检测实现公式列出如下(检测模版可以从相应的算法很轻易的得到):
Roberts算子:
G[i,i]=f[i,j]-f[i+1,j+1]+f[i+1,j]-f[i,j+1];
Sobe算子:
G[i,i]=f[i-1,j+1]+2f[i,j+1]+f[i+1,j+1]-f[i-1,j-1]-2f[i,j-1]-f[i+1,j-1]
+f[i-1,j-1]+2f[i-1,j]+f[i-1,j+1]-f[i+1,j-1]-2f[i+1,j]-f[i+1,j+1];
其中G[i,j]表示处理后(i,j)点的灰度值,f[i,j]表示处理前该点的灰度值。
Photoshop教程数据结构五笔输入法专题QQ病毒专题共享上网专题Google工具和服务专题 Kirsch算子实现起来相对来说稍微麻烦一些,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方向作出最大响应,运算中取最大值作为图像的边缘输出(上述算法中用到的8个模板在下面的实现代码中给出)。
为了便于读者理解该算法的实现,这里我们给出实现该算法的函数代码,读者可以稍加改动应用到自己的项目中去。
BOOLKirsch(BYTE*pData,intWidth,intHeight)
{//定义实现Kirsch算法的8个模板;
inti,j,s,t,k,max,sum[8];
statica[3][3]={{+5,+5,+5},{-3,0,-3},{-3,-3,-3}};
statica1[3][3]={{-3,+5,+5},{-3,0,+5},{-3,-3,-3}};
statica2[3][3]={{-3,-3,+5},{-3,0,+5},{-3,-3,+5}};
statica3[3][3]={{-3,-3,-3},{-3,0,+5},{-3,+5,+5}};
statica4[3][3]={{-3,-3,-3},{-3,0,-3},{+5,+5,+5}};
statica5[3][3]={{-3,-3,-3},{+5,0,-3},{+5,+5,-3}};
statica6[3][3]={{+5,-3,-3},{+5,0,-3},{+5,-3,-3}};
statica7[3][3]={{+5,+5,-3},{+5,0,-3},{-3,-3,-3}};
BYTE*pData1;
if(pData==NULL)
AfxMessageBox("
图像数据为空,请读取图像数据!
"
);
returnFALSE;
pData1=(BYTE*)newchar[Width*Height];
if(pData1==NULL)
图像缓冲数据区申请失败,请重新申请图像数据缓冲区!
returnFALSE;
memcpy(pData1,pData,Width*8*Height);
//kirsch算子处理,对每一像素点求取八个方向的导数;
;
for(i=1;
i<
Height-1;
i++)
for(j=1;
j<
Width-1;
j++)
{
sum[1]=sum[2]=sum[3]=sum[4]=sum[5]=sum[6]=sum[7]=sum[8]=0;
for(t=-1;
t<
2;
t++)
for(s=-1;
s<
s++)
{sum[1]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a[1+t][1+s];
sum[2]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a1[1+t][1+s];
sum[3]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a2[1+t][1+s];
sum[4]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a3[1+t][1+s];
sum[5]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a4[1+t][1+s];
sum[6]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a5[1+t][1+s];
sum[7]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a6[1+t][1+s];
sum[8]+=*(pData+WIDTHBYTES(Width*8)*(i+t)+j+s)*a7[1+t][1+s];
//取最大方向的导数;
for(k=0;
k<
8;
k++)
max=0;
if(max<
sum[k])
max=sum[k];
0)
if(max>
255)
max=255;
*(pData1+Width*8*i+j)=max;
memcpy(pData,pData1,Width*8*Height);
deletepData1;
returnTRUE;
另外还有一种称为拉普拉斯的算子是不依靠于边缘方向的二阶微分算子,其表示式
,对于数字图像来说拉普拉斯算子可以简单表示为:
G[I,j]=f[i+1,j]+f[i-1,j]+f(i,j+1)+f[i,j-1]-4f[i,j];
它是一个标量而不是向量,具有旋转不变,既各向同性的性质,它经常用在图像处理的过程中。
梯度算子和拉普拉斯算子对噪声敏感,它们都使噪声成份加强,因此在处理含有较大噪声的图像时,经常先对图像进行平滑操作,然后再进行二阶微分,这就产生了所谓的LOG(又称为Marr方法)边缘检测方法。
它先用高斯函数对图像进行平滑,然后再用拉普拉斯算子进行运算。
总的来说,传统的边缘检测算子的噪声平滑能力和边缘定位能力是矛盾的,为了克服这个不足,正确地得到图像的边缘信息,人们提出了很多方法,如多尺度空间滤波、Facet模型检测边缘、模板匹配、Hough变换、小波变换、人工神经网络、模糊推理等算法。
但这些方法绝大多数没有经典的算法精简,要么难以获得合理的计算复杂度,要么需要人为的调节各种参数,有时甚至难以实时运行。
因为传统边缘的定义为图像中灰度的突变,所以这样定义边缘既失去了边缘的部分信息,又把噪声的影响包含在了边缘中。
其实,边缘往往具有以下特征:
1)灰度突变;
2)是不同区域的边界;
3)具有方向性;
根据边缘的这三个特征,可以判定所关心的区域其特征是否存在差异来判定是否存在边缘的可能性。
假如特征没有差异,则认为是平滑区;
假如特征有差异,则判定为边缘点。
算法的具体实现步骤如下:
1)设置四个3x3模板如图三所示,显而易见,四个模板分别按0、45、90、135以(x,y)点为中心将3x3的区域分成两个部分,按照这四个模板分别对图像中的每一像素点进行卷积求和操作。
2)对图像中每一像素点求的四个结果求绝对值,将每个结果分别与一个阈值比较,假如其中任意一结果大于或等于阈值T,则该模板的中心点所对应的图像像素点的灰度值为255,否则为0。
图三边缘提取模板
对于有噪声的图像,由于噪声是随机分布的,因此不论(x,y)是有效边界点还是处于平坦区域内部,沿边缘方向划分的两个区域R1和R2的噪声分布和噪声强度,在概率上相同。
从四个模板的结构可以看出,噪声的影响基本上被相应的抵消,不会对边缘提取产生太大的影响,因此该算法具有较好的抗噪能力,克服了传统的边界提取仅考虑灰度突变的情况的局限。
经实验证实该方法有较强的抗噪声性能。
为了更好的对比各种算法进行边缘检测的效果,我们对一幅汽车图像进行了处理,下图中的a、b、c、d是分别通过LOG算子、Sober算子、Kirsch算子和使用上述算法检测得到的边缘。
(a)原始图像
(b)LOG算子
(c)Sober算子
(d)Kirsch算子
(e)模板检测法
图四图像的边缘检测
从上面的处理后的效果图来说,只有最后一种算法处理后肉眼看不出有噪声点,所以从去噪和提取边缘的综合效果来看,我们上述介绍的模板检测算法还是比较另人满足的。
Photoshop教程数据结构五笔输入法专题QQ病毒专题共享上网专题Google工具和服务专题 三、图像的二值化
所谓二值图像,就是指图像上的所有点的灰度值只用两种可能,不为"
0"
就为"
255"
,也就是整个图像呈现出明显的黑白效果。
为了得到理想的二值图像,一般采用阈值分割技术,它对物体与背景有较强对比的图像的分割非凡有效,它计算简单而且总能用封闭、连通的边界定义不交叠的区域。
所有灰度大于或等于阈值的像素被判决为属于物体,灰度值用"
表示,否则这些像素点被排除在物体区域以外,灰度值为"
,表示背景。
这样一来物体的边界就成为这样一些内部的点的集合,这些点都至少有一个邻点不属于该物体。
假如感爱好的物体在内部有均匀一致的灰度值,并且其处在一个具有另外一个灰度值的均匀背景下,使用阈值法可以得到比较好的效果。
假如物体同背景的差别不在灰度值上(比如纹理不同),可以将这个性质转换为灰度的差别,然后利用阈值化技术来分割该图像。
为了使分割更加鲁棒,适用性更强,系统应该可以自动选择阈值。
基于物体、环境和应用域等知识的图像分割算法比基于固定阈值的算法更具有普遍性和适应性。
这些知识包括:
对应于物体的图像灰度特性、物体的尺寸、物体在图像中所占的比例、图像中不同类型物体的数量等。
其中图像直方图就是一种灰度特性,通常被用来作为分割图像的工具。
阈值分割法分为全局阈值法和局部阈值分割法。
所谓局部阈值分割法是将原始图像划分成较小的图像,并对每个子图像选取相应的阈值。
在阈值分割后,相邻子图像之间的边界处可能产生灰度级的不连续性,因此需用平滑技术进行排除。
局部阈值法常用的方法有灰度差直方图法、微分直方图法。
局部阈值分割法虽然能改善分割效果,但存在几个缺点:
(1)每幅子图像的尺寸不能太小,否则统计出的结果无意义。
(2)每幅图像的分割是任意的,假如有一幅子图像正好落在目标区域或背景区域,而根据统计结果对其进行分割,也许会产生更差的结果。
(3)局部阈值法对每一幅子图像都要进行统计,速度慢,难以适应实时性的要求。
全局阈值分割方法在图像处理中应用比较多,它在整幅图像内采用固定的阈值分割图像。
经典的阈值选取以灰度直方图为处理对象。
根据阈值选择方法的不同,可以分为模态方法、迭代式阈值选择等方法。
这些方法都是以图像的直方图为研究对象来确定分割的阈值的。
另外还有类间方差阈值分割法、二维最大熵分割法、模糊阈值分割法、共生矩阵分割法、区域生长法等等。
对于比较简单的图像,可以假定物体和背景分别处于不同的灰度级,图像被零均值高斯噪声污染,所以图像的灰度分布曲线近似认为是由两个正态分布函数(
)和(
)叠加而成,图像的直方图将会出现两个分离的峰值,如图五所示。
对于这样的图像,分割阈值可以选择直方图的两个波峰间的波谷所对应的灰度值作为分割的阈值。
这种分割方法不可避免的会出现误分割,使一部分本属于背景的像素被判决为物体,属于物体的一部分像素同样会被误认为是背景。
可以证实,当物体的尺寸和背景相等时,这样选择阈值可以使误分概率达到最小。
在大多数情况下,由于图像的直方图在波谷四周的像素很稀疏,因此这种方法对图像的分割影响不大。
这一方法可以推广到具