详细的图像分割之边缘检测实验报告.docx
《详细的图像分割之边缘检测实验报告.docx》由会员分享,可在线阅读,更多相关《详细的图像分割之边缘检测实验报告.docx(69页珍藏版)》请在冰豆网上搜索。
详细的图像分割之边缘检测实验报告
边缘检测实验报告
一、实验目的
通过课堂的学习,已经对图像分割的相关理论知识已经有了全面的了解,知道了许多图像分割的算法及算子,了解到不同的算子算法有着不同的优缺点,为了更好更直观地对图像分割进行深入理解,达到理论联系实际的目的,特制定如下的实验。
二、实验原理:
图像处理有两大类目的:
1.改善像质(增强、恢复);2.图像分析:
对图像内容作出描述;其一般的图像处理过程如下:
图像分割的算法有:
(1)阈值分割原理:
(2)边缘检测:
梯度对应一阶导数,对于一个连续图像函数f(x,y):
梯度矢量定义:
梯度的幅度:
梯度的方向:
a)Roberts算子
b)Sobel算子
c)Prewitt算子
d)Kirsch算子
由K0~K7八个方向模板组成,将K0~K7的模板算法分别与图像中的3×3区域乘,选最大一个值,作为中央像素的边缘强度
(3)区域分割
1区域生长法
算法描述
先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素有相似性质的像素合并到种子像素所在的区域中。
将这些新像素当作新的种子像素继续进行上面的过程,直到再没有满足条件的像素可被包括进来。
2分裂合并法
实际中常先把图像分成任意大小且不重叠的区域,然后再合并或分裂这些区域以满足分割的要求,即分裂合并法.一致性测度可以选择基于灰度统计特征(如同质区域中的方差),假设阈值为T,则算法步骤为:
①对于任一Ri,如果,则将其分裂成互不重叠的四等分;
②对相邻区域Ri和Rj,如果,则将二者合并;
③如果进一步的分裂或合并都不可能了,则终止算法。
(4)Hough变换
Hough变换是一种检测、定位直线和解析曲线的有效方法。
它是把二值图变换到Hough参数空间,在参数空间用极值点的检测来完成目标的检测。
下面以直线检测为例,说明Hough变换的原理。
三、实验过程:
1、打开VC++6.0,利用AppWizard向导新建基于多文档的工程文件”demo”,其他默认设置即可。
2、新建如下的菜单资源:
图像分割
Roberts算子
ID_Robert
Sobel算子
ID_Sobel
Prewitt算子
ID_Prewitt
Laplacian算子
ID_Laplacian
Gauss-Laplacian算子
ID_Gauss_laplacian
Krisch算子
ID_Krisch
3、在demoDoc.h中添加如下代码:
#include"ImgCenterDib.h"
public:
ImgCenterDib*GetPDib()
{
return&m_dib;
}
private:
ImgCenterDibm_dib;
4、在demoView.cpp中添加代码如下:
#include"MainFrm.h"
#include"Segment.h"
5、新建图像处理的图像分割类Segment.h和ImgCenterDib.h,代码如下:
//图像分割类的定义:
#ifndef_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:
//不带参数的构造函数
ImgSegment();
//带参数的构造函数
ImgSegment(CSizesize,intnBitCount,LPRGBQUADlpColorTable,
unsignedchar*pImgData);
//析构函数
~ImgSegment();
//以像素为单位返回输出图像的尺寸
CSizeGetDimensions();
//Roberts算子
voidRoberts();
//Sobel算子
voidSobel();
//Prewitt算子
voidPrewitt();
//Laplacian算子
voidLaplacian();
//Krisch算子
voidKrisch();
//Gauss-Laplacian算子
voidGaussLaplacian();
};
#endif//_INSIDE_VISUAL_CPP_IMGSEGMENT
//ImgCenterDib类的定义:
ImgCenterDib.h
#ifndef_INSIDE_VISUAL_CPP_IMGCENTERDIB
#define_INSIDE_VISUAL_CPP_IMGCENTERDIB
//ImgCenterDib类
classImgCenterDib
{
public:
//图像数据指针
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:
//不带参数的构造函数
ImgCenterDib();
//带参数的构造函数
ImgCenterDib(CSizesize,intnBitCount,LPRGBQUADlpColorTable,
unsignedchar*pImgData);
//析构函数
~ImgCenterDib();
//获取DIB的尺寸(宽高)
CSizeGetDimensions();
//DIB读函数
BOOLRead(LPCTSTRlpszPathName);
//DIB写函数
BOOLWrite(LPCTSTRlpszPathName);
//显示DIB
BOOLDraw(CDC*pDC,CPointorigin,CSizesize);
//用新的数据替换DIB
voidReplaceDib(CSizesize,intnBitCount,LPRGBQUADlpColorTable,
unsignedchar*pImgData);
//计算颜色表的长度
intComputeColorTabalLength(intnBitCount);
private:
//创建逻辑调色板
voidMakePalette();
//清理空间
voidEmpty();
};
#endif//_INSIDE_VISUAL_CPP_IMGCENTERDIB
6、类Segment.cpp和ImgCenterDib.cpp的实现代码:
//图像分割类的实现Segment.cpp:
#include"stdafx.h"
#include"Segment.h"
#include"math.h"
/***********************************************************************
*函数名称:
*ImgSegment()
*
*说明:
无参数的构造函数,对成员变量进行初始化
***********************************************************************/
ImgSegment:
:
ImgSegment()
{
m_pImgDataOut=NULL;//输出图像位图数据指针为空
m_lpColorTableOut=NULL;//输出图像颜色表指针为空
m_nColorTableLengthOut=0;//输出图像颜色表长度为0
m_nBitCountOut=0;//输出图像每像素位数为0
m_imgWidthOut=0;//输出图像的宽为0
m_imgHeightOut=0;//输出图像的高为0
}
/***********************************************************************
*函数名称:
*ImgSegment()
*
*函数参数:
*CSizesize-图像大小(宽、高)
*intnBitCount-每像素所占位数
*LPRGBQUADlpColorTable-颜色表指针
*unsignedchar*pImgData-位图数据指针
*
*返回值:
*无
*
*说明:
本函数为带参数的构造函数,给定位图的大小、每像素位数、颜色表
*及位图数据,调用ImgCenterDib()对基类成员初始化,并初始化派生类的
*数据成员
***********************************************************************/
ImgSegment:
:
ImgSegment(CSizesize,intnBitCount,LPRGBQUADlpColorTable,unsignedchar*pImgData):
ImgCenterDib(size,nBitCount,lpColorTable,pImgData)
{
m_pImgDataOut=NULL;//输出图像位图数据指针为空
m_lpColorTableOut=NULL;//输出图像颜色表指针为空
m_nColorTableLengthOut=0;//输出图像颜色表长度为0
m_nBitCountOut=0;//输出图像每像素位数为0
m_imgWidthOut=0;//输出图像的宽为0
m_imgHeightOut=0;//输出图像的高为0
}
/***********************************************************************
*函数名称:
*~ImgSegment()
*
*说明:
析构函数,释放资源
***********************************************************************/
ImgSegment:
:
~ImgSegment()
{
//释放输出图像位图数据缓冲区
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
//释放输出图像颜色表
if(m_lpColorTableOut!
=NULL){
delete[]m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
}
/***********************************************************************
*函数名称:
*GetDimensions()
*
*函数参数:
*无
*
*返回值:
*图像的尺寸,用CSize类型表达
*
*说明:
返回输出图像的宽和高
***********************************************************************/
CSizeImgSegment:
:
GetDimensions()
{
if(m_pImgDataOut==NULL)returnCSize(0,0);
returnCSize(m_imgWidthOut,m_imgHeightOut);
}
/***********************************************************************
*函数名称:
*Roberts()
*
*函数参数:
*无
*
*返回值:
*无
*
*说明:
Roberts边缘检测,函数将图像看作若干通道数据的合成,在不同通道上
*完成了边缘检测,因此可同时适用于灰度和彩色图像
***********************************************************************/
voidImgSegment:
:
Roberts()
{
//释放m_pImgDataOut指向的图像数据空间
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
//释放颜色表空间
if(m_lpColorTableOut!
=NULL){
delete[]m_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);
}
//输出图像的宽高,与输入图像相等
m_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=1;ifor(j=1;jfor(k=0;k//x方向梯度
x=*(m_pImgData+i*lineByte+j*pixelByte+k)
-*(m_pImgData+(i+1)*lineByte+j*pixelByte+k);
//y方向梯度
y=*(m_pImgData+i*lineByte+j*pixelByte+k)
-*(m_pImgData+i*lineByte+(j+1)*pixelByte+k);
t=sqrt(x*x+y*y)+0.5;
if(t>255)
t=255;
*(m_pImgDataOut+i*lineByte+j*pixelByte+k)=t;
}
}
}
}
/***********************************************************************
*函数名称:
*Sobel()
*
*函数参数:
*无
*
*返回值:
*无
*
*说明:
Sobel边缘检测,函数将图像看作若干通道数据的合成,在不同通道上
*完成了边缘检测,因此可同时适用于灰度和彩色图像
***********************************************************************/
voidImgSegment:
:
Sobel()
{
//释放m_pImgDataOut指向的图像数据空间
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
//释放颜色表空间
if(m_lpColorTableOut!
=NULL){
delete[]m_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);
}
//输出图像的宽高,与输入图像相等
m_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;
//Sobel算子
for(i=1;ifor(j=1;jfor(k=0;k//x方向梯度
x=*(m_pImgData+(i-1)*lineByte+(j+1)*pixelByte+k)
+2**(m_pImgData+i*lineByte+(j+1)*pixelByte+k)
+*(m_pImgData+(i+1)*lineByte+(j+1)*pixelByte+k)
-*(m_pImgData+(i-1)*lineByte+(j-1)*pixelByte+k)
-2**(m_pImgData+i*lineByte+(j-1)*pixelByte+k)
-*(m_pImgData+(i+1)*lineByte+(j-1)*pixelByte+k);
//y方向梯度
y=*(m_pImgData+(i-1)*lineByte+(j-1)*pixelByte+k)
+2**(m_pImgData+(i-1)*lineByte+j*pixelByte+k)
+*(m_pImgData+(i-1)*lineByte+(j+1)*pixelByte+k)
-*(m_pImgData+(i+1)*lineByte+(j-1)*pixelByte+k)
-2**(m_pImgData+(i+1)*lineByte+j*pixelByte+k)
-*(m_pImgData+(i+1)*lineByte+(j+1)*pixelByte+k);
t=sqrt(x*x+y*y)+0.5;
if(t>255)
t=255;
*(m_pImgDataOut+i*lineByte+j*pixelByte+k)=t;
}
}
}
}
/***********************************************************************
*函数名称:
*Prewitt()
*
*函数参数:
*无
*
*返回值:
*无
*
*说明:
Prewitt边缘检测,函数将图像看作若干通道数据的合成,在不同通道上
*完成了边缘检测,因此可同时适用于灰度和彩色图像
***********************************************************************/
voidImgSegment:
:
Prewitt()
{
//释放m_pImgDataOut指向的图像数据空间
if(m_pImgDataOut!
=NULL){
delete[]m_pImgDataOut;
m_pImgDataOut=NULL;
}
//释放颜色表空间
if(m_lpColorTableOut!
=NULL){
delete[]m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
//输出图像与输入图像为同