数字图像处理实验三中值滤波和均值滤波实验报告.docx
《数字图像处理实验三中值滤波和均值滤波实验报告.docx》由会员分享,可在线阅读,更多相关《数字图像处理实验三中值滤波和均值滤波实验报告.docx(26页珍藏版)》请在冰豆网上搜索。
数字图像处理实验三中值滤波和均值滤波实验报告
数字图像处理实验三
均值滤波、中值滤波的计算机实现
12281166雪莹计科1202班
一、实验目的:
1〕熟悉均值滤波、中值滤波处理的理论根底;
2〕掌握均值滤波、中值滤波的计算机实现方法;
3〕学习VC++6。
0的编程方法;
4〕验证均值滤波、中值滤波处理理论;
5〕观察均值滤波、中值滤波处理的结果。
二、实验的软、硬件平台:
硬件:
微型图像处理系统,包括:
主机,PC机;摄像机;
软件:
操作系统:
WINDOWS2000或WINDOWSXP应用软件:
VC++6.0
三、实验容:
1〕握高级语言编程技术;
2〕编制均值滤波、中值滤波处理程序的方法;
3〕编译并生成可执行文件;
4〕考察处理结果。
四、实验要求:
1〕学习VC++确6。
0编程的步骤及流程;
2〕编写均值滤波、中值滤波的程序;
3〕编译并改错;
4〕把该程序嵌入试验二给出的界面中〔作适当修改〕;
5〕提交程序及文档;
6〕写出本次实验的体会。
五、实验结果截图
实验均值滤波采用的是3X3的方块,取周围的像素点取得其均值代替原像素点。
边缘像素的处理方法是复制边缘的像素点,增加一个边框,计算里面的像素值得均值滤波。
六、实验体会
本次实验在前一次的实验根底上增加均值滤波和中值滤波,对于椒盐噪声的处理,发现中值滤波的效果更为好一点,而均值滤波是的整个图像变得模糊了一点,效果差异较大。
本次实验更加增加了对数字图像处理的了解与学习。
七、实验程序代码注释及分析
//HistDemoADlg.h:
头文件
//
#include"ImageWnd.h"
#pragmaonce
//CHistDemoADlg对话框
classCHistDemoADlg:
publicCDialogEx
{
//构造
public:
CHistDemoADlg(CWnd*pParent=NULL);//标准构造函数
intnWidth;
intnHeight;
intnLen;
intnByteWidth;
BYTE*lpBackup;
BYTE*lpBitmap;
BYTE*lpBits;
CStringFileName;
CImageWndsource,dest;
//对话框数据
enum{IDD=IDD_HISTDEMOA_DIALOG};
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持
//实现
protected:
HICONm_hIcon;
//生成的消息映射函数
virtualBOOLOnInitDialog();
afx_msgvoidOnSysmand(UINTnID,LPARAMlParam);
afx_msgvoidOnPaint();
afx_msgHCURSOROnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
voidLoadBitmap(void);
afx_msgvoidOnOpen();
afx_msgvoidOnHist();
voidHistogramEq(void);
voidNoColor(void);
voidHistogramEq1(intnWidth,intnHeight,BYTE*lpInput,BYTE*lpOutput);
voidMeanFilter(intnWidth,intnHeight,BYTE*lpInput,BYTE*lpOutput);
voidMedianFilter(intnWidth,intnHeight,BYTE*lpInput,BYTE*lpOutput);
afx_msgvoidOnBnClickedClose();
afx_msgvoidOnBnClickedMeanfilter();
afx_msgvoidOnBnClickedMedianfilter();
};
HistDemoADlg.cpp对HistDemoADlg.h进展具体的实现,OnOpen()函数响应ID为IDC_OPEN的按钮事件,而且会调取文件选择对话框,选取文件之后,会显示在原始图像区域显示对应的位图图像,OnHist()函数会响应ID为IDC_HIST的按钮事件,调用HistogramEq()进展直方图均衡化的处理,HistogramEq()会调用HistogramEq1()进展直方图均衡化的处理,并用dst.setImage()显示处理之后的图像,以及NoColor()函数,对原始图像转化为灰度图像之后再显示。
//HistDemoADlg.cpp:
实现文件
//
#include"stdafx.h"
#include"HistDemoA.h"
#include"HistDemoADlg.h"
#include"afxdialogex.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#endif
#definePoint(x,y)lpPoints[(x)+(y)*nWidth]
#definePoint1(x,y)lpPoints1[(x)+(y)*nWidth]
//用于应用程序“关于〞菜单项的CAboutDlg对话框
classCAboutDlg:
publicCDialogEx
{
public:
CAboutDlg();
//对话框数据
enum{IDD=IDD_ABOUTBOX};
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持
//实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialogEx(CAboutDlg:
:
IDD)
{
}
voidCAboutDlg:
:
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);
lpBitmap=0;
lpBackup=0;
}
voidCHistDemoADlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialogEx:
:
DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CHistDemoADlg,CDialogEx)
ON_WM_SYSMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_OPEN,&CHistDemoADlg:
:
OnOpen)
ON_BN_CLICKED(IDC_HIST,&CHistDemoADlg:
:
OnHist)
ON_BN_CLICKED(IDCLOSE,&CHistDemoADlg:
:
OnBnClickedClose)
ON_BN_CLICKED(IDC_MEANFILTER,&CHistDemoADlg:
:
OnBnClickedMeanfilter)
ON_BN_CLICKED(IDC_MEDIANFILTER,&CHistDemoADlg:
:
OnBnClickedMedianfilter)
END_MESSAGE_MAP()
//CHistDemoADlg消息处理程序
BOOLCHistDemoADlg:
:
OnInitDialog()
{
CDialogEx:
:
OnInitDialog();
//将“关于...〞菜单项添加到系统菜单中。
//IDM_ABOUTBOX必须在系统命令围。
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
BOOLbNameValid;
CStringstrAboutMenu;
bNameValid=strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//设置此对话框的图标。
当应用程序主窗口不是对话框时,框架将自动
//执行此操作
SetIcon(m_hIcon,TRUE);//设置大图标
SetIcon(m_hIcon,FALSE);//设置小图标
//TODO:
在此添加额外的初始化代码
source.Create(0,L"Source",WS_CHILD|WS_VISIBLE,CRect(40,40,360,280),this,10000);
dest.Create(0,L"Destination",WS_CHILD|WS_VISIBLE,CRect(400,40,720,280),this,10001);
returnTRUE;//除非将焦点设置到控件,否那么返回TRUE
}
voidCHistDemoADlg:
:
OnSysmand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx:
:
OnSysmand(nID,lParam);
}
}
//如果向对话框添加最小化按钮,那么需要下面的代码
//来绘制该图标。
对于使用文档/视图模型的MFC应用程序,
//这将由框架自动完成。
voidCHistDemoADlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND,reinterpret_cast(dc.GetSafeHdc()),0);
//使图标在工作区矩形中居中
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//绘制图标
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialogEx:
:
OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSORCHistDemoADlg:
:
OnQueryDragIcon()
{
returnstatic_cast(m_hIcon);
}
voidCHistDemoADlg:
:
LoadBitmap()
{
//位图文件:
BITMAPFILEHEADER+BITMAPINFOHEADER+有效信息局部
BITMAPINFOHEADER*pInfo;//位图文件的头部信息指针pInfo
pInfo=(BITMAPINFOHEADER*)(lpBitmap+sizeof(BITMAPFILEHEADER));//pInfo指向位图文件的头部信息
nWidth=pInfo->biWidth;//图片宽度
nByteWidth=nWidth*3;//字节宽度
if(nByteWidth%4)nByteWidth+=4-(nByteWidth%4);//使字节宽度为4的整数倍
nHeight=pInfo->biHeight;//图片高度
if(pInfo->biBitCount!
=24)//位图的位深度不为24
{
if(pInfo->biBitCount!
=8)//位深度不为8
{
AfxMessageBox(L"无效位图");
deletelpBitmap;
lpBitmap=0;
return;
}
//位深度为8
unsignedintPaletteSize=1<biBitCount;//左移8位,PaletteSize调色板尺寸
if(pInfo->biClrUsed!
=0&&pInfo->biClrUsedbiClrUsed;//biClrUsed位图实际使用的颜色表中的颜色数
lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);//lpBits指向有效信息局部
RGBQUAD*pPalette=(RGBQUAD*)lpBits;//颜色表局部
/*
typedefstructtagRGBQUAD{
BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;
}RGBQUAD;
*/
lpBits+=sizeof(RGBQUAD)*PaletteSize;//lpBits指向图像有效信息局部
nLen=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nByteWidth*nHeight;//整个位图文件的长度
BYTE*lpTemp=lpBitmap;
lpBitmap=newBYTE[nLen];
BITMAPFILEHEADERbmh;
BITMAPINFOHEADERbmi;
bmh.bfType='B'+'M'*256;
bmh.bfSize=nLen;
bmh.bfReserved1=0;
bmh.bfReserved2=0;
bmh.bfOffBits=54;
bmi.biSize=sizeof(BITMAPINFOHEADER);
bmi.biWidth=nWidth;
bmi.biHeight=nHeight;
bmi.biPlanes=1;
bmi.biBitCount=24;
bmi.bipression=BI_RGB;
bmi.biSizeImage=0;
bmi.biXPelsPerMeter=0;
bmi.biYPelsPerMeter=0;
bmi.biClrUsed=0;
bmi.biClrImportant=0;
intnBWidth=pInfo->biWidth;
if(nBWidth%4)nBWidth+=4-(nBWidth%4);
memset(lpBitmap,0,nLen);
memcpy(lpBitmap,&bmh,sizeof(BITMAPFILEHEADER));//位图文件头部
memcpy(lpBitmap+sizeof(BITMAPFILEHEADER),&bmi,sizeof(BITMAPINFOHEADER));//位图信息头部
BYTE*lpBits2=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);//位图图像信息局部
intx,y,p1,p2,Palette;
for(y=0;y{
for(x=0;x{
p1=y*nBWidth+x;
p2=y*nByteWidth+x*3;
if(lpBits[p1]elsePalette=0;
lpBits2[p2]=pPalette[Palette].rgbBlue;
lpBits2[p2+1]=pPalette[Palette].rgbGreen;
lpBits2[p2+2]=pPalette[Palette].rgbRed;
}
}
deletelpTemp;
}
lpBits=lpBitmap+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
if(lpBackup)deletelpBackup;
lpBackup=newBYTE[nLen];
memcpy(lpBackup,lpBitmap,nLen);
}
voidCHistDemoADlg:
:
OnOpen()//点击翻开文件之后,对应的事件处理函数
{
//TODO:
在此添加控件通知处理程序代码
CFileFile;
CFileDialogdlg(TRUE,0,0,OFN_HIDEREADONLY,L"位图文件|*.bmp|所有文件|*.*||",this);//新建文件选择对话框
if(dlg.DoModal()==IDOK)
{
FileName=dlg.GetPathName();//得到文件的路径
if(!
File.Open(FileName,CFile:
:
modeRead))return;//以只读方式翻开文件
//TODO:
addloadingcodehere
if(lpBitmap)deletelpBitmap;//保证lpBitmap为空
nLen=(int)File.GetLength();//得到文件的长度
lpBitmap=newBYTE[nLen];//为lpBitmap分配空间
File.Read(lpBitmap,nLen);//将文件的容读入到lpBitmap所指向的存区域
LoadBitmap();//调用LoadBitmap(),加载位图图像
if(lpBitmap)source.SetImage(nWidth,nHeight,lpBits);
}
}
voidCHistDemoADlg:
:
OnHist()
{
//TODO:
在此添加控件通知处理程序代码
HistogramEq();
}
voidGetPoints(intnWidth,intnHeight,BYTE*lpBits,BYTE*lpPoints)
{
intx,y,p;
intnByteWidth=nWidth*3;
if(nByteWidth%4)nByteWidth+=4-(nByteWidth%4);
for(y=0;y{
for(x=0;x{
p=x*3+y*nByteWidth;
lpPoints[x+y*nWidth]=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+0.114*(float)lpBits[p]+0.1);//三种颜色的比例计算对应点的颜色值,并且强制转换成BYTE
}
}
}
voidPutPoints(intnWidth,intnHeight,BYTE*lpBits,BYTE*lpPoints)//逐个对lpBits进展赋值
{
intnByteWidth=nWidth*3;
if(nByteWidth%4)nByteWidth+=4-(nByteWidth%4);
intx,y,p,p1;
for(y=0;y{
for(x=0;x{
p=x*3+y*nByteWidth;
p1=x+y*nWidth;
lpBits[p]=lpPoints[p1];
lpBits[p+1]=lpPoints[p1];
lpBits[p+2]=lpPoints[p1];
}
}
}
voidCHistDemoADlg:
:
HistogramEq(void)
{
if(lpBitmap==0)return;
BYTE*lpOutput=newBYTE[nByteWidth*nHeight];
HistogramEq1(nWidth,nHeight,lpBits,lpOutput);
dest.SetImage(nWidth,nHeight,lpOutput);//在直方图均衡化的区域显示结果
deletelpOutput;
NoColor();//将原始图像转换成灰度图像
}
voidCHistDemoADlg:
:
NoColor()
{
if(lpBitmap==0)return;
intx,y,p;
BYTEPoint;
for(y=0;y{
for(x=0;x{
p=x*3+y*nByteWidth;
Point=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+0.114*(float)lpBits[p]+0.1);//计算颜色值,在0