详细的图像分割之边缘检测实验报告.docx
《详细的图像分割之边缘检测实验报告.docx》由会员分享,可在线阅读,更多相关《详细的图像分割之边缘检测实验报告.docx(64页珍藏版)》请在冰豆网上搜索。
详细的图像分割之边缘检测实验报告
边缘检测实验报告
一、实验目的
通过课堂的学习,已经对图像分割的相关理论知识已经有了全面的了解,知逍了许多图像分割的算法及算子,了解到不同的算子算法有着不同的优缺点,为了更好更直观地对图像分割进行深入理解,达到理论联系实际的目的,特制左如下的实验。
二、实验原理:
图像处理有两大类目的:
1.改善像质(增强、恢复);2.图像分析:
对图像内容作岀描述:
英一般的图像处理过程如下:
图像分割的算法有:
(1)阈值分割原理:
Illhlll
(2)边缘检测:
梯度对应一阶导数,对于一个连续图像函数f(x,y):
梯度矢量定义:
梯度的幅度:
|Vf(x,y)\=叫冈匕,刃)=(G:
+G泸
梯度的方向:
y)=arctan(Gv/Gr)
a)
」+i)f+L/W+1J)-/Cj+i)]2F
Roberts算子
gCj)=t/'Cj)-/G+i,
1
0
0
-1
0
1
-1
0
Roberts算子
b)Sobel算子
-1
0
1
-2
0
2
-1
0
1
1
2
1
0
0
0
-1
-2
-1
c)Prewitt算子
由八个方向模板组成,将K0~K7的模板算法分别与图像中的3X3区域乘,选最大一个值,作为中央像素的边缘强度
g(x,y)=max{g0,gr-\gT}
gi(x,y)=工工K,伙,/)/(x+R,y+/)—1
(3)区域分割
1区域生长法
算法描述
先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周国邻域中与种子像素有相似性质的像素合并到种子像素所在的区域中。
将这些新像素当作新的种子像素继续进行上而的过程,直到再没有满足条件的像素可被包括进来。
2分裂合并法
实际中常先耙图像分成任意大小且不重叠的区域,然后再合并或分裂这些区域以满足分割的要求,即分裂合并法•一致性测度可以选择基于灰度统计特征(如同质区域中的方差),假设阈值为7,则算法步骤为:
1对于任一卮,谢;风)>T,则将其分裂成互不重叠的四等分;
2对相邻区域卮和心物闻U心),则将二者合并:
3如果进一步的分裂或合并都不可能了,则终止算法。
(4)Hough变换
Hough变换是一种检测、定位直线和解析曲线的有效方法。
它是把二值图变换到Hough参数空间,在参数空间用极值点的检测来完成目标的检测。
下而以直线检测为例,说明
Hough变换的原理。
°¥
三、实验过程:
lx打开VC+十6.0,利用AppWizard向导新建基于多文档的工程文件”demo",其他默认设置即可。
2、新建如下的菜单资源:
图像分割
Roberts算子
IDRobert
Sobel算子
ID.Sobel
Prewitt算子
IDPrewitt
Laplacian算子
IDLaplacian
Gauss-Laplacian算子
ID_Gauss_laplacian
Krisch算子
IDKrisch
习Menu
gjIDR_DEMOIYPt|直IDR.MAINFRAMEIStringTable
□固诸讹ID.Robert三|H
掺齒為9冋羽1
■|||AIIglobalmembersjJ|(Nomembers-CreateNewClass...)J▼
——jd-il
丈幷他)褊窃⑥育看边旨口血帮9hQ
)-匪履:
H■割:
••••
de>o一KicrosoftVisualC++一[deso.rc-IDR_DE10TTPE(Kenu)]
詔?
ilcEditYiowIxisortPrcj^ctBuild7oolzWind&vHelp
EoboL算子
Tr&vittj$子
L^placi子
GeulL久pLaei子
Erxsh算子
圧OAcceleratorE□Dialog凹LJIcon冋.
EQToolbar帶口畑血“
3x在demoDoc.h中添加如下代码:
ttinclude"IngCenterDib.h"classCDomoDoc:
publicCDocunent
Sinclude,?
ImgCenterDib・h"
classCDemoDoc:
publicCDocunent
<
protected:
//createfromserializationonlyCDemoDoc();
DECLARE_DVNCREATE(CDemoDoc)
jjAttribut:
。
%public:
ImgCenterDib*GetPDib()
return;
}"private:
ImgCenterDibmdib;
public:
ImgCenterDib*GetPDib()
}
private:
ImgCenterDibm_dib;
4、在demoView,cpp中添加代码如下:
t
include"MainFrin.h'1include"'Segment・tT'
^include"MainFrm.h"
^include''Segment・h〃
5、新建图像处理的图像分割类Segment,h和ImgCenterDib.h»代码如下:
//图像分割类的定义:
Sifndef_INSIDE_VISUAL_CPP.IMGSEGMENT
^define_INSIDE_VISUAL_CPP.IMGSEGMENT
^include"ImgCenterDib・h〃
classImgSegment:
publicImgCenterDib
{
public:
//输岀图像每像素位数
intm_nBitCountOut;
〃输出图像位图数据指针
unsignedchar*m_pImgDataOut;
〃输出图像颜色表
LPRGBQUADm_lpColorTableOut;
private:
//输出图像的宽
intm_imgWidthOut;
//输岀图像的高
intm_imgHeightOut;
//输出图像颜色表长度
intm_nColorTableLengthOut;
public:
//不带参数的构造函数
ImgSegment0;
〃带参数的构造函数
ImgSegment(CSizesize,intnBitCount,LPRGBQUADIpColorTable,unsignedchar*pImgData);
//析构函数
ImgSegment0;
//以像素为单位返回输出图像的尺寸
CSizeGetDimensions0;
//Roberts算子
voidRoberts();
//Sobel算子
voidSobel();
//Prewitt算子
voidPrewitt0;
//Laplacian算子
voidLaplacian();
//Krisch算子
voidKrischO;
//Gauss-Lap1acian算子
voidGaussLaplacianO;
};
Sendif//_INSIDE_VISUAL_CPP_IMGSEGMENT
//ImgCenterDib类的上义:
ImgCenterD让.h#ifndef_INSIDE_VISUAL_CPP.IMGCENTERDIB^define_INSIDE_VISUAL_CPP.IMGCENTERDIB
//ImgCenterDib类classImgCenterDibpublic:
//图像数据指针
unsignedchar*m_pImgData;
〃图像颜色表指针
LPRGBQUADm.lpColorTable;
〃每像素占的位数
intm_nBitCount;
private:
//指向DIB的指针(包含BITMAPFILEHEADER,BITMAPINFOHEADER和颜色表)LPBYTEm.lpDib;
〃逻辑调色板句柄
HPALETTEm.hPalette;
〃颜色表长度(多少个表项)
intm_nColorTableLength;
protected:
〃图像的宽,像素为单位intm_imgWidth;
〃图像的高,像素为单位
intm_imgHeight;
〃图像信息头指针
LPBITMAPINFOHEADERm.lpBmpInfoHead;
public:
//不带参数的构造函数ImgCenterDibO;
〃带参数的构造函数
ImgCenterDib(CSizesize,intnBitCount,LPRGBQUADIpColorTable,unsignedchar*pImgData);
〃析构函数
^ImgCenterDibO;
//获取DIB的尺寸(宽高)
CSizeGetDimensions0;
//DIB读函数
BOOLRead(LPCTSTRIpszPathName);
//DIB写函数
BOOLWrite(LPCTSTRIpszPathName);
//显示DIB
BOOLDraw(CDC*pDC,CPointorigin,CSizesize):
〃用新的数据替换DIB
voidReplaceDib(CSizesize,intnBitCount,LPRGBQUADIpColorTable,unsignedchar*pImgData);
〃计算颜色表的长度
intComputeColorTabalLength(intnBitCount);
private:
〃创建逻辑调色板
voidMakePaletteO;
〃淸理空间
voidEmpty0;
};
#endif//_INSIDE_VISUAL_CPP.IMGCENTERDIB
6>类Segment,cpp和ImgCenterDib.cpp的实现代码:
〃图像分割类的实现Segment,cpp:
#include"stdafx・h〃
^include''Segment・h"
^include"math・h〃
/***********************************************************************
*函数名称:
*ImgSegment0
*
*说明:
无参数的构造函数,对成员变量进行初始化
***********************************************************************/
ImgSegment:
:
ImgSegment0
m.pImgDataOut=NULL;//输岀图像位图数据指针为空m_lpColorTableOut=NULL;//输出图像颜色表指针为空m_nColorTableLengthOut=0;//输出图像颜色表长度为0m_nBitCount0ut=0;//输出图像每像素位数为0m_imgWidthOut二0;//输岀图像的宽为0m_imgHeightOut=0;//输出图像的髙为0
/***********************************************************************
*函数名称:
*ImgSegment0*
*函数参数:
*CSizesize-图像大小(宽.髙)
*intnBitCount-每像素所占位数
*LPRGBQUADIpColorTable-颜色表指针
*unsignedchar*pImgData-位图数据指针
*
*返回值:
*无京说明:
本函数为带参数的构适函数,给泄位图的大小、每像素位数、颜色表
*及位图数据,涮用ImgCenterDib0对基类成员初始化,并初始化派生类的
*数据成员
***********************************************************************/
ImgSegment:
:
ImgSegment(CSizesize,intnBitCount,LPRGBQUADIpColorTable,unsignedchar*plmgData):
ImgCenterDib(size,nBitCount,IpColorTable,plmgData)
{
m_pImgDataOut=NULL;//输岀图像位图数据指针为空
m_lpColorTableOut=NULL;//输出图像颜色表指针为空
m_nColorTableLengthOut=0;//输出图像颜色表长度为0
m_nBitCount0ut=0;//输岀图像每像素位数为0
m_imgWidth0ut=0;//输出图像的宽为0
m_imgHeightOut=0;//输出图像的髙为0}
/************************************************************************函数名称:
*ImgSegment0
和兑明:
析构函数•释放资源***********************************************************************/
ImgSegment:
:
"ImgSegment0
〃释放输出图像位图数据缓冲区if(m_pImgDataOut!
二NULL){delete[]m_pImgDataOut;
m_pImgDataOut=NULL;}
//释放输岀图像颜色表
if(m.lpColorTableOut!
=NULL){delete[Jm_lpColorTableOut;m_lpColorTableOut=NULL;
}
}/************************************************************************函数名称:
*GetDimensions0
倉函数参数:
*无
客返回值:
*图像的尺寸,用CSize类型表达*说明:
返回输出图像的宽和髙
***********************************************************************/
CSizeImgSegment:
:
GetDimensions0
if(m_pImgDataOut=NULL)returnCSize(0,0);returnCSize(m_imgWidthOut,m_imgHeightOut):
/************************************************************************函数划称:
*Roberts0
*
*函数参数:
*无*返回值:
*无
*
*说明:
Roberts边缘检测,函数将图像看作若干通道数据的合成,在不同通道上
*完成了边缘检测,因此可同时适用于灰度和彩色图像
***********************************************************************/voidImgSegment:
:
Roberts0
{
//释放m_pImgDataOut指向的图像数据空间
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
〃释放颜色表空间
if(m.lpColorTableOut!
=NULL){
delete[Jm_lpColorTableOut;m_lpColorTableOut=NULL;
}
〃输出图像与输入图像为同一类型
m_nBitCountOut=m_nBitCount;
//输出图像颜色表长度m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
〃输岀图像颜色表,与输入图像相同
if(m_nColorTableLengthOut!
=0){m_lpColorTableOut=newRGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLengthOut);
}
//输出图像的宽高,与输入图像相等imgWidthOut=m_imgWidth;
m_imgHeightOut=m_imgHeight;
//每行像素所占字节数,输岀图像与输入图像相同intlineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;
//申请输岀图像缓冲区
m_pImgDataOut=newunsignedchar^lineByte*m_imgHeight];
〃循环变量,图像的坐标
inti,j;
〃每像素占字节数,输岀图像与输入图像相同
intpixelByte=m_nBitCount/8;
〃循环变量,遍历像素的每个通道,比如彩色图像三个分量
intk;
〃中间变量
intx,y,t;
//Roberts算子
for(i=l;ifor(j=l;jfor(k=0:
kk卄){
//x方向梯度
x二*(m_pImgDat3+i*lineByte+j*pixelByte+k)
-*(m_pImgData+(i+l)*lineByte+j*pixelByte+k);
//y方向梯度
y=*(m-pImgData+i*lineByte+j*pixelByte+k)
-*(m_pImgData+i*lineByte+(j+l)*pixelByte+k);
t=sqrt(x*x+y*y〉+0.5;if(t>255)
t二255;
*(m_pImgDataOut+i*lineByte+j*pixelByte+k)=t;
}
}
}
}
/************************************************************************函数名称:
*Sobel0京函数参数:
*无
*
*返回值:
*无
*
*说明:
Sobel边缘检测,函数将图像看作若干通逍数据的合成,在不同通道上
*完成了边缘检测,因此可同时适用于灰度和彩色图像
***********************************************************************/
voidImgSegment:
:
Sobel0
{
//释放m_pImgDataOut指向的图像数据空间
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
〃释放颜色表空间
if(m.lpColorTableOut!
=NULL){
delete[Jm_lpColorTableOut;
m_lpColorTableOut=NULL;
}
〃输出图像勺输入图像为同一类型
m_nBitCountOut=m_nBitCount;
//输出图像颜色表长度m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
〃输出图像颜色表,与输入图像相同
if(m_nColorTableLengthOut!
=0){
m_lpColorTableOut=newRGBQUADEm_nCo1orTab1eLengthOutJ;
memcpy(m_lpColorTableOut,m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength
Out);
}
〃输出图像的宽高,与输入图像相等
imgWidthOut=m_imgWidth;
m^imgHeightOut^m^imgHeight;
〃每行像素所占字节数,输出图像与输入图像相同
intlineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;
//申请输出图像缓冲区
m_pImgDataOut=newunsignedcharllineByte*m_imgHeight];
//循环变量•图像的坐标
inti,j;
〃每像素占字节数,输出图像与输入图像相同
intpixelByte=m_nBitCount/8;
//循环变量,遍历像素的每个通道,比如彩色图像三个分量
intk;
〃中间变量
intx,y,t;
//Sobel算子
for(i=l;ifor(j=l;jfor(k=0:
kk++){
//x方向梯度
x=*(m_pImgData+(i-1)*1in^Byte+(j+1)*pixelByte+k)
+2**(m_pImgData+i*linEByte+(j+l)*pixelByte+k)
+*(m_pImgData+(i+1)*linEByte+(j+1)*pixelByte+k)
-*(m_pImgData+(iT)*1ineByte+(j-1)*pixelByte+k)
-2**(m_pImgData+i*lineByte+(jT)*pixelByte+k)
-*(m_pImgData+(i+l)*1ineByte+(jT)*pixelByte+k);
//y方向梯度
y=*(m_pImgDdta+(i-1)*1ineByte+(j-1)*pixelByte+k)
+2**(m_pImgData+(iT)*lineByte+j*pixelByte+k)
+*(m_pImgDat3+(i-1)*1ineByte+(j+1)*pixelByte+k)
-*(m_pImgData+(i+1)*lineByte+(j-1)*pixelByte+k)
-2**(m_pImgData+(i+l)*lineB57,te+j*pixelByte+k)
-*(m_pImgData+(i+l)*1in^Byte+(j+l)*pixelByte+k);
t=sqrt(x*x+y*y)+0.5;
辻(t>255)