《数字图像处理》实验指导书.docx

上传人:b****3 文档编号:12673143 上传时间:2023-04-21 格式:DOCX 页数:57 大小:84.69KB
下载 相关 举报
《数字图像处理》实验指导书.docx_第1页
第1页 / 共57页
《数字图像处理》实验指导书.docx_第2页
第2页 / 共57页
《数字图像处理》实验指导书.docx_第3页
第3页 / 共57页
《数字图像处理》实验指导书.docx_第4页
第4页 / 共57页
《数字图像处理》实验指导书.docx_第5页
第5页 / 共57页
点击查看更多>>
下载资源
资源描述

《数字图像处理》实验指导书.docx

《《数字图像处理》实验指导书.docx》由会员分享,可在线阅读,更多相关《《数字图像处理》实验指导书.docx(57页珍藏版)》请在冰豆网上搜索。

《数字图像处理》实验指导书.docx

《数字图像处理》实验指导书

 

《数字图像处理》

实验指导书

编写:

罗建军

 

海南大学三亚学院

2009年10月

目录

一、概述1

二、建立程序框架1

三、建立图像类2

四、定义图像文档实现图像读/写9

五、实现图像显示11

六、建立图像处理类17

七、实现颜色处理功能18

(一)亮度处理18

(二)对比度处理21

(三)色阶处理22

(四)伽马变换24

(五)饱和度处理24

(六)色调处理28

八、实现几何变换功能28

(一)图像缩放28

(二)旋转30

(三)水平镜像34

(四)垂直镜像35

(五)右转90度35

(六)左转90度36

(七)旋转180度36

九、实现平滑锐化功能36

十、图像处理扩展编程37

一、概述

实验项目:

图像处理程序编程

运行环境:

WindowsXP/2000

编程工具:

VisualC++6.0

主要内容:

(1)建立程序框架,实现图像的读取、保存、显示;

(2)编写颜色处理、几何变换、平滑锐化等图像处理代码,并实现其调用;

(3)自行编写实现扩展的图像处理功能。

二、建立程序框架

预备工作:

在本机的硬盘上以自己完整的学号和姓名建立一个文件夹,如:

0810660044李剑。

上机编程的内容全部保存在该文件夹中。

每次下机前将该文件夹拷贝到网络服务器上本班的文件夹中;下次上机时再从服务器上将文件夹拷贝到本机。

1.新建应用程序

运行VisualC++6.0;

点击菜单“文件——新建”,打开“新建”对话框;

点击“工程”选项页;选中“MFCAppWizard(exe)”;在“位置”编辑框中选中自己所建立的文件夹;在“工程名称”编辑框中输入DIP?

?

?

,其中?

?

?

为自己姓名的拼音缩写,如DIPLJJ;按“确定”按钮,进入向导过程。

2.应用程序向导

步骤1:

选择“单文档”,其它不变,

步骤2:

不作改变,点击“下一步”;

步骤3:

不作改变,

步骤4:

取消“打印和打印预览”;按下“高级”按钮,在“文件扩展名”编辑框中输入bmp,关闭;点击“下一步”;

步骤5:

选择“作为静态的DLL”,点击“下一步”;

步骤6:

将CDIPLJJView类的基类选择为CScrollView,其它不变,点击“完成”。

点击“确定”。

3.应用程序框架及基本操作

在完成向导过程后,将建立一套应用程序框架,该框架中包含如下几个类:

CDIPLJJApp——应用程序类

CMainFrame——主窗口框架类

CDIPLJJDoc——文档类

CDIPLJJView——视图类

CAboutDlg——关于对话框类

(其中LJJ应换为自己姓名的拼音缩写,后同)

每个类都有一个类定义文件.h,和类实现文件.cpp。

在VC主界面左侧的组合窗口中,切换到“ClassViev”选项页,点击展开“DIPLJJClasses”,将列出该应用程序的所有类。

双击某个类,将在编辑窗口中打开该类的.h文件;点击展开类,双击类中已实现的某个成员函数,将打开该类的.cpp文件。

4.修改“关于”对话框

在VC主界面左侧的组合窗口中,切换到“ResourceView”选项页,展开“DIPLJJresources”,展开“Dialog”,双击“IDD_ABOUTBOX”,对“关于”对话框进行编辑,在“版权所有(C)2009”之前加上自己的学号和姓名,然后保存。

5.组建和运行程序

点击菜单“组建——组建”,或点击相应的工具条按钮,生成可执行程序(exe);

点击菜单“组建——执行”,或点击相应的工具条按钮,运行该程序,在程序中打开“关于”对话框。

三、建立图像类

1.建立类文件

点击菜单“插入——类”,打开“新建类”对话框;在类的类型中选中“GenericClass”;在名称中输入“LImage”;确定。

将建立LImage类的头文件LImage.h和源文件LImage.cpp。

2.编写类定义代码

打开LImage.h文件,将LImage类的定义代码添加到该头文件中(灰底部分为文件中已有的代码,后同):

classLImage

{

public:

LImage();

virtual~LImage();

BOOLCreate(inta_Width,inta_Height);

voidDestroy();

BOOLIsValid();

BOOLCopyFrom(LImage*a_pImg);

BOOLLoadBmpFile(CStringa_Filename);

BOOLSaveBitmap(CStringa_Filename);

//属性

intm_Width,m_Height;//图像的宽度,高度,以象素计

intm_WidthBytes;//每行象素所占字节数

intm_ImageSize;//象素数据总字节数

BYTE*m_pBits;//图像数据块

CDCm_DC;

//显示

BOOLBitBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_Width,inta_Height,

inta_SrcX,inta_SrcY,DWORDa_Rop=SRCCOPY);

BOOLStretchBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_DestWidth,

inta_DestHeight,inta_SrcX,inta_SrcY,inta_SrcWidth,inta_SrcHeight,

DWORDa_Rop=SRCCOPY);

intFitBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_DestWidth,inta_DestHeight,

inta_SrcX,inta_SrcY,inta_SrcWidth,inta_SrcHeight,DWORDa_Rop=SRCCOPY);

protected:

HBITMAPm_hBitmap;

HDCm_hMemDC;

private:

HBITMAPm_hOldBitmap;

};

#endif//!

defined(AFX_LIMAGE_H__4BFB411F_B5D3_4A26_8188_919613CED4A8__INCLUDED_)

3.编写类实现代码

打开LImage.cpp文件,将LImage类的实现代码添加到该文件中。

(1)构造及析构函数

LImage:

:

LImage()

{

m_hBitmap=NULL;

m_pBits=NULL;

m_hMemDC=NULL;

}

LImage:

:

~LImage()

{

Destroy();

}

(2)图像空间创建函数

按给定的图像尺寸分配图像的内存空间,并定义相关参数。

BOOLLImage:

:

Create(inta_Width,inta_Height)

{

Destroy();

if(a_Width==0||a_Height==0)returnFALSE;

if(a_Width<0)a_Width=-a_Width;

if(a_Height<0)a_Height=-a_Height;

BITMAPINFObi;

bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

bi.bmiHeader.biWidth=a_Width;

bi.bmiHeader.biHeight=-a_Height;//使图像原点在左上角;若为正数则在左下角

bi.bmiHeader.biPlanes=1;

bi.bmiHeader.biBitCount=24;

bi.bmiHeader.biCompression=BI_RGB;

bi.bmiHeader.biSizeImage=0;

bi.bmiHeader.biXPelsPerMeter=11810;

bi.bmiHeader.biYPelsPerMeter=11810;

bi.bmiHeader.biClrUsed=0;

bi.bmiHeader.biClrImportant=0;

HDChdc=CreateCompatibleDC(NULL);

m_hBitmap=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&m_pBits,NULL,0);

DeleteDC(hdc);

if(m_hBitmap==NULL||m_pBits==NULL)

{

m_hBitmap=NULL;

m_pBits=NULL;

returnFALSE;

}

BITMAPbm;

GetObject(m_hBitmap,sizeof(BITMAP),&bm);

m_Width=bm.bmWidth;

m_Height=bm.bmHeight;

m_WidthBytes=bm.bmWidthBytes;

m_ImageSize=m_WidthBytes*m_Height;

m_hMemDC=CreateCompatibleDC(NULL);

if(m_hMemDC==NULL)

{

DeleteObject(m_hBitmap);

m_hBitmap=NULL;

m_pBits=NULL;

m_hMemDC=NULL;

returnFALSE;

}

m_hOldBitmap=(HBITMAP)SelectObject(m_hMemDC,m_hBitmap);

m_DC.Attach(m_hMemDC);

returnTRUE;

}

(3)图像空间释放函数

voidLImage:

:

Destroy()

{

if(m_hBitmap!

=NULL&&m_pBits!

=NULL&&m_hMemDC!

=NULL)

{

m_DC.Detach();

SelectObject(m_hMemDC,m_hOldBitmap);

DeleteDC(m_hMemDC);

DeleteObject(m_hBitmap);

}

m_hBitmap=NULL;

m_pBits=NULL;

m_hMemDC=NULL;

}

(4)图像有效性判别及图像复制函数

BOOLLImage:

:

IsValid()

{

return(m_hBitmap!

=NULL&&m_pBits!

=NULL&&m_hMemDC!

=NULL);

}

BOOLLImage:

:

CopyFrom(LImage*a_pImg)

{

if(a_pImg==NULL||!

a_pImg->IsValid())

returnFALSE;

if(!

Create(a_pImg->m_Width,a_pImg->m_Height))

returnFALSE;

memcpy((void*)m_pBits,(void*)a_pImg->m_pBits,m_WidthBytes*m_Height);

returnTRUE;

}

(5)图像显示函数

直接显示,缩放显示,按适合窗口的尺寸显示图像。

BOOLLImage:

:

BitBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_Width,inta_Height,

inta_SrcX,inta_SrcY,DWORDa_Rop)

{

return:

:

BitBlt(a_DestDC,a_DestX,a_DestY,a_Width,a_Height,

m_hMemDC,a_SrcX,a_SrcY,a_Rop);

}

BOOLLImage:

:

StretchBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_DestWidth,

inta_DestHeight,inta_SrcX,inta_SrcY,inta_SrcWidth,inta_SrcHeight,DWORDa_Rop)

{

:

:

SetStretchBltMode(a_DestDC,COLORONCOLOR);

return:

:

StretchBlt(a_DestDC,a_DestX,a_DestY,a_DestWidth,a_DestHeight,

m_hMemDC,a_SrcX,a_SrcY,a_SrcWidth,a_SrcHeight,a_Rop);

}

intLImage:

:

FitBlt(HDCa_DestDC,inta_DestX,inta_DestY,inta_DestWidth,

inta_DestHeight,inta_SrcX,inta_SrcY,inta_SrcWidth,inta_SrcHeight,DWORDa_Rop)

{

intdx,dy,dw,dh;

doublesx,sy;

sx=(double)a_SrcWidth/(double)a_DestWidth;

sy=(double)a_SrcHeight/(double)a_DestHeight;

if(sx<=1&&sy<=1)

{

dx=a_DestX+(a_DestWidth-a_SrcWidth)/2;

dy=a_DestY+(a_DestHeight-a_SrcHeight)/2;

dw=a_SrcWidth;

dh=a_SrcHeight;

}

elseif(sx>sy)

{

dx=a_DestX;

dw=a_DestWidth;

dh=(int)(a_SrcHeight/sx);

dy=a_DestY+(a_DestHeight-dh)/2;

}

elseif(sy>sx)

{

dw=(int)(a_SrcWidth/sy);

dx=a_DestX+(a_DestWidth-dw)/2;

dy=a_DestY;

dh=a_DestHeight;

}

else

{

dx=a_DestX;dy=a_DestY;

dw=a_DestWidth;dh=a_DestHeight;

}

:

:

SetStretchBltMode(a_DestDC,COLORONCOLOR);

:

:

StretchBlt(a_DestDC,dx,dy,dw,dh,

m_hMemDC,a_SrcX,a_SrcY,a_SrcWidth,a_SrcHeight,a_Rop);

if(a_SrcWidth!

=0)

return(int)(dw*100.0/a_SrcWidth+0.5);

else

return-1;

}

(6)Bmp文件读入函数

读入一个Bmp文件并将图像放入对象中。

BOOLLImage:

:

LoadBmpFile(CStringa_Filename)

{

FILE*pf=fopen(a_Filename,"rb");

if(pf==NULL)returnFALSE;

BITMAPFILEHEADERbmfHeader;

if(fread((LPSTR)&bmfHeader,1,sizeof(bmfHeader),pf)!

=sizeof(bmfHeader))

{fclose(pf);returnFALSE;}

if(bmfHeader.bfType!

=((WORD)('M'<<8)|'B'))

{fclose(pf);returnFALSE;}

intleng=bmfHeader.bfSize-sizeof(bmfHeader);

BYTE*pBmp=(BYTE*)calloc(leng,1);

if(pBmp==NULL)

{fclose(pf);returnFALSE;}

if((int)fread(pBmp,1,leng,pf)!

=leng)//读入位图文件头后的所有数据

{

free(pBmp);fclose(pf);

returnFALSE;

}

fclose(pf);

BYTE*pImg=(BYTE*)(pBmp+bmfHeader.bfOffBits-sizeof(BITMAPFILEHEADER));

BITMAPINFO*pbi;

pbi=(BITMAPINFO*)pBmp;

if(pbi->bmiHeader.biBitCount!

=24)

{free(pBmp);returnFALSE;}

intwidthBytes=((pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32)*4;

//将读入的bmp象素数据填入m_pBits

inti;

BYTE*p1,*p2;

RGBQUAD*ci=pbi->bmiColors;

if(Create(pbi->bmiHeader.biWidth,abs(pbi->bmiHeader.biHeight)))

{

intbytes=m_WidthBytes;

if(bytes>widthBytes)bytes=widthBytes;

for(i=0;i

{

p1=m_pBits+i*m_WidthBytes;

if(pbi->bmiHeader.biHeight<0)//文件中扫描线由上向下存储

p2=pImg+i*widthBytes;

else//文件中扫描线由下向上存储

p2=pImg+(m_Height-1-i)*widthBytes;

memcpy(p1,p2,bytes);

}

free(pBmp);returnTRUE;

}

else

{free(pBmp);returnFALSE;}

}

(7)Bmp文件保存函数

将对象中的图像保存为Bmp文件。

BOOLLImage:

:

SaveBitmap(CStringa_Filename)

{

if(!

IsValid())returnFALSE;

FILE*pf=fopen(a_Filename,"wb");

if(pf==NULL)returnFALSE;

BITMAPINFO*pbmi;

pbmi=(BITMAPINFO*)calloc(1,sizeof(BITMAPINFOHEADER));

pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

pbmi->bmiHeader.biWidth=m_Width;

pbmi->bmiHeader.biHeight=m_Height;

pbmi->bmiHeader.biPlanes=1;

pbmi->bmiHeader.biBitCount=24;

pbmi->bmiHeader.biCompression=BI_RGB;

UINTwidthBytes=((m_Width*24+31)/32)*4;

pbmi->bmiHeader.biSizeImage=widthBytes*m_Height;

pbmi->bmiHeader.biXPelsPerMeter=11810;

pbmi->bmiHeader.biYPelsPerMeter=11810;

pbmi->bmiHeader.biClrUsed=0;

pbmi->bmiHeader.biClrImportant=0;

BITMAPFILEHEADERhdr;//bitmapfile-header

BITMAPINFOHEADER*pbih;//bitmapinfo-header

pbih=(BITMAPINFOHEADER*)pbmi;

hdr.bfType=0x4d42;//0x42="B"0x4d="M"

hdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+

pbih->biSize+pbih->biSizeImage);

hdr.bfReserved1=0;

hdr.bfReserved2=0;

hdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+pbih->biSize;

fwrite(&hdr,sizeof(BITMAPFILEHEADER),1,pf);//写入位图文件头

fwrite(pbih,sizeof(BITMAPINFOHEADER),1,pf);//写入位图信息头

inti;

BYTE*p1;

for(i=m_Height-1;i>=0;i--)

{

p1=m_pBits+m_WidthBytes*i;

if(fwrite(p1,1,widthBytes,pf)!

=widthBytes)

{free((HLOCAL)pbmi);fclose(pf);returnFALSE;}

}

free((HLOCAL)pbmi);

fclose(pf);

returnTRUE;

}

4.组建程序

在LImage.cpp处于当前编辑窗口时,点击菜单“组建——编译”,或点击相应的工具栏图标,对LImage.cpp进行编译。

在VC主界面下侧的组合窗口中将显示编译的状态。

当编译出现错误时,按F4键将定位到源程序的错误处,然后检查并改正错误。

四、定义图像文档实现图像读/写

1.添加头文件

在DIPLJJ.h文件中添加如下一行代码:

(其中灰色部分为程序中已有的代码,后同)

#include"resource.h"//mainsymbols

#include"L

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 职业规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1