图像处理课程设计报告Word文档下载推荐.docx
《图像处理课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《图像处理课程设计报告Word文档下载推荐.docx(54页珍藏版)》请在冰豆网上搜索。
2.1灰度直方图原理分析
1、灰度直方图
直方像图反映了图的像素的灰度分布是反映一幅图像中的灰度级与出现这种灰度级的像素的概率之间关系的图形。
直方图的横坐标为灰度级(用r表示),纵坐标是具有该灰度级的像素个数或出现此灰度级的概率P(rk)。
设N(=a×
b)为一幅图像中像素总数,nk为第k级灰度的像素数;
rk表示第k个灰度级。
则:
P(rk)=nk/N(归一化后k级灰度像素数)
定义:
反映各灰度级出现频数的分布情况,进而反映图像对(清晰)度,但不反映各灰度级的空间位置分布。
图像的(灰度统计)直方图是一个一维的离散函数。
它的定义为:
设sk为图像f(x,y)的第k级灰度值,nk是f(x,y)中具有灰度值sk的象素的个数,n是图像象素总数,则:
ps(sk)=nk/nk=0,1,¼
,L-1称为图像f(x,y)的直方图。
这里ps(sk)代表原始图中第k个灰度级的出现概率。
以nk为自变量,以ps(sk)为函数,得到的曲线就是图像的直方图,在实际中常常直接将对第k个灰度级的统计值nk作为图像的直方图。
它提供了原图灰度值的分布情况,也可以说给出了一幅图所有灰度值的整体描述。
对灰度图像进行直方图统计的程序流程图如图2-2所示。
图2-2灰度图像直方图统计流程
2、直方图均衡化
如上面所述,一幅给定的图像的灰度级分布在0≤r≤1范围内。
可以对[0,1]区间内的任一个r值进行如下变换也就是说,通过上述变换,每个原始图像的像素灰度值r都对应产生一个s值。
变换函数T(r)应满足下列条件:
(1)在0≤r≤1区间内,T(r)单值单调增加;
(2)对于0≤r≤1,有0≤T(r)≤1。
这里的第一个条件保证了图像的灰度级从白到黑的次序不变。
第二个条件则保证了映射变换后的像素灰度值在允许的范围内。
3、直方图规定化
希望能够有目的地增强某个灰度区间的图像,即能够人为地修正直方图的形状,使之与期望的形状相匹配,这就是直方图规定化的基本思想。
换句话说,希望可以人为地改变直方图形状,使之成为某个特定的形状,直方图规定化就是针对上述要求提出来的一种增强技术,它可以按照预先设定的某个形状来调整图像的直方图。
直方图规定化是在运用均衡化原理的基础上,通过建立原始图像和期望图像之间的关系,选择地控制直方图,使原始图像的直方图变成规定的形状,从而弥补了直方图均衡不具备交互作用的特性。
4、BMP图像文件格式
BMP图像文件是MicrosoftWindows所规定的图像文件格式。
随着Windows的风行全球,BMP图像文件也就成为PC机上流行的图像文件格式。
BMP图像文件具有下列六项特色。
(1)文件结构只能存放一幅图像。
(2)可以存储单色、16色、256色和全彩色四种图像数据。
(3)图像数据可选择压缩或不压缩处理
(4)Windows设计了两种压缩方式:
RLE4和RLE8。
RLE4处理16色图像数据;
而RLE8则是压缩256图像数据。
(5)图像数据排列顺序,与一般图像文件有所不同。
(6)调色板的数据结构特殊。
2.2灰度直方图统计的实现方法
直方图均衡化过程(算法):
(1) 列出原始图灰度级rk;
(2) 统计原始直方图各灰度级像素数nk;
(3) 计算原始直方图各概率:
pk=nk/N;
(4) 计算累计直方图:
sk=Σpk;
(5) 取整Sk=int{(L-1)sk+0.5};
(6) 确定映射对应关系:
rksk;
(7) 统计新直方图各灰度级像素nk'
;
(8) 用pk(sk)=nk'
/N计算新直方图。
利用VisualC++中提供的MFC框架设计一个简单的应用程序框架,具有图像显示,图像直方图均衡、直方图规定化、直方图、直方图均衡后图像等菜单栏,再利用C++具有面向对象程序设计的性质,编写程序代码实现MFC框架中对应菜单栏中的图像处理的功能,即可得到一个简易的图像处理系统,达到课程考核题目的要求。
本次课程考核设计了一个简单的图片处理系统,主要具有以对话框的形式显示原始图片(bmp格式)、显示原图像的直方图、图像直方图均衡化、图像直方图规定化、显示均衡化和规定化处理后的直方图的功能。
2.3图像的灰度变换原理
灰度即使用黑色调表示物体。
每个灰度对象都具有从0%(白色)到100%(黑色)的亮度值。
灰度变换处理是图像增强处理技术中一种非常基础、直接的空间域图像处理方法,也是图像数字化和图像显示的一个重要组成部分。
灰度变换主要针对独立的像素点进行处理,通过改变原始图像数据所占有的灰度范围而使图像在视觉上得到改观。
三.课程设计的步骤和结果
3.1类声明与核心算法程序代码
//灰度均衡
voidCBitmapView:
:
OnPointEqua()
{
//获取文档
CBitmapDoc*pDoc=GetDocument();
//指向DIB的指针
LPSTRlpDIB;
//指向DIB象素指针
LPSTRlpDIBBits;
//锁定DIB
lpDIB=(LPSTR):
GlobalLock((HGLOBAL)pDoc->
GetHDIB());
//找到DIB图像象素起始位置
lpDIBBits=:
FindDIBBits(lpDIB);
//判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的直方图均衡,其它的可以类推)
if(:
DIBNumColors(lpDIB)!
=256)
{
//提示用户
MessageBox("
目前只支持256色位图的直方图均衡!
"
"
系统提示"
MB_ICONINFORMATION|MB_OK);
//解除锁定
:
GlobalUnlock((HGLOBAL)pDoc->
//返回
return;
}
//更改光标形状
BeginWaitCursor();
//调用InteEqualize()函数进行直方图均衡
InteEqualize(lpDIBBits,:
DIBWidth(lpDIB),:
DIBHeight(lpDIB));
//设置脏标记
pDoc->
SetModifiedFlag(TRUE);
//更新视图
UpdateAllViews(NULL);
//解除锁定
:
//恢复光标
EndWaitCursor();
}
/********************************************************************
*函数名称:
*InteEqualize()
*
*参数:
*LPSTRlpDIBBits-指向源DIB图像指针
*LONGlWidth-源图像宽度(象素数)
*LONGlHeight-源图像高度(象素数)
*返回值:
*BOOL-成功返回TRUE,否则返回FALSE。
*说明:
*该函数用来对图像进行直方图均衡。
************************************************************************/
BOOLWINAPIInteEqualize(LPSTRlpDIBBits,LONGlWidth,LONGlHeight)
{//指向源图像的指针
unsignedchar*lpSrc;
//临时变量
LONGlTemp;
//循环变量
LONGi;
LONGj;
//灰度映射表
BYTEbMap[256];
LONGlCount[256];
//图像每行的字节数
LONGlLineBytes;
//计算图像每行的字节数
lLineBytes=WIDTHBYTES(lWidth*8);
//重置计数为0
for(i=0;
i<
256;
i++)
//清零
lCount[i]=0;
//计算各个灰度值的计数
lHeight;
for(j=0;
j<
lWidth;
j++)
{
lpSrc=(unsignedchar*)lpDIBBits+lLineBytes*i+j;
//计数加1
lCount[*(lpSrc)]++;
}
//计算灰度映射表
i++)
{//初始为0
lTemp=0;
=i;
j++)
lTemp+=lCount[j];
}//计算对应的新灰度值
bMap[i]=(BYTE)(lTemp*255/lHeight/lWidth);
//每行
for(i=0;
{//每列
for(j=0;
//指向DIB第i行,第j个象素的指针
lpSrc=(unsignedchar*)lpDIBBits+lLineBytes*(lHeight-1-i)+j;
//计算新的灰度值
*lpSrc=bMap[*lpSrc];
}//返回
returnTRUE;
3.2直方图均衡化过程实现步骤
根据BMP图像文件的基本格式,利用VC编写8bits无压缩BMP图像文件的打开和存储的程序;
编写对灰度图像进行直方图统计的程序,并将结果显示在屏幕上。
1、总体流程图
2、参考步骤和程序
打开VC程序——文件——新建——工程中的MFCAppWizard(exe),在工程下面的框中输入工程名(假定工程名为111),点确定——选多重文档,点下一个——后面都点下一个直到完成确定,基本框架就完成了,下面就加代码。
这时VC界面上左边框的下面有三个按钮:
ClassView、ResourceView和FileView,ClassView里面是工程111的类:
CAdoutDlg、CChildFrame、CMy111App、CMy111Doc、CMy111View和Globals;
点ResourceView里面是资源类:
Accelerator、Dialog、Icon、Menu、StringTable、Toolbar和Version;
点开FileView里面是文件类:
SourceFile、HeaderFiles、ResourceFiles和ReadMe.txt。
点界面的“工程”按钮——添加工程——新建——选C++SourceFile,在文件下面的框里输入文件名(如DIBAPI),点“结束”,这样在FileView中的SourceFiles里面就多了一个DIBAPI.cpp文件,所有的代码都加在该文件中。
再点界面的“工程”按钮——添加工程——新建——选C/C++HeaderFile,在文件下面的框里输入文件名(和前面的文件名必须一致),点“结束”,这样在FileView中的HeaderFiles里面就多了一个DIBAPI.h文件,该文件是DIBAPI.cpp的头文件。
点开DIBAPI.h文件,里面是空白的,把如下代码考入文件中:
//DIBAPI.h
#ifndef_INC_DIBAPI
#define_INC_DIBAPI
DECLARE_HANDLE(HDIB);
#definePALVERSION0x300
#defineIS_WIN30_DIB(lpbi)((*(LPDWORD)(lpbi))==sizeof(BITMAPINFOHEADER))
#defineRECTWIDTH(lpRect)((lpRect)->
right-(lpRect)->
left)
#defineRECTHEIGHT(lpRect)((lpRect)->
bottom-(lpRect)->
top)
#defineWIDTHBYTES(bits)(((bits)+31)/32*4)
#defineDIB_HEADER_MARKER((WORD)('
M'
<
8)|'
B'
)
BOOLWINAPIPaintDIB(HDC,LPRECT,HDIB,LPRECT,CPalette*pPal);
BOOLWINAPICreateDIBPalette(HDIBhDIB,CPalette*cPal);
LPSTRWINAPIFindDIBBits(LPSTRlpbi);
DWORDWINAPIDIBWidth(LPSTRlpDIB);
DWORDWINAPIDIBHeight(LPSTRlpDIB);
WORDWINAPIPaletteSize(LPSTRlpbi);
WORDWINAPIDIBNumColors(LPSTRlpbi);
HGLOBALWINAPICopyHandle(HGLOBALh);
BOOLWINAPISaveDIB(HDIBhDib,CFile&
file);
HDIBWINAPIReadDIBFile(CFile&
//在此处输入自己的函数声明
#endif//!
_INC_DIBAPI
上面这些函数是实现图像的读取、存储等图像处理的基本功能的,你将自己需要的函数也输入到“//在此处输入自己的函数声明”的下面。
点开DIBAPI.cpp文件,里面是空白的,将如下代码加入其中:
//DIBAPI.cpp
#include"
stdafx.h"
DIBAPI.h"
WORDWINAPIDIBNumColors(LPSTRlpbi)
WORDwBitCount;
if(IS_WIN30_DIB(lpbi))
DWORDdwClrUsed;
dwClrUsed=((LPBITMAPINFOHEADER)lpbi)->
biClrUsed;
if(dwClrUsed)
return(WORD)dwClrUsed;
wBitCount=((LPBITMAPINFOHEADER)lpbi)->
biBitCount;
else
wBitCount=((LPBITMAPCOREHEADER)lpbi)->
bcBitCount;
switch(wBitCount)
case1:
return2;
case4:
return16;
case8:
return256;
default:
return0;
WORDWINAPIPaletteSize(LPSTRlpbi)
return(WORD)(DIBNumColors(lpbi)*sizeof(RGBQUAD));
return(WORD)(DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
LPSTRWINAPIFindDIBBits(LPSTRlpbi)
return(lpbi+*(LPDWORD)lpbi+:
PaletteSize(lpbi));
DWORDWINAPIDIBWidth(LPSTRlpDIB)
LPBITMAPINFOHEADERlpbmi;
LPBITMAPCOREHEADERlpbmc;
lpbmi=(LPBITMAPINFOHEADER)lpDIB;
lpbmc=(LPBITMAPCOREHEADER)lpDIB;
if(IS_WIN30_DIB(lpDIB))
returnlpbmi->
biWidth;
return(DWORD)lpbmc->
bcWidth;
DWORDWINAPIDIBHeight(LPSTRlpDIB)
biHeight;
bcHeight;
BOOLWINAPIPaintDIB(HDChDC,LPRECTlpDCRect,HDIBhDIB,LPRECTlpDIBRect,CPalette*pPal)
LPSTRlpDIBHdr;
BOOLbSuccess=FALSE;
HPALETTEhPal=NULL;
HPALETTEhOldPal=NULL;
if(hDIB==NULL)
returnFALSE;
lpDIBHdr=(LPSTR):
GlobalLock((HGLOBAL)hDIB);
lpDIBBits=FindDIBBits(lpDIBHdr);
if(pPal!
=NULL)
hPal=(HPALETTE)pPal->
m_hObject;
hOldPal=:
SelectPalette(hDC,hPal,TRUE);
SetStretchBltMode(hDC,COLORONCOLOR);
if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&
&
(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect)))
bSuccess=:
SetDIBitsToDevice(hDC,lpDCRect->
left,lpDCRect->
top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),lpDIBRect->
left,\
(int)DIBHeight(lpDIBHdr)-lpDIBRect->
top-RECTHEIGHT(lpDIBRect),0,(WORD)DIBHeight(lpDIBHdr),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
StretchDIBits(hDC,lpDCRect->
lpDIBRect->
top,RECTWIDTH(lpDIBRect),RECTHEIGHT(lpDIBRect),\
lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
GlobalUnlock((HGLOBAL)hDIB);
if(hOldPal)
SelectPalette(hDC,hOldPal,TRUE);
GlobalUnlock(hDIB);
returnbSuccess;
BOOLWINAPICreateDIBPalette(HDIBhDIB,CPalette*pPal)
LPLOGPALETTElpPal;
HANDLEhLogPal;
LPSTRlpbi;
LPBITMAPINFOlpbmi;
LPBITMAPCOREINFOlpbmc;
BOOLbWinStyleDIB;
inti;
WORDwNumColors;
BOOLbResult=FALSE;
lpbi=(LPSTR):
lpbmi=(LPBITMAPINFO)lpbi;
lpbmc=(LPBITMAPCOREINFO)lpbi;
wNumColors=DIBNumColors(lpbi);
bWinStyleDIB=IS_WIN30_DIB(lpbi);
if(wNumColors!
=0)
hLogPal=:
GlobalAlloc(GHND,sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
if(hLogPal==0)
:
returnFALSE;
lpPal=(LPLOGPALETTE)