04级数字图像处理试验说明及简要指导文档
2007.5.10 第一版
2007.5.17 更新了对话框操作
2007.5.29 实验检查通知和报告要求
试验检查情况(截至07.6.4)
04级数字图像实验检查通知
实验报告大体要求
(Word版下载)
在阅读本文前,假设你已经:
1, 能够用C语言实现特定算法;
2, 对C++的类、对象等概念有简单的了解。
本文内容:
1,主要关注的两个类
3,菜单显示处理结果
四、对话框操作(New)
五、一点说明
一、04级数字图像处理实验内容及要求
详见BBS置顶
实验内容
1. 计算图象统计参数:最大值,最小值,均值,直方图;
2. 对比度增强:直方图均衡;
3. 图象平滑:中值滤波;图象锐化: Sobel算子;
4. 图像旋转:将图像旋转任意角度并显示;
5. 图象变换:将图象分块(8*8),作DCT变换,并作IDCT;
注: 所有实验均对灰度(8bit)图象进行处理即可。
实验时可以自己选用不同的图象,也可以使用512×512或1024×1024的图象。
检查时将提供样图。
实验要求
1. 试验要求使用编程语言完成,包括C, C++, basic,pascal. 不允许用matlab。
可以用VB, Delphi, VC等工具软件。推荐使用c/c++,在VC环境下编程。
2. 递交实验结果的可执行程序、源程序并演示实验结果。如源程序不能提供, 请说明
理由。
3. 递交实验报告。要求:写出选做实验的实验原理、实验结果,并对实验结果进行分
析。
范例下载
http://202.38.75.33/doc-introduce.html#image
二、VC++ 6.0试验环境简单介绍
考虑到一部分同学对VC环境不熟悉,为了避免大家把时间浪费在MFC框架的熟悉上,针对本课程实验的要求,这里简单介绍一下VC环境,希望对大家专注于图像处理算法有益。(从实验要求及简单的原则,有的地方不一定符合MFC规范。)
在本实验中,可以直接利用提供的例子程序进行修改即可。以下的讲解与范例都是基于例子程序的。
大家实验时主要涉及CDib类和CShowDIBView类,至于CShowDIBApp、CMainFrame、CShowDIBDoc几个类以及他们之间的关系,可以不用理会他。
图1 打开例子程序所看到的界面
CDib类负责图像处理算法的实现;View类负责显示。
程序里已经含有一个二值化的示例程序,依照它就可以实现自己的算法。
图2
假设要实现的函数名为AllBlack,功能为将图像上所有点变为黑点
1) 在DIB.h里声明函数
双击类名CDib,右边显示CDIB.h的内容,在其中添加函数声明 bool AllBlack();
图3
2) 在CDIB类体(即DIB.cpp)中定义函数
双击CDib的任意函数,即可在主窗口中显示函数的实现代码。
复制ConvertToTwoValue函数体,直接对其进行修改即可
图4 准备拷贝二值化例子程序
图5 拷贝结束(未修改为AllBlack()函数)
修改拷贝的函数,使函数名与我们声明的一致。修改函数体,实现我们需要的功能。
图6 修改函数和函数体
参数说明:size---图像数据块大小(矩阵宽╳矩阵高)
P---指向图像数据块的指针
1) 编辑菜单
打开资源视图;
图7
打开菜单资源,并编辑
图8
图9
点击”Properties(属性)”后弹出对话框,在对话框中编辑菜单名和ID号
图10
关闭属性对话框。
2) 添加响应函数
在菜单上点击右键
图11
弹出得对话框中Class Name项选”CShowDIBView”,
图12
Message处选择“COMMAND”,然后点击“Add Function”,在弹出的对话框中点“OK”
图13
图14
消息映射添加完毕,点击“Edit Code”按钮,就行编辑,使之达到以下目的:
点击菜单“全黑”时,调用我们写好的“AllBlack()”函数并显示结果。
图15
点击”Edit Code(编辑代码)”按钮后,将进入CShowDIBView.cpp文件进行函数编写。
3) 调用已经写好的处理程序,处理并显示之
图16
1),设置断点
直接按F9,或者利用图示的设置工具。
图17
2),调试运行
直接按F5,就运行到第一个断点,再次按F5就运行到第二个断点,依次下去,直至结束。
或者利用菜单中的start debugègo,或者点击“设置断点”左边的图标
三、在View(视图)中的绘图
在本试验中,需要自己根据数值进行绘图,比如直方图的绘制。
下面演示直方图的绘制:
1,依照“菜单显示”步骤,编辑好菜单,并完成消息映射,最后在ShowDIBCiew.cpp文件中的程序结构如下图
图18
2,调用自己写好的直方图统计函数
3,使用GetDC函数获取DC后,用DC进行绘图
如果需要每次刷新后,都能显示DC绘制的效果,则需要把DC绘图部分放在CShowDIBView::OnDraw(CDC* pDC)函数中。
图19
效果图如下(真实的直方图和下图差别比较大,我这里只是用常数划几条线示例一下而已)
图20
四、对话框操作
我们来制作一个输出结果和获取参数的对话框。界面如下:
1,创建对话框资源
图21
图22
1,在对话框上添加Edit框和Static 控件,编辑效果如下
“结果”表示要从View类获得输入,并显示(比如显示最大值等)
“参数”表示要把对话框中Edit的值返回给View,使以后的程序利用此参数(比如旋转角度等)
图23
2,将两个Edit框关联两个变量
选中Edit框,并点击右键,在出现的菜单里选择“Classwizard”,在弹出的新建对话框类提醒时,点击“OK”,在弹出的对话框中填写类名,自己给他命名为CShow(这个名字是你随便定的),然后点击“OK”确定。
(注意:如果你是第二次添加Edit控件,并点右键关联变量你将直接看到图27。只有没有创建对话框类的第一次关联才会出现图24-图26的过程)
图24
图25
图26
再回到Classwizard对话框的时候,我们选择“member variables”选项页,就可以看到我们刚才添加的两个Edit控件的ID了,在这里关联两个变量即可。
选中某个Edit控件对应的ID,点击右边的Add Variable..按钮,在弹出的对话框里添加变量名和类型即可。点击“OK”,并在Classwizard的对话框也点击“OK”关闭
图27
图28
同样的道理为Edit2添加关联成员变量为m_param。
3,在View中给CShow类的成员变量赋值或者从其中取值
注意要在View类的头文件或者cpp文件的开始,包含CShow类的头文件
图29
下面以已经存在的二值化菜单为例演示。
l 点击“2Value”菜单
l 弹出我们添加的CShow对应的对话框
l “结果”对应的Edit显示View中已经计算完毕的值
l 在“参数”对应Edit填入数值,关闭对话框后,在View类中取到此值
图30
图31
五、一点说明
1,不要拘泥于形式。显示的手段是多样的,比如最大值显示可以用messagebox简单显示,可以用对话框,还可以写文件,还可以用DC的textout来显示,随便你用一种自己觉得方便的方法,并不一定都要用对话框来显示。
2,图像处理的实现 比 界面的设计更重要。实验的重点在于实现图像处理的算法。如果编程工具不熟的话,更应该把精力集中在实现实验的要求,而并非其他的事情,诸如漂亮的界面。
3,给大家写这个文档,是为了照顾那些对于编程比较陌生的同学,所以只介绍最基本的操作,而对于VC或者.net等某个编程环境的并非几页纸能写完。如果对VC++感兴趣的同学,可以在课后学习《VC++技术内幕》、《深入浅出MFC》等经典著作(.net我就不知道了。大概图书馆都能找到一大堆吧)。当然,之前你要熟悉一下C++。
4,一点提醒:
在做sobel的时候,是不是应该分配一段空间(或者用大数组,不推荐数组的方法,容易出错),保存图像的一个副本?
在作图像旋转的时候,图像大小已经改变,是不是应该重新开辟空间,在把Dib类里数据指针指向新开辟并且保存处理结果的内存段(指向指针即可)?,这种情况下是不是要改变Dib中关于图像大小的几个成员变量值?
(分配内存C中用malloc,施放用free,C++中用new,施放用delete。忘记的同学复习一下C)
在其他时间上机的同学如果有不明白的问题,可以在每周二、四上课课间和我讨论,或者给我发信(bywang@mail.ustc.edu.cn),或者询问当时的助教老师。
根据大家试验反映的情况,文档可能会有更新,我都放在以下地址:
http://mail.ustc.edu.cn/~bywang/ip.html