vc++数字图像处理实验指导书.docx
- 文档编号:8519286
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:23
- 大小:786.91KB
vc++数字图像处理实验指导书.docx
《vc++数字图像处理实验指导书.docx》由会员分享,可在线阅读,更多相关《vc++数字图像处理实验指导书.docx(23页珍藏版)》请在冰豆网上搜索。
vc++数字图像处理实验指导书
《数字图像处理》
实验指导书
曹江中、何家峰
广东工业大学信息工程学院
二00九年一月
前言
《数字图像处理》是信息工程专业一门重要的专业课程。
随着图像处理技术的迅速发展和在当今社会中的广泛应用,给《数字图像处理》课程的教学提出了新的更高的要求。
《数字图像处理》也是一门实践性较强的课程,实验占有重要地位。
本实验指导书在分析学生专业特点和知识结构的基础上,选择VC++作为编程工具,通过几个主要的图像处理知识点作为实验内容,旨在让学生在较短的实验时间内熟悉数字图像处理实际工程的基本框架、流程,使学生在理论课程学习的同时直接接触、掌握所学知识点的应用,达到培养学生的编程实践能力和学以致用能力的目的。
通过对本指导书的使用,为该门课程的课程设计打下良好的基础。
本指导书的内容包括:
位图格式、VC++图像编程基础、基于VC++的图像工程实例以及图像的基本处理,如平滑、锐化、区域增强等算法设计等。
共8个学时。
在《数字图像处理》的课程实验过程中,要求学生做到:
(1)预习实验指导书有关部分,认真做好实验内容的准备,就实验可能出现的情况提前作出思考和分析。
(2)学生应认真并且独立完成相应实验内容。
(3)认真书写实验报告。
实验报告包括实验目的和要求,实验情况及其分析。
对需编程的实验,写出程序设计说明,给出源程序框图和清单。
(4)遵守机房纪律,服从辅导教师指挥,爱护实验设备。
目录
前言I
目录II
实验一VC++图像编程基础1
一.实验目的1
二.实验内容和要求1
三.实验主要仪器设备和材料1
四.实验原理及方法1
实验二一个简单的图像处理工程实例16
一.实验目的16
二.实验内容和要求16
三.实验主要仪器设备和材料16
四.实验原理与方法16
五.实验内容与步骤17
实验三、图像的空间域平滑和锐化22
一.实验目的22
二.实验内容和要求22
三.实验主要仪器设备和材料22
四.实验原理22
五.实验设计步骤24
实验一VC++图像编程基础
实验项目名称:
VC++图像编程基础
实验项目性质:
验证性实验
所属课程名称:
数字图像处理
实验计划学时:
2
一.实验目的
(1)学习使用vc++图像处理的基本知识。
(2)了解BMP位图格式。
(3)掌握利用VC++建立单文档工程。
(4)掌握使用CDIB类。
(5)掌握添加菜单项和响应函数。
二.实验内容和要求
在VC++6.0环境下编程利用CDIB类实现对位图的读取和显示操作。
三.实验主要仪器设备和材料
计算机,VC++6.0
四.实验原理及方法
1、位图格式
计算机中位图文件由三部分组成,分别是:
文件头、位图信息和位图像素数据(如图1.1)。
文件头
位图信息
(信息头+颜色信息表)
图像数据
图1.1、Bmp位图文件的组成
1.1位图文件头
位图文件头主要用于识别位图文件。
以下是位图文件头结构的定义:
typedefstructtagBITMAPFILEHEADER{
WORDbfType;
DWORDbfSize;
WORDbfReserved1;
WORDbfReserved2;
DWORDbfOffBits;
}BITMAPFILEHEADER;
其中的bfType值应该是“BM”(0x4d42),标志该文件是位图文件。
bfSize的值是位图文件的大小。
1.2位图信息结构
位图信息结构中所记录的值用于分配内存,设置调色板信息,读取像素值等。
以下是位图信息结构的定义:
typedefstructtagBITMAPINFO{
BITMAPINFOHEADERbmiHeader;//信息头
RGBQUADbmiColors[1];//颜色表
}BITMAPINFO;
可见位图信息也是由两部分组成的:
位图信息头+颜色表
1.2.1位图信息头
位图信息头包含了单个像素所用字节数以及描述颜色的格式,此外还包括位图的宽度、高度、目标设备的位平面数、图像的压缩格式。
以下是位图信息头结构的定义:
typedefstructtagBITMAPINFOHEADER{
DWORDbiSize;//结构BITMAPINFOHEADER的字节数,即//sizeof(BITMAPINFOHEADER)*
LONGbiWidth;//以像素为单位的图像宽度*
LONGbiHeight;//以像素为单位的图像长度
WORDbiPlanes;//目标设备的位平面数
WORDbiBitCount//每个像素的位数*
(1)
DWORDbiCompression;//图像的压缩格式(这个值几乎总是为0)
DWORDbiSizeImage;//以字节为单位的图像数据的大小(对//BI_RGB压缩方式而言)
LONGbiXPelsPerMeter;//水平方向上的每米的像素个数
LONGbiYPelsPerMeter;//垂直方向上的每米的像素个数
DWORDbiClrUsed;//调色板中实际使用的颜色数
(2)
DWORDbiClrImportant;//现实位图时必须的颜色数(3)
}BITMAPINFOHEADER;
说明:
(1)、*是需要加以注意的部分,因为它们是我们在进行位图操作时经常参考的变量。
(2)、biBitCount:
对于每个像素的字节数,分别有以下意义:
0,用在JPEG格式中
1,单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片
4,16色图
8,256色图,通常说的灰度图
16,64K图,一般没有调色板,图像数据中每两个字节表示一个像素,5个或6个位表示一个RGB分量
24,16M真彩色图,一般没有调色板,图像数据中每3个字节表示一个像素,每个字节表示一个RGB分量
32,4G真彩色,一般没有调色板,每4个字节表示一个像素,相对24位真彩图而言,加入了一个透明度,即RGBA模式
(3)、biClrUsed:
这个值通常为0,表示使用biBitCount确定的全部颜色,例外是使用的颜色数目小于制定的颜色深度的颜色数目的最大值。
(4)、biClrImportant:
这个值通常为0,表示所有的颜色都是必需的。
1.2.2颜色表
颜色表一般是针对16位以下的图像而设置的,对于16位和16位以上的图像,由于其位图像素数据中直接对对应像素的RGB(A)颜色进行描述,因而省却了调色板。
而对于16位以下的图像,由于其位图像素数据中记录的只是调色板索引值,因而需要根据这个索引到调色板去取得相应的RGB(A)颜色。
颜色表的作用就是创建调色板。
图1.2是带调色板和不带调色板的位图的简单示意图:
a.带调色板的位图b.不带调色板的位图
图1.2不同的位图结构
颜色表是由颜色表项组成的,颜色表项结构的定义如下:
typedefstructtagRGBQUAD{
BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;
}RGBQUAD;
其中需要注意的问题是,RGBQUAD结构中的颜色顺序是BGR,而不是平常的RGB。
1.2.3位图数据
最后,在位图文件头、位图信息头、位图颜色表之后,便是位图的主体部分:
位图数据。
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。
位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=16时,1个像素占2个字节(RGB555格式);
当biBitCount=24时,1个像素占3个字节(BGR格式);
当biBitCount=32时,1个像素占4个字节(BGR-格式,-表示不处理的字节)
注意:
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,一个扫描行所占的字节数计算方法:
DataSizePerLine=(biWidth*biBitCount+31)/8;//一个扫描行所占的字节数
每行的字节数必须是4的倍数。
DataSizePerLine==DataSizePerLine/4*4;
位图数据的大小(不压缩情况下):
DataSize=DataSizePerLine*biHeight;
2、CDIB类
该类将位图文件的读取、象素数据的获取及显示进行了封装。
具体的代码见附带的电子参考资料。
下面介绍具体的成员和方法:
1、boolCDIB:
:
LoadFromFile(LPCTSTRlpszFileName)
功能:
用于加载位图。
参数:
lpszFileName表示加载的位图路径和名称。
如:
d:
\test\123.bmp
返回值:
成功读取后,返回true,否则为false
注意:
但调用该函数成功加载位图后,CDIB类的成员变量m_bLoaded将变为true,否则为false,因此,可以通过m_bLoaded来进行判断是否加载了位图。
2、intGetDIBWidth()
功能:
获取位图的宽度
返回值:
位图的宽度
注意:
该函数只有在加载位图后才能调用,否则会出错(可通过m_bLoaded来判断)。
3、intGetDIBHeight()
功能:
获取位图的高度
返回值:
位图的高度
注意:
该函数只有在加载位图后才能调用,否则会出错(可通过m_bLoaded来判断)。
4、voidCDIB:
:
ShowDIB(CDC*pDC,intnLeft,intnTop,intnRight,intnBottom,BYTE*pDIBData,BITMAPINFO*pBMI)
功能:
显示位图
参数:
pDC//DC的句柄
nLeft,//目标矩形左上角的X坐标
nTop,//目标矩形左上角的Y坐标
nRight,//目标矩形的宽度
nBottom,//目标矩形的高度
0,//源矩形左上角的X坐标
0,//源矩形左上角的Y坐标
GetDIBWidth(),//源矩形的宽度
GetDIBHeight(),//源矩形的高度
pDIBData,//位图图象数据的地址
pBMI,//位图信息结构地址
5、InvalidateData()
功能:
将m_pdata的信息赋值给m_pDIBData,便于显示m_pdata的信息。
6、几个重要的成员变量
BYTE*m_pdata;//位图的灰度信息
boolm_bLoaded;//表示是否加载了位图
BITMAPINFO*m_pBMI;//位图信息头
BYTE*m_pDIBData;//位图象素数据指针
BYTE*m_pDumpDIBData;//位图象素数据指针
BITMAPFILEHEADERbfh;//位图信息头
BITMAPINFOHEADERbih;//位图文件头
注意:
m_pdata与m_pDIBData的关系
⏹如果是8位图,m_pdata与m_pDIBData两个指针指向的数据块内容是相等的,即:
m_pdata[k]=m_pDIBData[k]
⏹如果是24位图,m_pdata与m_pDIBData两个指针指向的数据块内容是不相等的,m_pDIBData代表的是象素的RGB格式,而m_pdata表示的是象素的灰度信息。
其关系为:
m_pdata[ni*nW+nj]=(unsignedchar)(m_pDIBData[ni*(3*nW+length)+3*nj]*0.11+m_pDIBData[ni*(3*nW+length)+3*nj+1]*0.59+m_pDIBData[ni*(3*nW+length)+3*nj+2]*0.3);
具体见CDIB类代码。
当为24位图时,显示时采用m_pDIBData数据,为简单起见,我们可以仅仅对灰度信息进行处理,因为在灰度信息m_pdata数据中,一个象素对应于一个字节,而彩色信息m_pDIBData数据中,一个象素对于于三个字节。
如果对m_pdata进行处理后,我们可以通过调用InvalidateData()函数来将m_pdata的数据赋值给m_pDIBData,从而显示处理结果。
五.实验步骤:
1、建立当文档工程。
步骤一:
建立工程
进入vc集成开发环境,单击File菜单下的new,出现一个对话框,在对话框中选择Project项目,选中MFCAppWinzid(exe),并填写好项目名称,存储路径,点击OK.进入下一步,在出现的页面中选择当文档模式(Singledocument),单击完成(Finish),即可。
步骤二:
编译工程
单击Build菜单下的Executetest.exe(或单击工具栏中的!
)编译一下刚才建立的项目。
即可看到一个如下图1.3的windows风格窗口。
图1.3
2、添加CDIB类
步骤一:
将dib.cpp和dib.h文件(已发给大家)拷贝到工程目录下。
步骤二:
打开工程空间(双击刚才建立的目录下的test.dsw)。
单击在编译窗口中的ProjectAddToProjectFiles,在弹出的对话框中选择dib.cpp和dib.h。
单击确定。
步骤三:
在类视图中查看是否有CDIB类(如下图1.4),如果没有请重复步骤一。
图1.4
3、建立菜单项
步骤一、点击ResouceView。
双击资源中的MEUM->IDC_MAINFRAME。
在编辑框中将看到主框架的菜单资源(如图.5).
如图1.5
步骤二、在菜单资源中,添加菜单栏和菜单项。
双击其中的一个空白菜单栏,即进入其熟悉框,可添加或修改其名称,这里将其命名为(图像操作),如图1.6.
图1.6
步骤三、在“图像操作栏”中添加菜单项――“打开图像”。
具体步骤见图1.7。
步骤四、编译(单击!
),将出现如图1.8的界面,如果没有出现菜单栏和菜单项,请重复到步骤一。
图1.8
4、添加CTestView的公共成员函数m_dib
按照如图1.9中的提示操作,添加CTestView的公共成员函数m_dib.
图1.9
5、添加响应函数
步骤一、右击编辑框中的任意位置,在弹出的提示菜单中,选择ClassWizard,在弹出的类向导对话框中,按照如图1.10的提示进行选择和操作。
图1.10
步骤二、查看类视图中的CTestView类中是否有OnOpenImage函数,正确的如图1.11,单击该函数即进入该函数体。
图1.11
6、实现响应函数的功能
在ClassView中CTestView类中的OnOpenImage函数,进入其函数体。
添加如下红色字体代码:
voidCTestView:
:
OnOpenIamge()
{
//TODO:
Addyourcommandhandlercodehere
staticcharszFilter[]="BMP文件(*.bmp)|*.bmp||";//定义过滤文件的类型
CFileDialogdlg(TRUE,"bmp",NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);//定义文件对话框对象
CStringfilename;
intret=dlg.DoModal();//运行打开文件对方框
if(ret==IDOK)
{
filename=dlg.GetFileName();//获取所选择图像的路径
m_dib.LoadFromFile(filename);//加载图像
if(!
m_dib.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
}
Invalidate
(1);//刷新屏幕
}
7、添加显示代码
在ClassView中CTestView类中的OnDraw函数,进入其函数体。
添加如下红色字体代码:
voidCTestView:
:
OnDraw(CDC*pDC)
{
CTestDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
if(m_dib.m_bLoaded==true)//判断是否加载图像
{
//获取图像宽和高
intnw=m_dib.GetDIBWidth();
intnh=m_dib.GetDIBHeight();
//显示图像(具体的参数见CDIB类的该函数说明)
m_dib.ShowDIB(pDC,10,10,nw,nh,m_dib.m_pDIBData,m_dib.m_pBMI);
m_dib.ShowDIB(pDC,400,10,nw,nh,m_dib.m_pDumpDIBData,m_dib.m_pBMI);
}
}
8、编译运行
点击(!
)编译运行刚才的代码,如果没有出错则可单击“图像操作”――》“打开图像”,选择图像打开,显示(结果如图1.12),有错则对图从第一部分重新新一步一步调试。
图1.12
实验二一个简单的图像处理工程实例
实验项目名称:
一个简单的图像处理工程实例
实验项目性质:
综合性实验
所属课程名称:
数字图像处理
实验计划学时:
3
六.实验目的
(1)掌握图像处理工程的流程。
(2)掌握图像点运算。
(3)理解图像处理功能函数的编写。
(4)了解对CDIB类中各成员函数和变量的功能。
七.实验内容和要求
在实验一的工程中实现图像二值化和底片效果。
八.实验主要仪器设备和材料
计算机,VC++6.0
九.实验原理与方法
1、图像的二值化的基本原理
图像的二值化处理图像分割中的一个主要内容,就是将图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。
用I表示原图,R表示二值化后的图,则二值化的过程可以用以下公式表示:
thr表示选取的阈值。
二值化的过程就是当原图的象素灰度值大于阈值就将其变白,否则就将其变黑。
即将256个亮度等级的灰度图像通过适当的阀值选而将图像变为二个级别灰度级,这样只有二个灰度级的图像在图像处理分析过程中占有非常重要的地位,特别是在实用的图像处理中。
以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。
如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。
如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。
动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。
根据对全图使用统一阈值还是对不同区域使用不同阈值,可以分为全局阈值方法(globalthresholding)和局部阈值方法(localthresholding,也叫做自适应阈值方法adaptivethresholding);这种与坐标相关的阈值也叫动态阈值,此方法也叫变化阈值法,或自适应阈值法。
具体的方法,可以参考相关的图像处理书籍。
本实验采用固定全局阈值方法,即在整个图像中所有的象素点,其阈值thr相同。
2、底片效果原理
大家对照片的底片一定都很熟悉了,底片上的颜色与色彩鲜艳的照片的颜色是正好相反的,即反色。
编程原理:
各种色彩都是由红、绿、蓝三种颜色按不同的比例混合而成的,这就是我们所说的三基色,它们的颜色值(RGB值)是0~255,我们只需用255减去各个点的R、G、B各基色值,然后用255减去这个值,并将这个值重新赋值给各个点,就会达到我们想要的底片效果了。
3、实验中图像处理的一步流程:
获取数据(打开图像,得到图像信息)――>处理数据(采用相应的算法对图像数据进行处理)――>返回结果(显示图像)
一十.实验内容与步骤
1、图像的底片化操作
步骤一、打开实验一建立的test工程空间(双击test.dsw)。
步骤二、按照实验一介绍的方法建立在“图像操作”菜单栏中新建菜单项“底片化”。
步骤三、按照实验一介绍的方法建立菜单项“底片化”的响应函数Negative()。
步骤四、打开响应函数Negative(),将下来红色字体代码拷贝到Negative()中,注意:
请分析每行代码的意思。
voidCTestView:
:
OnNegative()
{
//TODO:
Addyourcommandhandlercodehere
//////////////////////////
//功能:
实现底片化
//////////////////////////
//判断图像是否打开,没打开,则弹出提示框并退出函数
if(!
m_dib.m_bLoaded)
{
AfxMessageBox("图像还打开,请先打开图像!
");
return;
}
//获取图像宽和高
intnw=m_dib.GetDIBWidth();
intnh=m_dib.GetDIBHeight();
inti,j;
//定义阈值并赋值为100;
//对每一个象素进行底片化处理
for(j=0;j for(i=0;i { //对图像的第j行、第i列的象素的灰度信息进行判断,修改 intgray=m_dib.m_pdata[j*nw+i]; m_dib.m_pdata[j*nw+i]=255-gray; } //将修改的m_pdata的数据赋值给m_pDIBData,以显示修改的结果 m_dib.UpdateData(); //刷新屏幕 Invalidate(); } 步骤五、点击(! ),编译运行,打开一幅24位bmp图,然后再单击“二值化”,观察效果。 如图2.1示。 图2.1 2、图像的二值化操作 步骤一、打开实验一建立的test工程空间(双击test.dsw)。 步骤二、按照实验一介绍的方法建立在“图像操作”菜单栏中新建菜单项“二值化”。 步骤三、按照实验一介绍的方法建立菜单项“二值化”的响应函数Binary()。 步骤四、打开响应函数Binary(),将下来红色字体代码拷贝到Binary()中,注意: 请分析个行代码的意思。 voidCTestView: : OnBinary() { //TODO: Addyourcommandhandlercodehere /
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vc 数字图像 处理 实验 指导书