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

更新时间:2024-03-16 00:20:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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

《数字图像处理》

实验指导书

一、概述 ........................................................................................................................... 2 二、建立程序框架 ........................................................................................................... 2 三、建立图像类 ............................................................................................................... 3 四、定义图像文档实现图像读/写 ................................................................................ 10 五、实现图像显示 ......................................................................................................... 12 六、建立图像处理类 ..................................................................................................... 18 七、实现颜色处理功能 ................................................................................................. 19 (一) 亮度处理 ................................................................................................................ 19 (二) 对比度处理 ............................................................................................................ 22 (三) 色阶处理 ................................................................................................................ 24 (四) 伽马变换 ................................................................................................................ 25 (五) 饱和度处理 ............................................................................................................ 25 (六) 色调处理 ................................................................................................................ 29 八、实现几何变换功能 ................................................................................................. 29 (一) 图像缩放 ................................................................................................................ 29 (二) 旋转 ........................................................................................................................ 31 (三) 水平镜像 ................................................................................................................ 35 (四) 垂直镜像 ................................................................................................................ 36 (五) 右转90度 .............................................................................................................. 36 (六) 左转90度 .............................................................................................................. 37 (七) 旋转180度 ............................................................................................................ 37 九、实现平滑锐化功能 ................................................................................................. 38

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

十、图像处理扩展编程 ................................................................................................. 38

一、概述

实验项目:图像处理程序编程 运行环境:Windows XP/2000 编程工具:Visual C++ 6.0 主要内容:

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

(2) 编写颜色处理、几何变换、平滑锐化等图像处理代码,并实现其调用; (3) 自行编写实现扩展的图像处理功能。

二、建立程序框架

预备工作:在本机的硬盘上以自己完整的学号和姓名建立一个文件夹。上机编程的内容全部保存在该文件夹中。每次下机前将该文件夹拷贝到网络服务器上本班的文件夹中;下次上机时再从服务器上将文件夹拷贝到本机。 1. 新建应用程序

运行Visual C++ 6.0;

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

点击“工程”选项页;选中“MFC AppWizard(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”选项页,点击展开“DIPLJJ Classes”,

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

将列出该应用程序的所有类。双击某个类,将在编辑窗口中打开该类的.h文件;点击展开类,双击类中已实现的某个成员函数,将打开该类的.cpp文件。 4. 修改“关于”对话框

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

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

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

三、建立图像类

1. 建立类文件

点击菜单“插入——类”,打开“新建类”对话框;在类的类型中选中“Generic Class”;在名称中输入“LImage”;确定。建立起LImage类的头文件LImage.h和源文件LImage.cpp。 2. 编写类定义代码

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

BOOL Create(int a_Width,int a_Height); void Destroy(); BOOL IsValid();

BOOL CopyFrom(LImage *a_pImg); BOOL LoadBmpFile(CString a_Filename); BOOL SaveBitmap(CString a_Filename); //属性

int m_Width,m_Height; //图像的宽度,高度,以象素计 int m_WidthBytes; //每行象素所占字节数 int m_ImageSize; //象素数据总字节数 BYTE* m_pBits; //图像数据块 CDC m_DC; //显示

BOOL BitBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_Width,int a_Height,

int a_SrcX,int a_SrcY,DWORD a_Rop=SRCCOPY); LImage();

virtual ~LImage();

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

};

BOOL StretchBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_DestWidth,

int a_DestHeight,int a_SrcX,int a_SrcY,int a_SrcWidth,int a_SrcHeight, DWORD a_Rop=SRCCOPY);

int a_SrcX,int a_SrcY,int a_SrcWidth,int a_SrcHeight,DWORD a_Rop=SRCCOPY);

int FitBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_DestWidth,int a_DestHeight,

protected:

HBITMAP m_hBitmap; HDC m_hMemDC;

HBITMAP m_hOldBitmap;

private:

#endif // !defined(AFX_LIMAGE_H__4BFB411F_B5D3_4A26_8188_919613CED4A8__INCLUDED_)

3. 编写类实现代码

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

LImage::~LImage() { } {

BITMAPINFO bi;

bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = a_Width; Destroy();

if( a_Width==0 || a_Height==0 ) return FALSE; if( a_Width<0 ) a_Width = -a_Width; if( a_Height<0 ) a_Height = -a_Height; (2) 图像空间创建函数

按给定的图像尺寸分配图像的内存空间,并定义相关参数。 Destroy(); m_hBitmap = NULL; m_pBits = NULL; m_hMemDC = NULL; (1) 构造及析构函数 LImage::LImage()

BOOL LImage::Create(int a_Width,int a_Height)

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

}

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; HDC hdc=CreateCompatibleDC(NULL);

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

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

BITMAP bm;

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 ) { }

m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC,m_hBitmap); m_DC.Attach(m_hMemDC); return TRUE;

(3) 图像空间释放函数

DeleteObject(m_hBitmap); m_hBitmap = NULL; m_pBits = NULL; m_hMemDC = NULL; return FALSE; m_hBitmap = NULL; m_pBits = NULL; return FALSE;

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

void LImage::Destroy() { } { }

BOOL LImage::CopyFrom(LImage *a_pImg) { } { }

int a_DestHeight, int a_SrcX,int a_SrcY,int a_SrcWidth,int a_SrcHeight,DWORD a_Rop) BOOL LImage::StretchBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_DestWidth,

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

m_hMemDC, a_SrcX, a_SrcY, a_Rop);

(5) 图像显示函数

直接显示,缩放显示,按适合窗口的尺寸显示图像。 int a_SrcX,int a_SrcY,DWORD a_Rop) if( a_pImg==NULL || !a_pImg->IsValid() )

return FALSE; return FALSE;

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

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

return ( m_hBitmap!=NULL && m_pBits!=NULL && m_hMemDC!=NULL ); (4) 图像有效性判别及图像复制函数 BOOL LImage::IsValid()

if( m_hBitmap!=NULL && m_pBits!=NULL && m_hMemDC!=NULL ) { }

m_hBitmap = NULL; m_pBits = NULL; m_hMemDC = NULL;

m_DC.Detach();

SelectObject(m_hMemDC,m_hOldBitmap); DeleteDC(m_hMemDC); DeleteObject(m_hBitmap);

BOOL LImage::BitBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_Width,int a_Height,

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

{ }

BOOL LImage::FitBlt(HDC a_DestDC,int a_DestX,int a_DestY,int a_DestWidth, {

int dx,dy,dw,dh; double sx,sy;

sx = (double)a_SrcWidth/(double)a_DestWidth; sy = (double)a_SrcHeight/(double)a_DestHeight; if( sx<=1 && sy<=1 ) { }

else if( sx>sy ) { }

else if( sy>sx ) { } else { }

::SetStretchBltMode(a_DestDC,COLORONCOLOR); return ::StretchBlt(a_DestDC, dx, dy, dw, dh,

dx = a_DestX; dy = a_DestY;

dw = a_DestWidth; dh = a_DestHeight; dw = (int)(a_SrcWidth/sy);

dx = a_DestX + (a_DestWidth - dw)/2; dy = a_DestY; dh = a_DestHeight; dx = a_DestX; dw = a_DestWidth;

dh = (int)(a_SrcHeight/sx);

dy = a_DestY + (a_DestHeight - dh)/2; dx = a_DestX + (a_DestWidth - a_SrcWidth)/2; dy = a_DestY + (a_DestHeight - a_SrcHeight)/2; dw = a_SrcWidth; dh = a_SrcHeight;

int a_DestHeight, int a_SrcX,int a_SrcY,int a_SrcWidth,int a_SrcHeight,DWORD a_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);

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

} {

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

(6) Bmp文件读入函数

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

BOOL LImage::LoadBmpFile(CString a_Filename)

FILE *pf = fopen(a_Filename,\if( pf==NULL ) return FALSE; BITMAPFILEHEADER bmfHeader;

if ( fread((LPSTR)&bmfHeader,1,sizeof(bmfHeader),pf) != sizeof(bmfHeader) ) { fclose(pf); return FALSE; { fclose(pf); return FALSE;

} }

if( bmfHeader.bfType != ((WORD)('M'<<8) | 'B') )

int leng = bmfHeader.bfSize - sizeof(bmfHeader); BYTE *pBmp = (BYTE *)calloc(leng,1); if( pBmp == NULL )

{ fclose(pf); return FALSE;

}

if ( (int)fread(pBmp,1,leng,pf) != leng ) //读入位图文件头后的所有数据 { }

fclose(pf);

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

if( pbi->bmiHeader.biBitCount != 24 ) { free(pBmp); return FALSE;

}

int widthBytes = ((pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32)*4; //将读入的bmp象素数据填入m_pBits int i; BYTE *p1,*p2;

RGBQUAD *ci = pbi->bmiColors;

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

free(pBmp); fclose(pf); return FALSE;

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

} {

{ } else

{ free(pBmp); return FALSE;

}

int bytes = m_WidthBytes;

if( bytes>widthBytes ) bytes = widthBytes; for(i=0;i

free(pBmp); return TRUE;

p1 = m_pBits + i*m_WidthBytes;

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

p2 = pImg + i*widthBytes;

//文件中扫描线由下向上存储 p2 = pImg + (m_Height-1-i)*widthBytes; else

memcpy(p1,p2,bytes);

(7) Bmp文件保存函数

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

BOOL LImage::SaveBitmap(CString a_Filename)

if( !IsValid() ) return FALSE; FILE *pf = fopen(a_Filename,\if( pf==NULL ) return FALSE;

BITMAPINFO *pbmi;

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;

UINT widthBytes = ((m_Width * 24 +31)/32)*4; pbmi->bmiHeader.biXPelsPerMeter = 11810; pbmi->bmiHeader.biYPelsPerMeter = 11810;

pbmi->bmiHeader.biSizeImage = widthBytes * m_Height;

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

pbmi->bmiHeader.biClrUsed = 0;

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

pbmi->bmiHeader.biClrImportant = 0;

BITMAPFILEHEADER hdr; // bitmap file-header BITMAPINFOHEADER *pbih; // bitmap info-header

pbih = (BITMAPINFOHEADER*)pbmi;

hdr.bfType = 0x4d42; // 0x42 = \ hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0;

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

4. 组建程序

在LImage.cpp处于当前编辑窗口时,点击菜单“组建——编译”,或点击相应的工具栏图标,对LImage.cpp进行编译。在VC主界面下侧的组合窗口中将显示编译的状态。当编译中出现错误时,按F4键将依次定位到源程序的错误处,请检查并改正错误。

free((HLOCAL)pbmi); fclose(pf); return TRUE; int i; 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); return FALSE;

}

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

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

1. 添加头文件

在DIPLJJ.h文件中添加如下一行代码:(其中灰色部分为程序中已有的代码,后同) #include \#include \

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

2. 定义图像类指针

在DIPLJJDoc.h文件中添加如下一行代码: // Attributes public:

class LImage *m_pCurImage,*m_pLastImage;

注:定义两个图像类的指针,以使程序具备对最近一次处理的恢复功能。

3. 图像对象的建立和释放

在“ClassView”选项页中,点击展开“CDIPLJJDoc”,双击“CDIPLJJDoc()”,打开DIPLJJDoc.cpp文件,在文件中修改添加如下代码: CDIPLJJDoc::CDIPLJJDoc() { }

CDIPLJJDoc::~CDIPLJJDoc() { }

4. 进行消息映射

点击菜单“查看——建立类向导”,打开“MFC ClassWizard”对话框。在“Class Name”下拉框中选中“CDIPLJJDoc”,在“Object IDs”列表框中选中“CDIPLJJDoc”,然后在“Messgaes”列表框中,选中“OnOpenDocument”并双击,建立起相应的消息映射函数;再选中“OnSaveDocument”双击。

在“Object IDs”列表框中选中“ID_EDIT_UNDO”,然后在“Message”列表框中双击“COMMAND”,建立起相应的消息映射函数。 5. 添加消息映射函数代码

在“ClassView”选项页中,点击展开“CDIPLJJDoc”,双击“OnOpenDocument(LPCTSTR lpszPathName)”,打开DIPLJJDoc.cpp文件,在文件中添加如下代码: BOOL CDIPLJJDoc::OnOpenDocument(LPCTSTR lpszPathName) { }

if (!CDocument::OnOpenDocument(lpszPathName))

return FALSE;

// TODO: Add your specialized creation code here return m_pCurImage->LoadBmpFile(lpszPathName); delete m_pCurImage; delete m_pLastImage;

// TODO: add one-time construction code here m_pCurImage = new LImage; m_pLastImage = new LImage;

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

BOOL CDIPLJJDoc::OnSaveDocument(LPCTSTR lpszPathName) { }

void CDIPLJJDoc::OnEditUndo() { }

点击菜单“组建——组建”,再次组建整个程序,排除组建过程中出现的错误。 // TODO: Add your command handler code here

if( m_pCurImage->IsValid() && m_pLastImage->IsValid() ) { }

LImage *p = m_pCurImage; m_pCurImage = m_pLastImage; m_pLastImage = p; UpdateAllViews(NULL);

// TODO: Add your specialized code here and/or call the base class return m_pCurImage->SaveBitmap(lpszPathName);

五、实现图像显示

1. 定义显示控制变量

在DIPLJJView.h文件中添加两个显示控制变量。 public:

CDIPLJJDoc* GetDocument();

int m_ShowMode; //显示模式:普通缩放;适合窗口 int m_ShowScale; //显示比例,百分之

在DIPLJJView.cpp文件中定义两个显示模式枚举常量,在构造函数中给显示控制参数赋初值。

enum {SHOWMODE_SCALE, SHOWMODE_FIT}; CDIPLJJView::CDIPLJJView() { }

2. 图像显示代码

在CDIPLJJView类的OnDraw()函数中添加图像显示代码。 // TODO: add construction code here m_ShowMode = SHOWMODE_FIT; m_ShowScale = 100;

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

void CDIPLJJView::OnDraw(CDC* pDC) { }

3. 图像区域设置代码

在CDIPLJJView类的OnInitialUpdate()函数中添加视图滚动区域设置代码。 void CDIPLJJView::OnInitialUpdate() {

CScrollView::OnInitialUpdate(); CDIPLJJDoc* pDoc = GetDocument(); CSize sizeTotal;

// TODO: calculate the total size of this view CDIPLJJDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

// TODO: add draw code for native data here CRect rect;

if( m_ShowMode == SHOWMODE_FIT ) { } else { }

CSize size;

size = GetTotalSize(); GetClientRect(&rect); int x0=0,y0=0;

if( rect.Width()>size.cx )

x0 = (rect.Width()-size.cx)/2; y0 = (rect.Height()-size.cy)/2;

pDoc->m_pCurImage->BitBlt(pDC->m_hDC,x0,y0,pDoc->m_pCurImage->m_Width,

pDoc->m_pCurImage->m_Height,0,0);

if( rect.Height()>size.cy ) if( m_ShowScale==100 ) GetClientRect(&rect);

m_ShowScale = pDoc->m_pCurImage->FitBlt(pDC->m_hDC,0,0,rect.Width(),

rect.Height(),0,0,pDoc->m_pCurImage->m_Width, pDoc->m_pCurImage->m_Height);

else

pDoc->m_pCurImage->StretchBlt(pDC->m_hDC,x0,y0,size.cx,size.cy,

0,0,pDoc->m_pCurImage->m_Width,pDoc->m_pCurImage->m_Height);

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

}

if( pDoc->m_pCurImage->IsValid() ) { } else { }

SetScrollSizes(MM_TEXT, sizeTotal);

sizeTotal.cx = sizeTotal.cy = 100; if( m_ShowMode==SHOWMODE_FIT ) { } else { }

sizeTotal.cx = (int)(pDoc->m_pCurImage->m_Width*m_ShowScale/100.0+0.5); sizeTotal.cy = (int)(pDoc->m_pCurImage->m_Height*m_ShowScale/100.0+0.5); CRect rect;

this->GetClientRect(&rect); sizeTotal.cx = rect.Width(); sizeTotal.cy = rect.Height();

// ((CMainFrame*)AfxGetApp()->m_pMainWnd)->ShowScale(m_ShowScale);

4. 修整程序菜单

切换到“ResourceView”选项页,展开“DIPLJJ resources”,展开“Menu”,双击“IDR_MAINFRAME”,对菜单进行编辑。

在各顶层菜单下保留如下菜单项,其余删除。 文件:打开,保存,另存为,最近文件,退出 编辑:撤消

查看:工具栏,状态栏 帮助:关于

5. 添加显示操作菜单

点击顶层菜单“查看”,双击下部空白菜单项,打开“菜单项目 属性”对话框,在ID下拉列表框中输入“ID_SHOW_ENLARGE”,在标明编辑框中输入“放大”,在提示编辑框中输入“放大显示图象\\n放大”。关闭对话框,将该菜单项拖至最上部。

继续依次建立如下三个菜单项:

ID ID_SHOW_REDUCE ID_SHOW_ORIGINAL 标明 缩小 原始尺寸 提示 缩小显示图象\\n缩小 按原始尺寸显示图象\\n原始尺寸 《数字图像处理》实验指导书 15

ID_SHOW_FIT 适合窗口 使图象完整显示在窗口中\\n适合窗口 点击顶层菜单“查看”,双击下部空白菜单项,在“菜单项目 属性”对话框中,选中“分隔符”,关闭对话框,将分隔符拖至“工具栏”菜单项之上,“适合窗口”之下。

6. 编辑工具栏

切换到“ResourceView”选项页,展开“DIPLJJ resources”,展开“Toolbar”,双击“IDR_MAINFRAME”,对工具栏进行编辑。

保留打开、保存、关于三个按钮,删除其它按钮。

添加“撤消”按钮:点中最后的空白按钮,绘制撤消图形,双击该按钮,将ID设为“ID_EDIT_UNDO”,将按钮拖至保存按钮之后。

再依次添加如下四个按钮: 放大——ID_SHOW_ENLARGE 缩小——ID_SHOW_REDUCE 原始尺寸——ID_SHOW_ORIGINAL 适合屏幕——ID_SHOW_FIT 工具栏中个按钮的形状如下:

打 保开 存 撤消 放缩大 小 原始尺寸 适合屏幕 关于

7. 进行消息映射

点击菜单“查看——建立类向导”,打开“MFC ClassWizard”对话框。在“Class Name”下拉框中选中“CDIPLJJView”,在“Object IDs”列表框中选中“CDIPLJJView”,然后在“Message”列表框中选中“WM_SIZE”并双击,建立消息映射函数。

在“Object IDs”列表框中选中“ID_SHOW_ENLARGE”,然后在“Message”列表框中双击“COMMAND”,建立相应的消息映射函数。之后,依次建立“ID_SHOW_REDUCE”,“ID_SHOW_ORIGINAL”,“ID_SHOW_FIT”的消息映射函数。

8. 添加消息映射函数代码

打开DIPLJJView.cpp,在生成的消息映射函数中添加代码。 void CDIPLJJView::OnSize(UINT nType, int cx, int cy) { }

CScrollView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here OnInitialUpdate();

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

void CDIPLJJDoc::OnProcFliph() { }

注:在后面其它无参数的消息映射函数中,仅加粗的一行需改变,其它各行不变。 5. 组建程序,运行测试

// TODO: Add your command handler code here LImageProc lip;

lip.m_pSrcImg = m_pCurImage; lip.m_pDestImg = m_pLastImage; if( lip.FlipH() ) { }

LImage *p = m_pCurImage; m_pCurImage = m_pLastImage; m_pLastImage = p; UpdateAllViews(NULL); SetPathName(\

(四) 垂直镜像

参照水平镜像的实现过程,自行实现该功能。

(五) 右转90度

1. 在图像处理类中实现右转90度功能

在LImageProc.h文件中加入右转90度函数的定义:

BOOL RotateRight(); //图像顺时针旋转90度

在LImageProc.cpp文件的最后,添加函数的实现代码,如下: BOOL LImageProc::RotateRight() //图像顺时针旋转90度 {

if( !ImageIsValid() ) return FALSE;

m_pDestImg->Create(m_pSrcImg->m_Height, m_pSrcImg->m_Width); //宽高交换 BYTE *sd=m_pSrcImg->m_pBits; BYTE *dd=m_pDestImg->m_pBits; int i,j,k1,k2;

for(i=0;im_Height;i++) {

k1 = i*m_pSrcImg->m_WidthBytes; k2 = (m_pDestImg->m_Width-1-i)*3; for(j=0;jm_Width;j++) {

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

}

}

}

memcpy(dd+k2, sd+k1, 3); k1+=3;

k2+=m_pDestImg->m_WidthBytes;

return TRUE;

2. 建立菜单

在“几何变换”下建立水平镜像菜单项,ID为“ID_PROC_ROTATE_RIGHT”,标明为“右转90度”,提示为“右转90度\\n右转”。 3. 建立消息映射函数

在CDIPLJJDoc类中建立“右转90度”菜单项的消息映射函数。 4. 在消息映射函数中添加调用代码

打开DIPLJJDoc.cpp文件,在OnProcFliph()函数中加入如下代码: void CDIPLJJDoc::OnProcFliph() { }

5. 组建程序,运行测试

// TODO: Add your command handler code here LImageProc lip;

lip.m_pSrcImg = m_pCurImage; lip.m_pDestImg = m_pLastImage; if( lip.RotateRight() ) { }

LImage *p = m_pCurImage; m_pCurImage = m_pLastImage; m_pLastImage = p; UpdateAllViews(NULL); SetPathName(\

(六) 左转90度

参照右转90度功能。

(七) 旋转180度

参照水平镜像和垂直镜像。

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

九、实现平滑锐化功能

参照课堂笔记、作业及水平镜像功能的实现模式,依次实现如下功能: (1) 均值平滑;

(2) 水平一阶微分边缘检测; (3) 垂直一阶微分边缘检测; (4) 双向一阶微分边缘检测; (5) 双向一阶微分锐化。

十、图像处理扩展编程

自行设计并实现如下一个或多个图像处理功能。 1. 简单色彩处理

实现如下一组简单的色彩处理功能:

(1) 转为灰度图像。将彩色图像转为灰度图像。

(2) 生成负片。将每个像素点的每个基色值取反(小变大,大变小)。 (3) 单通道图像。生成红、绿、蓝某一个基色构成的图像。 2. 图像插值缩放

实现图像的双向一次或高次插值缩放。 3. 边缘保持平滑

参照教材,实现一组能较好保持边缘的平滑方法,包括中值平滑、最小方差均值平滑、K邻近平滑、对称近邻均值平滑等。 4. 照片自动处理

针对于实景照片,依据对直方图的分析,自动对照片进行亮度、对比度调整,以及自动进行平滑和锐化,以改善照片的视觉效果。

本文来源:https://www.bwwdw.com/article/4om8.html

Top