《数字图像处理》综合性实验报告

《数字图像处理》综合性实验

 

    目: 

    级:                

学生姓名:                                  

学生学号:                            

指导老师:                                 

提交时间:         

    绩:             

                    

                    

华南农业大学信息学院


一、实验目的

    1.掌握各种边缘检测算子的概念及原理。

2.掌握各种边缘检测算子的算法。

3.掌握各种边缘检测算子VC++实现的编制技巧。

4.启发学生依据边缘特征进行图像分析与识别,提高学生图像处理与分析能力和实际动手能力。

二、实验内容

1.编程实现以下六种图像边缘检测算子。

(1)Roberts边缘算子

(2)Sobel边缘算子

(3)Prewitt边缘算子

(4)拉普拉斯边缘算子

(5)Kirsch边缘算子

(6)高斯-拉普拉斯边缘算子

2.根据检测结果,分析与比较各种边缘检测算法的主要区别。

三、实验要求

    1.熟练利用VC++编程实现六个图像边缘检测算子

2.选取最优阈值或近似最优阈值实现图像二值化

3.通过对比检测效果,对比分析六个检测算子

四、实验原理

      算法思想及原理:

       就是基于算子模板的卷积过程,比如有一张8x8的图片,像素矩阵如下:

      

       又有一个3x3的算子模板矩阵如下:

       整个模板卷积过程就是用模板覆盖在像素矩阵上,重新计算像素值并移动的过程。如下图即为模板盖住左上角的示例。

       计算方式为模板单元格的值与被模板覆盖的图像子矩阵的值分别相乘并求和,并把结果放在模板中央单元格所对应的图像矩阵单元格中。上图模板中央对应的单元格的值应为:12*0+23*(-1)+52*0+12*(-1)+0*4+0*(-1)+56*0+45*(-1)+47*0=-80。

       各算子模板如下:

       1. Roberts算子

       2. 拉普拉斯边缘算子

       3. Kirsch边缘算子

       4. 高斯-拉普拉斯算子

       5. Prewitt边缘算子

       6. Sobel算子

五、实验过程

    1. 编写一个通用的模板卷积函数,并将实际模板作为参数。

    2. 在CDib类里面实现对应的模板卷积函数及模板卷积矩阵(数组)。

    3. 为菜单添加边缘检测的相关菜单项并添加事件处理函数。

    4. 拿一张灰度的8位图测试并对比结果。

六、实验结果及分析

    1. 下面是一些实验的结果及对比

    1.1 原图

    1.2 Roberts算子检测结果:

    1.3 Sobel算子结果:

    1.4 Prewitt边缘算子结果:

    1.5拉普拉斯边缘算子结果:

    1.6 Kirsch边缘算子结果

    1.7高斯-拉普拉斯算子结果:

    2. 结果分析

    通过以上实验结果对比可知,Roberts算子和Sobel算子的检测结果是比较理想的,其中,Roberts算子的边缘非常清晰。而其他算子可以明显的看出边缘处有较多的杂点,不明朗。当然,这几个算子模板并没有谁好谁不好之分,只是应用领域不同。

七、实验总结

    本次实验是在前面两次实验的基础上进行拓展的,故必须把前面打开和保存BMP、转灰度、直方图显示及均衡化的实验完善好。本次实验的完成还是相当顺利的,主要还是因为之前接触过MFC,对MFC的机制有些了解。考虑到图片处理效率等问题,我也发现VC++是非常适合做图片处理的。通过本次实验,我掌握了边缘检测算法,并实践了整个过程,感觉获益匪浅。当然,数字图像处理领域的知识体系是非常庞大的,边缘检测只是其中很小的一个。实验过程还是遇到过一些难点的,比如24位真彩色图片转8位的灰度图片,必须重建调色板,重构数据区,修改文件头等,否则会出错。但这些问题都在后来反复实践过程中解决了。

附录1:对应程序代码

矩阵定义:

const int sobel[2][9]=

{

       {-1,-2,-1,0,0,0,1,2,1},

       {-1,0,1,-2,0,2,-1,0,1},

};

const int kirsch[8][9]=

{

       {-3,-3,5,-3,0,5,-3,-3,5},

       {-3,5,5,-3,0,5,-3,-3,-3},

       {5,5,5,-3,0,-3,-3,-3,-3},

       {5,-3,-3,5,0,-3,5,-3,-3},

       {5,5,-3,5,0,-3,-3,-3,-3},

       {-3,-3,-3,5,0,-3,5,5,-3},

       {5,5,-3,5,0,-3,-3,-3,-3},

       {-3,-3,-3,-3,0,5,-3,5,5}

};

const int prewitt[2][9]=

{

       {-1,0,1,-1,0,1,-1,0,1},

       {-1,-1,-1,0,0,0,1,1,1},

};

const int roberts[2][4]=

{

       {1,0,0,-1},

       {0,1,-1,0},

};

const int laplace[2][9]=

{

       {0,1,0,1,-4,1,0,1,0},

       {1,1,1,1,-8,1,1,1,1},

};

const int gauss_Laplace[25]=

{

       -2,-4,-4,-4,-2,

       -4,0,8,0,-4,

       -4,8,24,8,-4,

       -4,0,8,0,-4,

       -2,-4,-4,-4,-2,

};

相关实现:

void CDib::Sobel()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       int k;

       for(k=0;k<2;++k)                                                                         //sobel算子有两个模板

       {

              Convolution(tmp,sobel[k],3,3,true);

       }

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

void CDib::Roberts()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       int k;

       for(k=0;k<2;++k)                                                                        

       {

              Convolution(tmp,roberts[k],2,2,true);

       }

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

void CDib::Prewitt()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       int k;

       for(k=0;k<2;++k)                                                                        

       {

              Convolution(tmp,prewitt[k],3,3,true);

       }

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

void CDib::Kirsch()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       int k;

       for(k=0;k<8;++k)                                                                        

       {

              Convolution(tmp,kirsch[k],3,3,true);

       }

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

void CDib::Laplace()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       int k;

       for(k=0;k<2;++k)                                                                        

       {

              Convolution(tmp,laplace[k],3,3,true);

       }

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

void CDib::Gauss_Laplace()

{

       if (!IsGray())

       {

              AfxMessageBox("请先将图像转换为8位灰度图像");

              return ;

       }

       int nWidth=GetWidth();

       int LineBytes=GetLineBytes();

       int nHeight=GetHeight();

       BYTE * pData=GetData();

       BYTE * tmp = new BYTE[LineBytes * nHeight];

       memset(tmp,0,sizeof(BYTE)*LineBytes*nHeight);

       Convolution(tmp,gauss_Laplace,5,5,true);

       memcpy(pData,tmp,sizeof(BYTE)*LineBytes*nHeight);                  //将处理完的数据赋给图像,用以显示

       delete [] tmp; 

}

附录2:用户使用说明

运行方式:直接运行提交文件夹根目录下的边缘检测.exe或用VC6打开程序项目文件夹下的BitmapTest.dsw运行。随后用菜单栏的的文件菜单项打开一个8位灰度BMP图像(或者打开24位的BMP图片并用菜单栏的灰度菜单项转化成8位灰度),随后就可以用边缘检测的菜单项观察结果了。

华南农业大学信息学院

设计性、综合性实验

 

第二篇:数字图像处理实验报告(二)

数字图像增强处理和编程实现

                                                  学号:030841017   姓名:李攀

一、实验目的

1、学习用C++Buider对数字图像进行处理;

2、利用C++Buider对数字图像的读取等基本操作;

3、掌握数字图像增强的原理极其过程;

二、  实验内容

1.熟悉C++Buider环境,初步掌握利用C++Buider对数字图像处理的编程实现。

2.数字图象增强技术包括:扩展对比度,增强图像中对象的边缘,消除或抑制噪声或保留图像中感兴趣的某些特征而抑制另一些特征。

三、验原理

1、图像增强

增强图象中的有用信息,它可以是一个失真的过程,其目的是要改善图像的视觉效果,针对给定图像的应用场合,有目的地强调图像的整体或局部特性,将原来不清晰的图像变得清晰或强调某些感兴趣的特征,扩大图像中不同物体特征之间的差别,抑制不感兴趣的特征,使之改善图像质量、丰富信息量,加强图像判读和识别效果,满足某些特殊分析的需要。  

2、空间滤波

对比度扩展的辐射增强是通过单个像元的运算从整体上改善图像的质量。而空间滤波则是以重点突出图像上的某些特征为目的的,如突出边线或纹理等,因此通过像元与其周围相邻像元的关系,采用空间域中的邻域处理方法。它仍属于一种几何增强处理,主要包括平滑和锐化。

四、实验结果分析

1.图像的读取与关闭

利用OpenPictureDialog和Close可以实现图像的读取和关闭

2.图像的柔化

    柔化后的图像和原图相比,减低了细节幅度,使图像看起来有些模糊,显得更加柔和。图像柔化的过程就是将图像各点的RGB加权求平均值,在柔化图像操作时用到了一个3*3的卷积核矩阵。当然也可用其他卷积核矩阵,这样即可得到不同的柔和效果。

         柔和操作就好像是用低通滤波器来过滤图像,将图像中的高频成分滤掉。而图像中的高频部分就是图像中颜色变化比较快的部分,也就是图像的边缘部分。

3.图像的锐化

和原图相比可以发现,锐化与柔化恰恰相反,其目的是增强图像的细节,使图像看起来更加清晰和醒目。图像锐化的过程也是一种像素点RGB的加权求值,与柔化不同的是,锐化图像的3*3的卷积核矩阵可以为,当然也可以为其他的矩阵,也能得到不同的锐化效果。

与柔化相比,锐化相当一个高通滤波器,它过滤了图像的低频部分。而图像中的低频部分就是图像中颜色变化较慢的部分,即图像中平滑的部分。

4.扩散图像

扩散图像不是采用卷积核的办法,而是采用随机函数来处理图像。这样就在图像上引入了一些随机性。从而使图像出现了油画般的渗透效果。

本例是从某点为中心的3*3的区域内随机选择一点作为该店的像素值,在处理完毕后,从整体看来图像的边缘部分彼此交错,出现了渗透般的效果。

5.中值滤波

     中值滤波与图像的柔化处理相比较,同样是一种像素点的区域算法。观察后可以得知,中值滤波和柔化效果基本相同,但从处理随机噪声来看,中值滤波的效果要更好些。但中值滤波需要对某个像素点领域的数进行排序,所以处理速度会慢些。

6.边缘增强

         与原图相比,边缘增强使图像的轮廓更加突出。边缘增强使图像中的高频部分,即图像中变化剧烈的区域图像出来。同时削弱了图像中的低频部分,因此那些像素点变化缓慢的部分会变黑。

边缘增强也是一种滤波器,也可用卷积核来实现。这里用到的是一个卷积核,属于水平竖直边缘同时增强。并且在处理完的图像上各点像素值加了一个小常数,这也出现了图像的浮雕效果。

7.边缘检测

边缘检测是通过边缘检测算子来检查每个像素的领域,并对其颜色的灰度变化率进行量化,其中也包括方向的确定。这里用的是Prewitt算子进行边缘检测,它涉及到用两个3*3的卷积核矩阵的操作。运算后取较大的作为运算结果。

五、实验心得

    本次实验我开始学习C++Builder,从开始对图片的读取和关闭,逐渐学习直到对数字图像增强的实现。

这个过程也让我对C++Builder的了解也逐渐深入。其次对于数字图像的处理方面,也是我有了更深的认识,

以前课堂上学的一些知识都似懂非懂,通过这次实验,用自己的图片进行处理,也使我对数字图像的增强实现有了更多感性的认识。当然,如果想更好的理解这些实现的方法,我想我还有很多地方需要学习、

相关推荐