c语言课设 图像处理实验报告,数字图像处理实验报告

数字图像处理实验报告

向图像数据部分的指针m_DIB.m_pBits,在数组中查出每个像素变化后的灰度值,并将此值赋给指针m_pBits指向的内存。刷新视图。

然后在菜单中加上线性拉伸的菜单,为该菜单的ID添加消息响应函数,在该函数中创建对话框,并调用文档类线性拉伸的函数,将对话框的两个成员变量传给此函数。

3.局部处理:

在文档类里添加低通滤波和高通滤波的成员函数,在函数中使用m_DIB对象中指向图像数据部分的指针m_pBits,首先申请一个新内存,将原来图像的灰度值存储起来,然后定义9个BYTE类型的指针,利用双重嵌套循环,在循环中每次用这9个指针指向复制图像对应模板中的9个数,然后按照模板中的数值计算出中心像素的灰度值,判断是否超过范围,如果超过范围则做相应的处理,否则将此值直接赋给m_pBits中对应的中心像素。循环之后刷新视图。

添加局部处理的菜单,为菜单设置消息响应函数,在菜单消息响应函数中调用文档类的函数,完成对m_DIB的处理。

4.图像几何变换:

建立平移对话框,定义两个成员变量,分别存储输入的水平位移和垂直位移。

在文档类里添加平移函数,申请一块新内存复制原图像的信息,在函数中将

外层循环变量i视为纵坐标,内层循环变量j视为横坐标,通过双重循环,对每个像素,求出其在原图像中的坐标(i0,j0),将复制图像中的对应(i0,j0)的像素灰度值赋给m_DIB.m_pBits指针中的图像。如果在原图像中找不到该像素,置为背景色。刷新视图。

在菜单中添加图像平移菜单,并为该菜单添加消息响应函数,在此函数中创建平移对话框,调用文档类的平移函数,将对话框的成员变量传入该函数。

建立缩放对话框类,为此类定义两个成员变量,存储输入的水平缩放因子和垂直缩放因子。

再在文档类中添加缩放函数,利用m_DIB.m_pBMI(指向位图信息头的指针),修改位图信息头中的宽度,高度,图像大小。计算出新图像的大小,申请一块新内存存储新图像,同平移函数一样,计算出每个像素在原图像中的坐标,i0=i/PRatio,j0=j/VRatio,PRatio与VRatio分别为水平缩放因子和垂直缩放因子。将原图像中对应坐标的灰度值赋给新内存,然后将m_DIB.m_pBits(指向图像数据的指针)指向新内存,刷新视图。

5.中值滤波:

在文档类中添加两个成员函数。一个用来把传入的指针里的内容排序,一个用来做中值滤波。也要申请一块新内存来复制原图像的信息,双重嵌套循环,边界像素不处理,对每个像素,使用一个大小为9个字节的数组来存放复制图像窗口中各像素值,然后将数组首地址传入排序的函数中,将中间的值赋给当前图像窗口中心的像素。排序函数我用的是快速排序法。

在菜单中添加中值滤波菜单项,为其添加消息响应函数,调用文档类的中值滤波函数。

6.边缘检测:

在文档类中定义三个函数,分别为Roberts,Prewit,Sobel算子处理函数,处理时,先申请新内存复制原来图像信息,边界像素不作处理,对每个像素值,求出其在复制图像中的梯度,判断,若梯度值大于150(这个是我自己定的),则将灰度值赋为255,否则置零。

菜单中添加边缘检测菜单,置属性为Pop—up,添加三个下一级菜单,分别为Roberts,Prewit,Sobel,各个菜单的消息响应函数中调用文档类中各自的处理函数。

7.图像旋转:

创建一个对话框输入旋转角度,在文档类中添加成员函数。

先将角度化为弧度值。

计算原图像四个角点的坐标,以及新图像四个角点的坐标。

根据新图像四个角点的坐标,取对角线上两个点横坐标差值较大值作为宽度,纵坐标差值较大值作为高度。

根据计算出来的高度和宽度修改文件信息头,并且申请内存存储新图像。

计算每点的像素在原来图像中的坐标从而获取其灰度值,写入新内存。

将m_DIB.m_pBits指向该新内存。刷新视图。

添加图像旋转菜单,在菜单响应函数中创建对话框,调用文档类中旋转函数,将对话框中获取的角度传给旋转函数。

8.图像二值化:

在文档类添加一个成员函数,根据传人的图像和阈值返回组间方差和组内方差的比值。

再添加一个成员函数,进行二值化。

在函数中:

计算新BMP文件的大小,申请一块新内存,存储新的整个BMP文件的信息,将位图信息头中biBitCount置为1,调色板数组只有两个两个元素,下标为0的三个灰度值都为0,下标为1的三个灰度值为255。

从最大灰度值到最小灰度值之间搜寻上述函数返回值最大的值,作为阈值。

对每个像素,若其原来灰度值小于阈值,赋1,否则赋0。

将m_DIB,m_pBits指向新内存的图像数据部分,m_DIB.m_pBMI指向位图信息头。

9.图像直方图:

为文档类添加一个int型指针成员变量m_pGray,在构造函数中将该指针赋空,在文档类中定义了一个函数,统计各个灰度值出现的频数,申请一个内存,存储在这个内存中,并将m_pGray指向它。

创建一个画直方图的对话框,添加Picture控件,在控件里调用文档类成员变量,画直方图。添加一个滚动条,用来确定阈值,为滚动条添加消息响应函数,按照滚动条的值进行二值化。

在菜单中添加直方图菜单,添加消息响应函数,在响应函数中创建直方图对话框对象。

最后,因为我开始做工程的时候没有把菜单设计好,做得有点乱,所以,我又在View里添加WM_CONTEXTMENU消息响应函数,在函数体内用CMenu类来实现弹出菜单。

四、结果分析与评价

(1)Raw格式到BMP格式的转换:效果见图1。

图表 1

老师说在转化的时候后面用一个循环会降低效率,但是实际上只要宽度是4的整数倍,后面的循环就不会做了。所以这个算法效率我觉得还行吧。

(2)线性变化:输入线性变化范围10~20,效果见图2。

图表 2

用了线性查找表之后,这个算法的效率应该会高很多,但是我的算法里是线性表从0~255都有变化之后的值,实际上,如果图片的灰度范围小一些的话,做了很多无用的计算,而且前面已经搜寻过原图像的最大最小灰度值了,所以线性表的生成循环可以只从最小灰度做到最大灰度。另外,我设计的算法里,如果最大值和最小值输反了的话,程序会自动交换他们的值,做这个可能就会多算一些东西了。

(3)低通滤波:效果见图3。

图表 3

取的是8邻域内的平均值,效果不是很好。

高通滤波:效果见图4。

图表 4

基本上我觉得边缘还是有突出了吧。

中值滤波:效果见图5。

图表 5

这个中值滤波的效果我还是比较满意的,因为排序所以要调用其他函数,我用了快速排序,而且用的是9个数的十字丝窗口,所以速度要比25个数的窗口快一些。平滑的效果出来还可以。

(4)边缘检测:

Roberts算子:效果见图6。

图表 6

Prewit算子:效果见图7。

图表 7

Sobel算子:效果见图8。

图表 8

由于Prewit算子和Sobel算子都用了8个数去做,所以效果要好一些,相比之下,Sobel算子对这幅图又要效果好些,应该是对4邻域赋予了更大权的缘故。但是后两种算法计算量也要大一些。

(5)图像平移:效果见图9。

图表 9

这个图像平移量比较大,所以被裁切的也显得不真实了。主要是因为我的图像大小和坐标都没有变化,所以只在原来的图像坐标范围内显示平移后的图像,实际上,我既可以改变图像的大小,并且为了节省计算,可以让循环变量i和j从一个新的值开始做计算,前面的全都赋背景色。

图像缩放:水平比例0.4,垂直比例0.5,效果见图10。

图表 10

在此基础上旋转:效果见图11。

图表 11

这几种算法主要的计算量都在for循环内,所以要想优化算法的话,必须简化循环里的计算。不过我的想法差不多跟书上的差不多,还没有什么优化。也许,这种优化的算法需要看很多别人做的好程序才能慢慢自己学会吧。

(6)二值化(判断分析法):效果见图12。

图表 12

实际上,我用直方图看的最佳阈值应该在100多左右,而我做的程序阈值好像偏小一些,所以效果不太好,我计算组间方差和组内方差的时候调用了一个函数专门求阈值,可能这里的计算还是有一点问题。而且在我的函数里,要256次调用这个函数,又因为计算机是按字节处理数据的,因此写图像数据的时候要用每8个写到一个数组中,然后通过计算得到字节类型的值,这些都使得我的算法效率比较低,最后一个问题,我觉得如果使用位运算会快一些,但是前面的问题还没有想到比较好的解决方法。

(7)直方图:效果见图13。

这个图像255的像素太多,如果我没算错的话,量化应该不是很好吧。

图表 13

五、实验总结与体会

这次实验学到最大的东西,是自己总算有MFC编程的概念了,虽然自己VC++考试的分数还不错,但是里面的很多东西,不通过自己的编程时绝对不能真正理解。比如说封装性,这次用CDib的方便,很好地利用了类的封装性。另外,比如MFC是基于消息响应机制的,这就决定了,要利用鼠标或者菜单响应函数去实现功能,而用c语言编写程序的时候,完全是按主函数的线程来的。

另外,我也学会了调试的真正含义。以前都只知道那几个按键是做什么用的,调试的真正目的,是根据自己的算法来检验程序计算的各个值是否符合,从而可以很快速方便地查到自己的错误。

自学也是很重要的一方面。实际上,在现在来说,用MSDN也不是很难的事了,我们不应该被英文打到,而且现在,随着对一些专有名词熟悉了之后,看MSDN也容易一些了,万一不懂的函数,也可以利用网络查到很多函数功能用法的解释。

刚开始的时候做的是位图的读取和显示,实在是不知从哪里做起,所以就照着实验书上敲了前面的部分,但是慢慢地也看懂了代码的意思。所以后来的基本上都是自己做的了,但是算法还是基本上和书上差不多。不过自己编的时候还是有很多细节的部分没有注意到,比如说,强制数据类型转换,我自己编的时候没有注意这个问题,结果出了很多错,有些事由于函数调用引起的,有些是由于不等号两边数据的匹配问题,还有的是由于指针的移动,直到这个时候,才真正明白实验书上程序为什么那么多强制类型转换,虽然书上很多东西不是尽善尽美,但是对于我这种刚开始学会编程的人还是有很多可以学习的地方的。

如老师所说,算法的效率是很重要的。要提高算法的效率,一个是要简化计算(不得不说,这需要数学基础),另外一个就是要避免许多重复的计算。在参考书上的程序里,很多时候,为了避免这种重复的计算(在循环中表现尤其明显),会把某些数当常数算出来,只要后来加上这个常数就可以,这样,效率高很多。

另外,对许多出错的情况,我的程序里也没有做好。比如,如果打开的不是8位图像,我的程序不会提示错误,正常结束,而可能做错,所以,这也是我应该向别人程序学习的地方。

最后一个,自己菜单的布局也是很乱的。要从一开始就布局好。

【数字图像处理实验报告】相关文章:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值