图像处理课程设计.docx
《图像处理课程设计.docx》由会员分享,可在线阅读,更多相关《图像处理课程设计.docx(27页珍藏版)》请在冰豆网上搜索。
![图像处理课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/21/537aef66-98d6-41e9-807d-fdb0ec19e122/537aef66-98d6-41e9-807d-fdb0ec19e1221.gif)
图像处理课程设计
课程设计报告
课程名称数字图像处理
课题名称图像特征提取软件设计
专业
班级
学号
姓名
指导教师
2011年1月20日
湖南工程学院
课程设计任务书
课程名称数字图像处理
课题图像特征提取软件设计
专业班级计算机0781
学生姓名
学号
指导老师刘长松
审批
任务书下达日期2011年1月5日
任务完成日期2011年1月20日
一、设计内容与设计要求
1.设计内容
(1)图像分割、边缘检测、边界跟踪、模板匹配、几何形状特征等图像特征提取方法集成为一个完整的图像特征提取软件。
(2)针对一幅人脸图像,利用所设计的软件实现人脸特征的提取(瞳孔中心、鼻孔、鼻尖、嘴角等特征点的抽取,以及嘴形轮廓、头部轮廓的提取等);
2.设计要求
1)总体要求
(1)充分认识课程设计的重要性,认真做好准备工作,尤其是对编程软件的使用有基本的认识。
(2)虚心接受老师的指导,充分发挥主观能动性。
结合课题,独立思考,努力钻研,勤于实践,勇于创新。
(3)独立按时完成规定的工作任务,不得弄虚作假,不准抄袭他人内容。
2)实施要求
(1)理解各种图像处理方法确切意义。
(2)独立进行方案的制定,系统结构设计要合理。
(3)在程序开发时,则必须清楚主要实现函数的目的和作用,需要在程序书写时说明做适当的注释。
在写课设报告时,必须要将主要函数的功能和参数做详细的说明。
(4)通过多幅不同形式的图像来检测该系统的稳定性和正确性。
3)课程设计报告的内容及要求
在完成课题验收后,学生应在规定的时间内完成课程设计报告一份(不少于2000字)。
二、进度安排
第19周星期一8时:
00分——12时:
00分
星期二8时:
00分——12时:
00分
星期三8时:
30分——12时:
00分
星期四14时:
00分——18时:
00分
星期五14时:
00分——18时:
00分
第20周星期一8时:
00分——12时:
00分
附:
课程设计报告装订顺序:
封面、任务书、目录、正文、评分表、附件(A4大小的图纸及程序清单)。
正文的格式:
一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。
正文的内容:
一、课题的主要功能;二、课题的功能模块的划分(要求画出模块图);三、主要功能的实现(至少要有一个主要模块的流程图);四、程序调试;五、总结;六、附件(所有程序的原代码,要求对程序写出必要的注释)。
正文总字数要求在5000字以上(不含程序原代码)。
一、课题的主要功能
1、图像获取功能:
该模块主要是从摄像头拍照后进行获取图片,也可以从图片库中获取,获取后的图片可以在软件的界面中显示出来。
2、图像预处理功能:
该模块主要包括图像光线补偿、图像变成灰色、高斯平滑、均衡直方图、实现图像对比度增强、二值化变换等。
3、人脸定位功能:
该模块主要是将处理后的人脸图片进行定位,将眼睛、鼻子、嘴巴标记出来,以便进行特征提取。
4、特征提取功能:
该模块是在定位后的人脸图片中将眼睛、鼻子、嘴巴的特征值提取出来。
2、课题的功能模块的划分
一、功能模块流程图
图2.1
二、各模块的功能
1、图像获取模块
该模块主要是从摄像头拍照后进行获取图片,也可以从图片库中获取,获取后的图片可以在软件的界面中显示出来以便进行识别。
2、人脸区域获取
该系统中图像里人脸区域的获取,主要是根据肤色来进行获取,通过肤色非线形分段色彩变换来实现。
这一非线性分段色彩变换得到的肤色模型属于色彩空间中的聚类模型,这一类肤色模型的建立首先要选取一种合适的色彩空间。
3、图像预处理模块
图像预处理就是对获取得来的图像进行适当的处理,使它具有的特征能够在图像中明显的表现出来。
该模块中的子模块有如下5个,下面对它们进行概述:
·光线补偿[3]
因为系统得到的图片可能会存在光线不平衡的情况,这会影响我们对特征的提取,同时系统中要用到YcrCB色彩空间,所以有必要对图像进行光线补偿。
尽可能将它的特征在图像中表现出来。
YcrCB是一种色彩空间,它用于视频系统中,在该色彩空间中,Y分量表示像素的亮度,Cr表示红色分量,Cb表示蓝色分量,通常把Cr和Cb称为色度。
YcrCB色彩空间是以演播室质量标准为目标的CC601编码方案中采用的彩色表示模型。
·灰度变化[4]
图像灰度化的过程就是把彩色图像转换为黑白色图像的过程,它也是为了将图像的信息更加具体、简单的表现出来,但是,这样做也将会丢失图像信息。
因此,尽可能在转化的过程中用简单的方式表现图像复杂的信息。
·高斯平滑处理[5]
高斯平滑将对图像进行平滑处理,在图像采集过程中,由于各种因素的影响,图像往往会出现一些不规则的噪声,入图像在传输、存储等都有可能产生数据的丢失。
从而影响图像的质量。
处理噪声的过程称为平滑。
平滑可以降低图像的视觉噪声,同时出去图像中的高频部分后,那些本来不明显的低频成分更容易识别。
平滑可以通过卷积来实现。
经过卷积平滑后的水平投影后,二值化提供了较好的图像效果。
·对比度增强[6]
对比度增强,就是对图像的进一步处理,将对比度再一次拉开。
它针对原始图像的每一个像素直接对其灰度进行处理的,其处理过程主要是通过增强函数对像素的灰度级进行运算并将运算结果作为该像素的新灰度值来实现的。
通过改变选用的增强函数的解析表达式就可以得到不同的处理效果。
·二值化[7]
二值化的目的是将采集获得的多层次灰度图像处理成二值图像,以便于分析理解和识别并减少计算量。
二值化就是通过一些算法,通过一个阈值改变图像中的像素颜色,令整幅图像画面内仅有黑白二值,该图像一般由黑色区域和白色区域组成,可以用一个比特表示一个像素,“1”表示黑色,“0”表示白色,当然也可以倒过来表示,这种图像称之为二值图像。
这便有利于我们对特征的提取。
该设计中采用组内方差和组外方差来实现二值化。
·直方图均衡[8]
直方图均衡化的目的是使一输入图像转换为在每一灰度级上都有相同的象素点数,它的处理的中心思想是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布,它的研究思路是:
通过直方图变换式来进行直方图的均衡处理,直方图变换式是
但是直方图均衡化存在着两个缺点:
1)变换后图像的灰度级减少,某些细节消失;
2)某些图像,如直方图有高峰,经处理后对比度不自然的过分增强。
4、人脸定位模块
人脸定位是将典型的脸部特征(如眼睛,鼻尖,嘴唇等等)标记出来,在本系统中,定位的特征是眼睛,鼻尖和嘴巴三个。
由于眼睛具有对称性,因此可以很快就能标记出来,而鼻子是在眼睛下面,且嘴巴在鼻子下面,所以只要眼睛标记好,鼻子和嘴巴也能相应的标记出来。
5、特征提取模块
特征提取按以下4个步骤进行:
(1)、提取两只眼睛的距离
(2)、眼睛的倾角度
(3)、眼睛、嘴巴的重心
(4)、用一个矩形标出每一个特征
在特征提取完之后将会得到相应的特征值以便存入后台数据库。
三、主要功能的实现
1、Gabor变换人脸提取特征的流程图
图3.1
2、功能的实现
1、光线补偿
光线补偿功能实质上是用上段代码中的LightingCompensate()函数来进行实现。
函数LightingCompensate()是类DIB的一个成员函数。
其核心代码如下所述:
//下面的循环对图像进行光线补偿
for(i=0;ifor(intj=0;j{
//获取像素偏移
lOffset=this->PixelOffset(i,j,wBytesPerLine);
//得到蓝色分量
*(lpData+lOffset)=colorb;
//绿色分量
colorb=*(lpData+lOffset+1);
colorb*=co;
if(colorb>255)
colorb=255;
*(lpData+lOffset+1)=colorb;
//红色分量
colorb=*(lpData+lOffset+2);
colorb*=co;
if(colorb>255)
colorb=255;
*(lpData+lOffset+2)=colorb;}
2、图像灰度化
①彩色转换成灰度
将彩色图像转化为灰阶图像常采用如下的经验式:
gray=0.39×R+0.50×G+0.11×B(式3)
其中,gray为灰度值,R、G、B分别为红色、绿色和蓝色分量值。
②灰度比例变换
灰度比例变换是把原像素的灰度乘以一个缩放因子,并最后截至[0,255]。
③灰度线性变换
当图像由于成像时曝光不足或曝光过度,会产生对比度不足的弊病,从而使图像中的细节分辨不清。
将图像灰度进行线性扩展,常能显著地改善图像的外观。
3、高斯平滑
1在类CFaceDetectView中添加“高斯平滑”菜单项的事件处理程序,其代码如下:
Template(tem,3,3,xishu);
Invalidate(TRUE);
其中tem是模板参数,xishu是模板系数;Template()函数是实现高斯平滑的主要函数,其核心代码是:
for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++)
{
for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++)
注:
将以点(i,j)为中心,与模板大小相同的范围内的象素与模板对用位置的系数进行相乘并线形叠加
sum+=Gray[m][n]*tem[(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)];
}
将结果乘上总的模板系数
sum=(int)sum*xishu;
计算绝对值
sum=fabs(sum);
如果小于0,强制赋值为0
if(sum<0)
sum=0;
如果大于255,强制赋值为255
if(sum>255)
sum=255;
HeightTemplate[i][j]=sum;
4、灰度均衡
在灰度均衡操作同样不需要改变DIB的调色板和文件夹,只要把指向DIB像素起始位置的指针和DIB高度、宽度信息传递给子函数就可以完成灰度均衡变换工作,其核心代码如下:
*(lpData+lOffset)=state;//显示灰度均衡
*(lpData+lOffset+1)=state;
*(lpData+lOffset+2)=state;
5、图像对比度增强
类CFaceDetectView中添加“实现图像对比度增强”菜单项的事件处理程序,其代码如下;
lOffset=gDib.PixelOffset(i,j,gwBytesPerLine);
获取图像灰度增强函数
intstate=IncreaseContrast(ZFT[k][k1],100);
显示灰度增强后的图像
*(lpData+lOffset)=state;
*(lpData+lOffset+1)=state;
*(lpData+lOffset+2)=state;
其中IncreaseContras()函数是实现图像对比度增强的关键函数,该根据参数n来调节对比度,n越大,对比越强烈,其核心是:
如果数据很小,设置为0
if(pByte<=Low)
return0;
获得中间数据,并进行对比增强处理
elseif((Lowreturnint(((pByte-Low)/Grad));
如果数据很大,设置为255
else
return255
四、程序调试
本系统主要由图像处理、人脸定位、特征提取三个部分组成,而图像处理对于后面的工作结果好坏起着至关重要的作用,因此从软件开发的最初阶段我们就要对软件进行不断的测试,对图像处理模块中的各个子模块进行测试以便检测经过处理后的图像效果是否达到预期的效果
图4.1编译成功
编译成功后进入操作界面:
图4..2运行界面
当输入的图片不符合规格时,程序会发出警告提示,终止程序的运行
图4.3错误提示
成功载入图片,准备进行图片的编辑:
图4.4载入图片
编译图片嘴角的匹配,勾勒出人物轮廓:
图脸部轮廓
五、总结
经过两个礼拜的课程设计,又重新温故了本学期数字图像处理的课本知识,同时锻炼了C++的编程能力。
面对着诸多的问题和考验,我一次又一次享受了难题解决前的困惑和难题解决后的兴奋。
两个星期的数字图像处理的课程设计在充满紧张的氛围中结束了,这次操作系统课程设计让我收获很多。
课程设计目的不仅是对所学知识的运用和扩展,也是在大学期间培养学生动手、分析问题和解决问题的能力。
通过这一周的课程设计实践让我重新温习了过去学过的知识。
通过资料的查询发现图像的处理方法很多,我们可以根据需要,有选择地使用各种方法。
在确定脸部区域上,通常使用的方法有肤色提取。
肤色提取,则对脸部区域的获取则比较准确,成功率达到95%以上,并且速度快,减少很多工作。
图像的亮度变化,由于图像的亮度在不同环境的当中,必然受到不同光线的影响,图像就变得太暗或太亮,我们就要对它的亮度进行调整,主要采取的措施是对图像进行光线补偿。
进行灰度处理,我们要保证图像信息尽可能少的丢失。
在图像的采集过程中,由于各种因素的影响,图像中往往会出现一些不规则的随机噪声,如数据在传输、存储时发生的数据丢失和损坏等,这些都会影响图像的质量,因此需要将图片进行平滑操作以此来消除噪声。
同样在进行灰度变换前,我们也要对图像的信息进行统计,找出一个比较合理的灰度值,才能进行灰度变换。
灰度变换后,就要进行灰度均衡,可以根据灰度分布来进行灰度均衡。
对于这次的课程设计,我们最重要的不是学会如何去编程,如何去实现算法,更重要的是我们学会怎样通过自己去查阅资料掌握我们要懂的知识,学会自己分析,学会自己独立去研究。
提高我们自学的能力,使我们即使有一天出去社会,没有老师在身边,也可以自己独立去研究我们的专业知识。
六、附录
#include"stdafx.h"
#include"DIB.h"
#include"math.h"#defineWIDTHBYTES(bits)((bits+31)/32*4)
#defineRECTWIDTH(x)(x->right-x->left)
#defineRECTHEIGHT(x)(x->bottom-x->top)
#defineTHRESHOLDCONTRAST40
#ifdef_DEBUG
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#definenewDEBUG_NEW
#endif
#definePI3.1415926
externintlocax,locay;
#definem_WIDTH600
#definem_HEIGHT600
HDIBDIB:
:
ReadDIBFile(HANDLEhFile)
{
BITMAPFILEHEADERbmfHeader;
DWORDdwBitsSize;
HANDLEhDIB;
HANDLEhDIBtmp;
LPBITMAPINFOHEADERlpbi;
DWORDdwRead;
//得到文件大小
dwBitsSize=GetFileSize(hFile,NULL);
hDIB=GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));
if(!
hDIB)
returnNULL;
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
if(!
lpbi)
{
GlobalFree(hDIB);
returnNULL;
}
if(!
ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
gotoErrExit;
if(sizeof(BITMAPFILEHEADER)!
=dwRead)//读取文件出错
gotoErrExit;
if(bmfHeader.bfType!
=0x4d42)//文件类型不匹配
gotoErrExit;
if(!
ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
gotoErrExit;
if(sizeof(BITMAPINFOHEADER)!
=dwRead)//读取数据出错
gotoErrExit;
GlobalUnlock(hDIB);
if(lpbi->biSizeImage==0)
lpbi->biSizeImage=(this->BytePerLine(hDIB))*lpbi->biHeight;
hDIBtmp=GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
if(!
hDIBtmp)
gotoErrExitNoUnlock;
else
hDIB=hDIBtmp;
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
//根据情况设定文件指针
if(bmfHeader.bfOffBits!
=0L)
SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
//读取文件的象素颜色数据
if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
gotoOKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitNoUnlock:
GlobalFree(hDIB);//释放内存
returnNULL;
OKExit:
GlobalUnlock(hDIB);
returnhDIB;
}
HDIBDIB:
:
ToGray(HANDLEhDIB)
{
HDIBhNewDIB=NULL;
LPBITMAPINFOHEADERlpSrc,lpDest;
LPBYTElpS,lpD;
DWORDdwBytesPerLine;
DWORDdwImgSize;
WORDwBytesPerLine;
unsignedi,j,height,width;
if(!
hDIB)
returnNULL;
lpSrc=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
dwBytesPerLine=WIDTHBYTES(24*(lpSrc->biWidth));
dwImgSize=lpSrc->biHeight*dwBytesPerLine;
//申请新的内存,大小等于原来图象的大小
hNewDIB=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);
lpDest=(LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
//保存图片的长宽、颜色深度等信息
memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
DWORDdwSBytesPerLine;
dwSBytesPerLine=(24*(lpSrc->biWidth)+31)/32*4;
height=lpDest->biHeight;
width=lpDest->biWidth;
lpS=(LPBYTE)lpSrc;
wBytesPerLine=this->BytePerLine(hDIB);
lpD=(LPBYTE)lpDest;
lpS=lpS+sizeof(BITMAPINFOHEADER);
lpD=lpD+sizeof(BITMAPINFOHEADER);
unsignedr,g,b,gray;
//扫描整个图片,实现灰度化
for(i=0;i{
for(j=0;j<(unsigned)lpDest->biWidth;j++)
{
//获得原来图片的颜色值
r=*(lpS++);
g=*(lpS++);
b=*(lpS++);
//计算灰度值
gray=(g*50+r*39+b*11)/100;
//保存灰度值到目标图片
*(lpD++)=gray;
*(lpD++)=gray;
*(lpD++)=gray;
}
//处理四字节对齐问题
unsignedk;
for(k=0;kbiWidth*3;k++)
{
lpS++;
lpD++;
}
}
GlobalUnlock(hDIB);
GlobalUnlock(hNewDIB);
returnhNewDIB;
}
voidDIB:
:
FaceLocate(HANDLEhDIB,CRectfaceLocation[10],int&faceNum)
{
HANDLEhDIBTemp;
//保存当前数据
hDIBTemp=this->CopyHandle(hDIB);
LPBITMAPINFOHEADERlpbi;
LPBYTElpData;
WORDwBytesPerLine;
intheight;
intwidth;
longlOffset;
//得到图象的基本信息
lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
height=lpbi->biHeight;
width=lpbi->biWidth;
lpD