




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
边缘检测实验报告一、实验目的通过课堂的学习,已经对图像分割的相关理论知识已经有了全面的了解,知道了许多图像分割的算法及算子,了解到不同的算子算法有着不同的优缺点,为了更好更直观地对图像分割进行深入理解,达到理论联系实际的目的,特制定如下的实验。二、实验原理:图像处理有两大类目的:1.改善像质(增强、恢复);2.图像分析:对图像内容作出描述;其一般的图像处理过程如下:图像输入图像输入光电变换数字化图像增强图像恢复图像编码预处理阈值分割边缘检测……图像分割图像识别图像分析理解描述解释特征提取图像分割的算法有:(1)阈值分割原理:(2)边缘检测:梯度对应一阶导数,对于一个连续图像函数f(x,y):梯度矢量定义:梯度的幅度:梯度的方向:a)Roberts算子1100-101-10Roberts算子b)Sobel算子-10-101-202-101121000-1-2-1c)Prewitt算子-10-101-101-101111000-1-1-1d)Kirsch算子由K0~K7八个方向模板组成,将K0~K7的模板算法分别与图像中的3×3区域乘,选最大一个值,作为中央像素的边缘强度(3)区域分割1区域生长法算法描述先对每个需要分割的区域找一个种子像素作为生长的起点,然后将种子像素周围邻域中与种子像素有相似性质的像素合并到种子像素所在的区域中。将这些新像素当作新的种子像素继续进行上面的过程,直到再没有满足条件的像素可被包括进来。2分裂合并法实际中常先把图像分成任意大小且不重叠的区域,然后再合并或分裂这些区域以满足分割的要求,即分裂合并法.一致性测度可以选择基于灰度统计特征(如同质区域中的方差),假设阈值为T,则算法步骤为:①对于任一Ri,如果,则将其分裂成互不重叠的四等分;②对相邻区域Ri和Rj,如果,则将二者合并;③如果进一步的分裂或合并都不可能了,则终止算法。(4)Hough变换Hough变换是一种检测、定位直线和解析曲线的有效方法。它是把二值图变换到Hough参数空间,在参数空间用极值点的检测来完成目标的检测。下面以直线检测为例,说明Hough变换的原理。(xi(xi,yi)(xj,yj)XoYy=p’x+q’PoQq=-pxj+yjq=-pxi+yiq’p’三、实验过程:1、打开VC++6.0,利用AppWizard向导新建基于多文档的工程文件”demo”,其他默认设置即可。2、新建如下的菜单资源:图像分割Roberts算子ID_RobertSobel算子ID_SobelPrewitt算子ID_PrewittLaplacian算子ID_LaplacianGauss-Laplacian算子ID_Gauss_laplacianKrisch算子ID_Krisch3、在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_IMGCENTERDIB6、类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;//输出图像颜色表长度为0m_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;//输出图像颜色表长度为0m_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;i<m_imgHeight-1;i++){ for(j=1;j<m_imgWidth-1;j++){ for(k=0;k<pixelByte;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;i<m_imgHeight-1;i++){ for(j=1;j<m_imgWidth-1;j++){ for(k=0;k<pixelByte;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; } //输出图像与输入图像为同一类型 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; //Prewitt算子 for(i=1;i<m_imgHeight-1;i++){ for(j=1;j<m_imgWidth-1;j++){ for(k=0;k<pixelByte;k++){ //x方向梯度 x=*(m_pImgData+(i-1)*lineByte+(j+1)*pixelByte+k) +*(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) -*(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) +*(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) -*(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; } } }}/************************************************************************函数名称:*Laplacian()**函数参数:*无**返回值:*无**说明:Laplacian边缘检测,函数将图像看作若干通道数据的合成,在不同通道上*完成了边缘检测,因此可同时适用于灰度和彩色图像***********************************************************************/voidImgSegment::Laplacian(){ //释放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; //中间变量 intt; //Laplacian算子 for(i=1;i<m_imgHeight-1;i++){ for(j=1;j<m_imgWidth-1;j++){ for(k=0;k<pixelByte;k++){ t=4**(m_pImgData+i*lineByte+j*pixelByte+k) -*(m_pImgData+(i-1)*lineByte+j*pixelByte+k) -*(m_pImgData+(i+1)*lineByte+j*pixelByte+k) -*(m_pImgData+i*lineByte+(j-1)*pixelByte+k) -*(m_pImgData+i*lineByte+(j+1)*pixelByte+k); t=abs(t)+0.5; if(t>255) t=255; *(m_pImgDataOut+i*lineByte+j*pixelByte+k)=t; } } }}/************************************************************************函数名称:*Krisch()**函数参数:*无**返回值:*无**说明:Krisch边缘检测,同时适合于灰度和彩色图像***********************************************************************/voidImgSegment::Krisch(){ //释放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]; //输出图像缓冲区初始化为0 memset(m_pImgDataOut,0,lineByte*m_imgHeight); //循环变量,图像的坐标 inti,j; //每像素占字节数,输出图像与输入图像相同 intpixelByte=m_nBitCount/8; //循环变量,遍历像素的每个通道,比如彩色图像三个分量 intk; //两个指针变量 unsignedchar*p1,*p2; //申请临时缓冲区,存放中间结果 unsignedchar*buf=newunsignedchar[lineByte*m_imgHeight]; //模板数组 intmask[9]; //设置Kirsch模板1参数 mask[0]=5; mask[1]=5; mask[2]=5; mask[3]=-3; mask[4]=0; mask[5]=-3; mask[6]=-3; mask[7]=-3; mask[8]=-3; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板2参数 mask[0]=-3; mask[1]=5; mask[2]=5; mask[3]=-3; mask[4]=0; mask[5]=5; mask[6]=-3; mask[7]=-3; mask[8]=-3; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板3参数 mask[0]=-3; mask[1]=-3; mask[2]=5; mask[3]=-3; mask[4]=0; mask[5]=5; mask[6]=-3; mask[7]=-3; mask[8]=5; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板4参数 mask[0]=-3; mask[1]=-3; mask[2]=-3; mask[3]=-3; mask[4]=0; mask[5]=5; mask[6]=-3; mask[7]=5; mask[8]=5; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板5参数 mask[0]=-3; mask[1]=-3; mask[2]=-3; mask[3]=-3; mask[4]=0; mask[5]=-3; mask[6]=5; mask[7]=5; mask[8]=5; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板6参数 mask[0]=-3; mask[1]=-3; mask[2]=-3; mask[3]=5; mask[4]=0; mask[5]=-3; mask[6]=5; mask[7]=5; mask[8]=-3; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板7参数 mask[0]=5; mask[1]=-3; mask[2]=-3; mask[3]=5; mask[4]=0; mask[5]=-3; mask[6]=5; mask[7]=-3; mask[8]=-3; //求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ p1=m_pImgDataOut+i*lineByte+j*pixelByte+k; p2=buf+i*lineByte+j*pixelByte+k; if(*p1<*p2) *p1=*p2; } } } //设置Kirsch模板8参数 mask[0]=5; mask[1]=5; mask[2]=-3; mask[3]=5; mask[4]=0; mask[5]=-3; mask[6]=-3; mask[7]=-3; mask[8]=-3;//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中 for(i=0;i<m_imgHeight;i++){ for(j=0;j<m_imgWidth;j++){ for(k=0;k<pixelByte;k++){ if(*(m_pImgDataOut+i*lineByte+j*pixelByte+k)<*(buf+i*lineByte+j*pixelByte+k)) *(m_pImgDataOut+i*lineByte+j*pixelByte+k)=*(buf+i*lineByte+j*pixelByte+k); } } }}/************************************************************************函数名称:*GaussLaplacian()**函数参数:*无**返回值:*无**说明:Gauss-Laplacian边缘检测,同时适合于灰度和彩色图像***********************************************************************/voidImgSegment::GaussLaplacian(){ //定义Gauss-Laplacian模板 intmask[25]; mask[0]=-2; mask[1]=-4; mask[2]=-4; mask[3]=-4; mask[4]=-2; mask[5]=-4; mask[6]=0; mask[7]=8; mask[8]=0; mask[9]=-4; mask[10]=-4; mask[11]=8; mask[12]=24; mask[13]=8; mask[14]=-4; mask[15]=-4; mask[16]=0; mask[17]=8; mask[18]=0; mask[19]=-4; mask[20]=-2; mask[21]=-4; mask[22]=-4; mask[23]=-4; mask[24]=-2; //释放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];}//ImgCenterDib.cpp的实现代码#include"stdafx.h"#include"ImgCenterDib.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif/************************************************************************函数名称:*ImgCenterDib()**说明:无参数的构造函数,对成员变量进行初始化***********************************************************************/ImgCenterDib::ImgCenterDib(){ m_lpDib=NULL;//初始化m_lpDib为空。 m_lpColorTable=NULL;//颜色表指针为空 m_pImgData=NULL;//图像数据指针为空 m_lpBmpInfoHead=NULL;//图像信息头指针为空 m_hPalette=NULL;//调色板为空}/************************************************************************函数名称:*ImgCenterDib()**函数参数:*CSizesize-图像大小(宽、高)*intnBitCount-每像素比特数*LPRGBQUADlpColorTable-颜色表指针*unsignedchar*pImgData-位图数据指针**返回值:*无**说明:本函数为带参数的构造函数,给定位图的大小、每像素位数、颜色表*及位图数据生成一个ImgCenterDib类对象***********************************************************************/ImgCenterDib::ImgCenterDib(CSizesize,intnBitCount,LPRGBQUADlpColorTable, unsignedchar*pImgData){ //如果没有位图数据传入,我们认为是空的DIB,此时不分配DIB内存 if(pImgData==NULL){ m_lpDib=NULL; m_lpColorTable=NULL; m_pImgData=NULL;//图像数据 m_lpBmpInfoHead=NULL;//图像信息头 m_hPalette=NULL; } else{//如果有位图数据传入 //图像的宽、高、每像素位数等成员变量赋值 m_imgWidth=size.cx; m_imgHeight=size.cy; m_nBitCount=nBitCount; //根据每像素位数,计算颜色表长度 m_nColorTableLength=ComputeColorTabalLength(nBitCount); //每行像素所占字节数,必须扩展成4的倍数 intlineByte=(m_imgWidth*nBitCount/8+3)/4*4; //位图数据缓冲区的大小(图像大小) intimgBufSize=m_imgHeight*lineByte; //为m_lpDib一次性分配内存,生成DIB结构 m_lpDib=newBYTE[sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize]; //填写BITMAPINFOHEADER结构 m_lpBmpInfoHead=(LPBITMAPINFOHEADER)m_lpDib; m_lpBmpInfoHead->biSize=sizeof(BITMAPINFOHEADER); m_lpBmpInfoHead->biWidth=m_imgWidth; m_lpBmpInfoHead->biHeight=m_imgHeight; m_lpBmpInfoHead->biPlanes=1; m_lpBmpInfoHead->biBitCount=m_nBitCount; m_lpBmpInfoHead->biCompression=BI_RGB; m_lpBmpInfoHead->biSizeImage=0; m_lpBmpInfoHead->biXPelsPerMeter=0; m_lpBmpInfoHead->biYPelsPerMeter=0; m_lpBmpInfoHead->biClrUsed=m_nColorTableLength; m_lpBmpInfoHead->biClrImportant=m_nColorTableLength; //调色板句柄初始化为空,有颜色表时,MakePalette()函数要生成新的调色板 m_hPalette=NULL; //如果有颜色表,则将颜色表拷贝进DIB的颜色表位置 if(m_nColorTableLength!=0){ //m_lpColorTable指向DIB颜色表的起始位置 m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER)); //颜色表拷贝 memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength); //创建逻辑调色板 MakePalette(); } //m_pImgData指向DIB位图数据起始位置 m_pImgData=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength; //拷贝图像数据进DIB位图数据区 memcpy(m_pImgData,pImgData,imgBufSize); }}/************************************************************************函数名称:*~ImgCenterDib()**说明:析构函数,释放资源***********************************************************************/ImgCenterDib::~ImgCenterDib(){ //释放m_lpDib所指向的内存缓冲区 if(m_lpDib!=NULL) delete[]m_lpDib; //如果有调色板,释放调色板缓冲区 if(m_hPalette!=NULL) ::DeleteObject(m_hPalette); }/************************************************************************函数名称:*Draw()**函数参数:*CDC*pDC-设备环境指针*CPointorigin-显示矩形区域的左上角*CSizesize-显示矩形区域的尺寸**返回值:*0为失败,1为成功**说明:给定设备环境指针,以及需要显示的矩形区域在设备环境中的位置*将m_lpDib所指向的DIB显示出来***********************************************************************/BOOLImgCenterDib::Draw(CDC*pDC,CPointorigin,CSizesize){ //旧的调色板句柄 HPALETTEhOldPal=NULL; //如果DIB为空,则返回0 if(m_lpDib==NULL)returnFALSE; //如果DIB有调色板 if(m_hPalette!=NULL){ //将调色板选进设备环境中 hOldPal=::SelectPalette(pDC->GetSafeHdc(),m_hPalette,TRUE); //实现调色板 pDC->RealizePalette(); } //设置位图伸缩模式 pDC->SetStretchBltMode(COLORONCOLOR); //将DIB在pDC所指向的设备上进行显示 ::StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy, 0,0,m_lpBmpInfoHead->biWidth,m_lpBmpInfoHead->biHeight,m_pImgData, (LPBITMAPINFO)m_lpBmpInfoHead,DIB_RGB_COLORS,SRCCOPY); //恢复旧的调色板 if(hOldPal!=NULL) ::SelectPalette(pDC->GetSafeHdc(),hOldPal,TRUE); //函数返回 returnTRUE;}/************************************************************************函数名称:*Read()**函数参数:*LPCTSTRlpszPathName-图像名字及路径**返回值:*0为失败,1为成功**说明:给定一个图像文件名及其路径,读取图像数据进内存生成DIB,*并存放在m_lpDib所指向的缓冲区***********************************************************************/BOOLImgCenterDib::Read(LPCTSTRlpszPathName){ //读模式打开图像文件 CFilefile; if(!file.Open(lpszPathName,CFile::modeRead|CFile::shareDenyWrite)) returnFALSE; BITMAPFILEHEADERbmfh; try{ //清理空间 Empty(); //读取BITMAPFILEHEADER结构到变量bmfh中 intnCount=file.Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER)); //异常判断 if(nCount!=sizeof(BITMAPFILEHEADER)){ thrownewCException; } if(bmfh.bfType!=0x4d42){ thrownewCException; } //为m_lpDib分配空间,读取DIB进内存 if(m_lpDib!=NULL) delete[]m_lpDib; m_lpDib=newBYTE[file.GetLength()-sizeof(BITMAPFILEHEADER)]; file.Read(m_lpDib,file.GetLength()-sizeof(BITMAPFILEHEADER)); //m_lpBmpInfoHead位置为m_lpDib起始位置 m_lpBmpInfoHead=(LPBITMAPINFOHEADER)m_lpDib; //为成员变量赋值 m_imgWidth=m_lpBmpInfoHead->biWidth; m_imgHeight=m_lpBmpInfoHead->biHeight; m_nBitCount=m_lpBmpInfoHead->biBitCount; //计算颜色表长度 m_nColorTableLength= ComputeColorTabalLength(m_lpBmpInfoHead->biBitCount); //如果有颜色表,则创建逻辑调色板 m_hPalette=NULL; if(m_nColorTableLength!=0){ m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER)); MakePalette(); } //m_pImgData指向DIB的位图数据起始位置 m_pImgData=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength; } catch(CException*pe){ AfxMessageBox("Readerror"); pe->Delete(); returnFALSE; } //函数返回 returnTRUE;}/************************************************************************函数名称:*Write()**函数参数:*LPCTSTRlpszPathName-指定图像名字及路径**返回值:*0为失败,1为成功**说明:给定一个图像文件名及其路径,将m_lpDib指向的DIB存盘***********************************************************************/BOOLImgCenterDib::Write(LPCTSTRlpszPathName){ //写模式打开文件 CFilefile; if(!file.Open(lpszPathName,CFile::modeCreate|CFile::modeReadWrite |CFile::shareExclusive)) returnFALSE; //填写文件头结构 BITMAPFILEHEADERbmfh; bmfh.bfType=0x4d42;//'BM' bmfh.bfSize=0; bmfh.bfReserved1=bmfh.bfReserved2=0; bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength; try{ //文件头结构写进文件 file.Write((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER)); //文件信息头结构写进文件 file.Write(m_lpBmpInfoHead,sizeof(BITMAPINFOHEADER)); //如果有颜色表的话,颜色表写进文件 if(m_nColorTableLength!=0) file.Write(m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength); //位图数据写进文件 intimgBufSize=(m_imgWidth*m_nBitCount/8+3)/4*4*m_imgHeight; file.Write(m_pImgData,imgBufSize); } catch(CException*pe){ pe->Delete(); AfxMessageBox("writeerror"); returnFALSE; } //函数返回 returnTRUE;}/************************************************************************函数名称:*ReplaceDib()**函数参数:*CSizesize-要替换的新图像尺寸*intnBitCount-每像素的位数*LPRGBQUADlpColorTable-颜色表指针*unsignedchar*pImgData-位图数据的指针*返回值:*无**说明:图像的尺寸,每像素位数、颜色表、及位图数据,*替换m_lpDib所指向的现有的DIB***********************************************************************/voidImgCenterDib::ReplaceDib(CSizesize,intnBitCount, LPRGBQUADlpColorTable,unsignedchar*pImgData){ //释放原DIB所占空间 Empty(); //成员变量赋值 m_imgWidth=size.cx; m_imgHeight=size.cy; m_nBitCount=nBitCount; //计算颜色表的长度 m_nColorTableLength=ComputeColorTabalLength(nBitCount); //每行像素所占字节数,扩展成4的倍数 intlineByte=(m_imgWidth*nBitCount/8+3)/4*4; //位图数据的大小 intimgBufSize=m_imgHeight*lineByte; //为m_lpDib重新分配空间,以存放新的DIB m_lpDib=newBYTE[sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize]; //填写位图信息头BITMAPINFOHEADER结构 m_lpBmpInfoHead=(LPBITMAPINFOHEADER)m_lpDib; m_lpBmpInfoHead->biSize=sizeof(BITMAPINFOHEADER); m_lpBmpInfoHead->biWidth=m_imgWidth; m_lpBmpInfoHead->biHeight=m_imgHeight; m_lpBmpInfoHead->biPlanes=1; m_lpBmpInfoHead->biBitCount=m_nBitCount; m_lpBmpInfoHead->biCompression=BI_RGB; m_lpBmpInfoHead->biSizeImage=0; m_lpBmpInfoHead->biXPelsPerMeter=0; m_lpBmpInfoHead->biYPelsPerMeter=0; m_lpBmpInfoHead->biClrUsed=m_nColorTableLength; m_lpBmpInfoHead->biClrImportant=m_nColorTableLength; //调色板置空 m_hPalette=NULL; //如果有颜色表,则将颜色表拷贝至新生成的DIB,并创建逻辑调色板 if(m_nColorTableLength!=0){ m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER)); memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength); MakePalette(); } //m_pImgData指向DIB的位图数据起始位置 m_pImgData=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*m_nColorTableLength; //将新位图数据拷贝至新的DIB中 memcpy(m_pImgData,pImgData,imgBufSize);}/************************************************************************函数名称:*ComputeColorTabalLength()**函数参数:*intnBitCount-DIB每像素位数**返回值:*颜色表的长度**说明:给定每像素的比特
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 税务软件操作讲解
- 商丘学院《综合日语(1)》2023-2024学年第一学期期末试卷
- 哈尔滨工业大学《职业发展与择业指导》2023-2024学年第一学期期末试卷
- 陕西省西北农林科技大学附属中学2025年高三下学期第二次月考(期中)数学试题含解析
- 2025高考语文名校作文题立意与例文参考11篇
- 甘肃钢铁职业技术学院《广告创意与表现》2023-2024学年第二学期期末试卷
- 江西师范高等专科学校《基础泰语(二)》2023-2024学年第一学期期末试卷
- 新疆建设职业技术学院《水泥基复合材料》2023-2024学年第二学期期末试卷
- 2025年上海市嘉定区外国语学校高三5月一诊模拟英语试题含解析
- 河池学院《科技论文写作能动》2023-2024学年第二学期期末试卷
- HPV分型检测介绍课件
- 超全自考英语二词汇表-含音标4500-个单词
- 外卖骑手交通安全课件
- 浙江省工贸企业电气隐患排查技术服务规范
- 安全生产法律法规注册安全工程师考试(初级)试题与参考答案(2024年)一
- 《BIS与复合麻醉》课件
- 外墙脚手架施工方案完整版
- 曲臂车高空作业车施工方案1
- 污水处理厂焊接钢管施工方案
- 电梯日管控、周排查、月调度内容表格
- 介入护士进修汇报
评论
0/150
提交评论