《数字图像处理实验三中值滤波和均值滤波实验报告(共22页).docx》由会员分享,可在线阅读,更多相关《数字图像处理实验三中值滤波和均值滤波实验报告(共22页).docx(22页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上数字图像处理实验三均值滤波、中值滤波的计算机实现 崔雪莹 计科1202班一、实验目的:1)熟悉均值滤波、中值滤波处理的理论基础;2)掌握均值滤波、中值滤波的计算机实现方法;3)学习VC+ 6。0 的编程方法;4)验证均值滤波、中值滤波处理理论;5)观察均值滤波、中值滤波处理的结果。二、实验的软、硬件平台: 硬件: 微型图像处理系统,包括:主机, PC机;摄像机;软件: 操作系统:WINDOWS2000或WINDOWSXP应用软件:VC+ 6.0三、实验内容:1)握高级语言编程技术;2)编制均值滤波、中值滤波处理程序的方法;3)编译并生成可执行文件;4)考察处理结果。四
2、、实验要求:1)学习VC+确6。0 编程的步骤及流程;2)编写均值滤波、中值滤波的程序;3)编译并改错;4)把该程序嵌入试验二给出的界面中(作适当修改);5)提交程序及文档;6)写出本次实验的体会。五、实验结果截图实验均值滤波采用的是3X3的方块,取周围的像素点取得其均值代替原像素点。边缘像素的处理方法是复制边缘的像素点,增加一个边框,计算里面的像素值得均值滤波。六、实验体会本次实验在前一次的实验基础上增加均值滤波和中值滤波,对于椒盐噪声的处理,发现中值滤波的效果更为好一点,而均值滤波是的整个图像变得模糊了一点,效果差异较大。本次实验更加增加了对数字图像处理的了解与学习。七、实验程序代码注释及
3、分析/ HistDemoADlg.h : 头文件/#include ImageWnd.h#pragma once/ CHistDemoADlg 对话框class CHistDemoADlg : public CDialogEx/ 构造public:CHistDemoADlg(CWnd* pParent = NULL);/ 标准构造函数int nWidth;int nHeight;int nLen;int nByteWidth;BYTE *lpBackup;BYTE *lpBitmap;BYTE *lpBits;CString FileName;CImageWnd source,dest;/ 对
4、话框数据enum IDD = IDD_HISTDEMOA_DIALOG ;protected:virtual void DoDataExchange(CDataExchange* pDX);/ DDX/DDV 支持/ 实现protected:HICON m_hIcon;/ 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MA
5、P()public:void LoadBitmap(void);afx_msg void OnOpen();afx_msg void OnHist();void HistogramEq(void);void NoColor(void);void HistogramEq1(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput);void MeanFilter(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput);void MedianFilter(int nWidth,int nHeight,B
6、YTE *lpInput,BYTE *lpOutput);afx_msg void OnBnClickedClose();afx_msg void OnBnClickedMeanfilter();afx_msg void OnBnClickedMedianfilter();HistDemoADlg.cpp对HistDemoADlg.h进行具体的实现,OnOpen()函数响应ID为IDC_OPEN的按钮事件,而且会调取文件选择对话框,选取文件之后,会显示在原始图像区域显示对应的位图图像,OnHist()函数会响应ID为IDC_HIST的按钮事件,调用HistogramEq()进行直方图均衡化的处
7、理,HistogramEq()会调用HistogramEq1()进行直方图均衡化的处理,并用dst.setImage()显示处理之后的图像,以及NoColor()函数,对原始图像转化为灰度图像之后再显示。/ HistDemoADlg.cpp : 实现文件/#include stdafx.h#include HistDemoA.h#include HistDemoADlg.h#include afxdialogex.h#ifdef _DEBUG#define new DEBUG_NEW#endif#define Point(x,y) lpPoints(x)+(y)*nWidth#define P
8、oint1(x,y) lpPoints1(x)+(y)*nWidth/ 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogExpublic:CAboutDlg();/ 对话框数据enum IDD = IDD_ABOUTBOX ;protected:virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV 支持/ 实现protected:DECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialogEx(CAboutDlg:
9、IDD)void CAboutDlg:DoDataExchange(CDataExchange* pDX)CDialogEx:DoDataExchange(pDX);BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()/ CHistDemoADlg 对话框CHistDemoADlg:CHistDemoADlg(CWnd* pParent /*=NULL*/): CDialogEx(CHistDemoADlg:IDD, pParent)m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);lpBit
10、map = 0;lpBackup = 0;void CHistDemoADlg:DoDataExchange(CDataExchange* pDX)CDialogEx:DoDataExchange(pDX);BEGIN_MESSAGE_MAP(CHistDemoADlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_OPEN, &CHistDemoADlg:OnOpen)ON_BN_CLICKED(IDC_HIST, &CHistDemoADlg:OnHist)ON_BN_CLI
11、CKED(IDCLOSE, &CHistDemoADlg:OnBnClickedClose)ON_BN_CLICKED(IDC_MEANFILTER, &CHistDemoADlg:OnBnClickedMeanfilter)ON_BN_CLICKED(IDC_MEDIANFILTER, &CHistDemoADlg:OnBnClickedMedianfilter)END_MESSAGE_MAP()/ CHistDemoADlg 消息处理程序BOOL CHistDemoADlg:OnInitDialog()CDialogEx:OnInitDialog();/ 将“关于.”菜单项添加到系统菜单中
12、。/ IDM_ABOUTBOX 必须在系统命令范围内。ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);/ 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动/ 执行此操作SetIcon(m_hIcon, TRUE);/ 设置大图标SetIcon(m_hIcon, FALSE);/ 设置小图标/ TODO: 在此添加额外的初始化代码sou
13、rce.Create(0,LSource,WS_CHILD|WS_VISIBLE,CRect(40,40,360,280),this,10000);dest.Create(0,LDestination,WS_CHILD|WS_VISIBLE,CRect(400,40,720,280),this,10001);return TRUE; / 除非将焦点设置到控件,否则返回 TRUEvoid CHistDemoADlg:OnSysCommand(UINT nID, LPARAM lParam)if (nID & 0xFFF0) = IDM_ABOUTBOX)CAboutDlg dlgAbout;dl
14、gAbout.DoModal();elseCDialogEx:OnSysCommand(nID, lParam);/ 如果向对话框添加最小化按钮,则需要下面的代码/ 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,/ 这将由框架自动完成。void CHistDemoADlg:OnPaint()if (IsIconic()CPaintDC dc(this); / 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc(), 0);/ 使图标在工作区矩形中居中int cxIcon = GetSyste
15、mMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;/ 绘制图标dc.DrawIcon(x, y, m_hIcon);elseCDialogEx:OnPaint();/当用户拖动最小化窗口时系统调用此函数取得光标/显示。HCURSOR CHistDemoADlg:OnQueryDragIcon()ret
16、urn static_cast(m_hIcon);void CHistDemoADlg:LoadBitmap()/位图文件:BITMAPFILEHEADER+BITMAPINFOHEADER+有效信息部分BITMAPINFOHEADER *pInfo; /位图文件的头部信息指针pInfopInfo=(BITMAPINFOHEADER *)(lpBitmap+sizeof(BITMAPFILEHEADER); /pInfo指向位图文件的头部信息nWidth=pInfo-biWidth; /图片宽度nByteWidth=nWidth*3; /字节宽度if (nByteWidth%4) nByteW
17、idth+=4-(nByteWidth%4); /使字节宽度为4的整数倍nHeight=pInfo-biHeight;/图片高度if (pInfo-biBitCount!=24) /位图的位深度不为24if (pInfo-biBitCount!=8) /位深度不为8AfxMessageBox(L无效位图);delete lpBitmap;lpBitmap=0;return;/位深度为8unsigned int PaletteSize=1biBitCount; /左移8位,PaletteSize调色板尺寸if (pInfo-biClrUsed!=0 & pInfo-biClrUsedbiClrU
18、sed; / biClrUsed 位图实际使用的颜色表中的颜色数lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);/lpBits指向有效信息部分RGBQUAD *pPalette=(RGBQUAD *)lpBits; /颜色表部分/*typedef struct tagRGBQUAD BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved; RGBQUAD;*/lpBits+=sizeof(RGBQUAD)*PaletteSize;/lpBits指向图像有效
19、信息部分nLen=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nByteWidth*nHeight;/整个位图文件的长度BYTE *lpTemp=lpBitmap;lpBitmap=new BYTEnLen;BITMAPFILEHEADER bmh;BITMAPINFOHEADER bmi;bmh.bfType=B+M*256;bmh.bfSize=nLen;bmh.bfReserved1=0;bmh.bfReserved2=0;bmh.bfOffBits=54;bmi.biSize=sizeof(BITMAPINFOHEADER);bm
20、i.biWidth=nWidth;bmi.biHeight=nHeight;bmi.biPlanes=1;bmi.biBitCount=24;bmi.biCompression=BI_RGB;bmi.biSizeImage=0;bmi.biXPelsPerMeter=0;bmi.biYPelsPerMeter=0;bmi.biClrUsed=0;bmi.biClrImportant=0;int nBWidth=pInfo-biWidth;if (nBWidth%4) nBWidth+=4-(nBWidth%4);memset(lpBitmap,0,nLen);memcpy(lpBitmap,&
21、bmh,sizeof(BITMAPFILEHEADER);/位图文件头部memcpy(lpBitmap+sizeof(BITMAPFILEHEADER),&bmi,sizeof(BITMAPINFOHEADER);/位图信息头部BYTE *lpBits2=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);/位图图像信息部分int x,y,p1,p2,Palette;for(y=0;ynHeight;y+)for(x=0;xnWidth;x+)p1=y*nBWidth+x;p2=y*nByteWidth+x*3;if (lpBi
22、tsp1PaletteSize) Palette=lpBitsp1;else Palette=0;lpBits2p2=pPalettePalette.rgbBlue;lpBits2p2+1=pPalettePalette.rgbGreen;lpBits2p2+2=pPalettePalette.rgbRed;delete lpTemp;lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);if (lpBackup) delete lpBackup;lpBackup=new BYTEnLen;memcpy(lpBack
23、up,lpBitmap,nLen);void CHistDemoADlg:OnOpen() /点击打开文件之后,对应的事件处理函数/ TODO: 在此添加控件通知处理程序代码CFile File;CFileDialog dlg(TRUE,0,0,OFN_HIDEREADONLY,L位图文件|*.bmp|所有文件|*.*|,this);/新建文件选择对话框if (dlg.DoModal()=IDOK) FileName=dlg.GetPathName(); /得到文件的路径if (!File.Open(FileName,CFile:modeRead) return; /以只读方式打开文件/ TO
24、DO: add loading code hereif (lpBitmap) delete lpBitmap;/保证lpBitmap为空nLen=(int)File.GetLength(); /得到文件的长度lpBitmap=new BYTEnLen; /为lpBitmap分配空间File.Read(lpBitmap,nLen);/将文件的内容读入到lpBitmap所指向的内存区域LoadBitmap();/调用LoadBitmap(),加载位图图像if (lpBitmap) source.SetImage(nWidth,nHeight,lpBits);void CHistDemoADlg:O
25、nHist()/ TODO: 在此添加控件通知处理程序代码HistogramEq();void GetPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)int x,y,p;int nByteWidth=nWidth*3; if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);for(y=0;ynHeight;y+) /每一行for(x=0;xnWidth;x+) /每一列p=x*3+y*nByteWidth;lpPointsx+y*nWidth=(BYTE)(0.299*(float)lp
26、Bitsp+2+0.587*(float)lpBitsp+1+0.114*(float)lpBitsp+0.1); /三种颜色的比例计算对应点的颜色值,并且强制转换成BYTEvoid PutPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints) /逐个对lpBits进行赋值int nByteWidth=nWidth*3;if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);int x,y,p,p1;for(y=0;ynHeight;y+) /每一行for(x=0;xnWidth;x+) /每一
27、列p=x*3+y*nByteWidth;p1=x+y*nWidth;lpBitsp=lpPointsp1;lpBitsp+1=lpPointsp1;lpBitsp+2=lpPointsp1;void CHistDemoADlg:HistogramEq(void)if (lpBitmap=0) return;BYTE *lpOutput=new BYTEnByteWidth*nHeight;HistogramEq1(nWidth,nHeight,lpBits,lpOutput);dest.SetImage(nWidth,nHeight,lpOutput); /在直方图均衡化的区域显示结果dele
28、te lpOutput;NoColor(); /将原始图像转换成灰度图像void CHistDemoADlg: NoColor()if (lpBitmap=0) return;int x,y,p;BYTE Point;for(y=0;ynHeight;y+) /每一行for(x=0;xnWidth;x+) /每一列p=x*3+y*nByteWidth;Point=(BYTE)(0.299*(float)lpBitsp+2+0.587*(float)lpBitsp+1+0.114*(float)lpBitsp+0.1);/计算颜色值,在0-255的灰度级之间lpBitsp+2=Point;lpB
29、itsp+1=Point;lpBitsp=Point;source.SetImage(nWidth,nHeight,lpBits);/将彩色图像转化成灰度图像void CHistDemoADlg:HistogramEq1(int nWidth, int nHeight, BYTE *lpInput, BYTE *lpOutput)int x,y;BYTE *lpPoints=new BYTEnWidth*nHeight;/像素点的个数GetPoints(nWidth,nHeight,lpInput,lpPoints); /lpPoints存的是颜色值int r256,s256; /颜色值数组,
30、统计对应颜色值像素点的个数ZeroMemory(r,1024);ZeroMemory(s,1024);for(y=0;ynHeight;y+) /统计对应颜色值像素点的个数,Point(x,y)是lpPoints(x,y)for(x=0;xnWidth;x+)rPoint(x,y)+;s0=r0;for(y=1;y256;y+)sy=sy-1;sy+=ry; /计算颜色值的前y种颜色的总像素点的个数(像素点颜色值=y)for(y=0;ynHeight;y+) /将计算对应点的像素值,直方图均匀化的结果保存在lpPointsfor(x=0;xnWidth;x+)Point(x,y)=sPoint
31、(x,y)*255/nWidth/nHeight;PutPoints(nWidth,nHeight,lpOutput,lpPoints); /输出lpPoints到lpOutputdelete lpPoints;void CHistDemoADlg:OnBnClickedClose()/ TODO: 在此添加控件通知处理程序代码/ExitProcess(0);/注意使用时先释放分配的内存,以免造成内存泄露 /exit(0) ;/正常终止程序; exit(非0)非正常终止程序PostQuitMessage(0);/最常用void CHistDemoADlg:OnBnClickedMeanfilt
32、er()/ TODO: 在此添加控件通知处理程序代码if (lpBitmap=0) return;BYTE *lpOutput=new BYTEnByteWidth*nHeight;MeanFilter(nWidth,nHeight,lpBits,lpOutput);dest.SetImage(nWidth,nHeight,lpOutput); /在直方图均衡化的区域显示结果delete lpOutput;NoColor(); /将原始图像转换成灰度图像void CHistDemoADlg:MeanFilter (int nWidth,int nHeight,BYTE *lpInput,BYT
33、E *lpOutput) int x,y;BYTE *lpPoints=new BYTEnWidth*nHeight;/像素点的个数BYTE *lpPoints1 = new BYTE(nWidth+2)*(nHeight+2);GetPoints(nWidth,nHeight,lpInput,lpPoints); /lpPoints存的是颜色值for(y=1;ynHeight+1;y+) /中间最整块图像的拷贝for(x=1;xnWidth;x+)Point1(x,y) = Point(x-1,y-1);/lpPoints1yx = lpPointsy-1x-1;for(y=1;ynHeig
34、ht+1;y+) /最左边和最右边一列的拷贝Point1(0,y) = Point(0,y-1);Point1(nWidth+1,y) = Point(nWidth-1,y-1);/lpPoints1y0 = lpPointsy-10;/lpPoints1ynWidth+1 = lpPointsy-1nWidth-1;for(x=0;xnWidth+2;x+) /最上边和最下边一行的拷贝Point1(x,0) = Point1(x,1);Point1(x,nHeight+1) = Point1(x,nHeight);/lpPoints10x = lpPoints11x;/lpPoints1nH
35、eight+1x = lpPoints1nHeightx;for(y=0;ynHeight;y+) /求以某点为中心的九个数平均值for (x=0;xnWidth;x+)Point(x,y) = ( Point1(x,y) + Point1(x+1,y) + Point1(x+2,y) +Point1(x,y+1) + Point1(x+1,y+1) + Point1(x+2,y+1) +Point1(x,y+2) + Point1(x+1,y+2) + Point1(x+2,y+2) )/9;/*lpPointsyx = (lpPoints1yx + lpPoints1yx+1 + lpPo
36、ints1yx+2 + lpPoints1y+1x + lpPoints1y+1x+1 + lpPoints1y+1x+2 + lpPoints1y+2x + lpPoints1y+2x+1 + lpPoints1y+2x+2)/9;*/PutPoints(nWidth,nHeight,lpOutput,lpPoints); /输出lpPoints到lpOutputdelete lpPoints; void CHistDemoADlg:MedianFilter(int nWidth,int nHeight,BYTE *lpInput,BYTE *lpOutput) int x,y;BYTE *
37、lpPoints=new BYTEnWidth*nHeight;/像素点的个数BYTE *lpPoints1 = new BYTE(nWidth+2)*(nHeight+2);GetPoints(nWidth,nHeight,lpInput,lpPoints); /lpPoints存的是颜色值for(y=1;ynHeight+1;y+) /中间一整块拷贝for(x=1;xnWidth;x+)Point1(x,y) = Point(x-1,y-1);for(y=1;ynHeight+1;y+) /最左边和最右边一列的拷贝Point1(0,y) = Point(0,y-1);Point1(nWid
38、th+1,y) = Point(nWidth-1,y-1);for(x=0;xnWidth+2;x+) /最上边和最下边一行的拷贝Point1(x,0) = Point1(x,1);Point1(x,nHeight+1) = Point1(x,nHeight);BYTE *window = new BYTE9;for(y=0;ynHeight;y+)for (x=0;xnWidth;x+)int k = 0;for(int i=y ; i = y+2 ; i+)for(int j=x ; j = x+2; j+)if(k 9)windowk+ = Point1(j,i);for (int m
39、= 0; m 5; +m) /求9个数的中值,window4为中值 int min = m; for (int n = m + 1; n 9; +n) if (windown windowmin) min = n; / Put found minimum element in its place BYTE temp = windowm; windowm = windowmin; windowmin = temp; Point(x,y) = window4;PutPoints(nWidth,nHeight,lpOutput,lpPoints); /输出lpPoints到lpOutputdelet
40、e lpPoints; void CHistDemoADlg:OnBnClickedMedianfilter()/ TODO: 在此添加控件通知处理程序代码if (lpBitmap=0) return;BYTE *lpOutput=new BYTEnByteWidth*nHeight;MedianFilter(nWidth,nHeight,lpBits,lpOutput);dest.SetImage(nWidth,nHeight,lpOutput); /在中值滤波的区域显示结果delete lpOutput;NoColor(); /将原始图像转换成灰度图像CImageWnd.h类继承自CWnd主要是图像显示方面的函数,如水平滚轮和垂直滚轮的事件函数,以及绘制函数OnPaint(),初始化函数等等,以及存放需要绘制的图像信息的成员变量。setImage(),外接提供绘制的信息,通过参数传递给内部的成员变量。#pragma onceclass CImageWnd:public CWndpublic:int HCurrentPosition; /