现代图像处理技术相关算法.docx
《现代图像处理技术相关算法.docx》由会员分享,可在线阅读,更多相关《现代图像处理技术相关算法.docx(56页珍藏版)》请在冰豆网上搜索。
现代图像处理技术相关算法
广东工业大学研究生考试答题纸
课程名称:
现代图像处理技术试卷满分100分
考试时间:
年月日(第周星期)
题号
一
二
三
四
五
六
七
八
九
十
总分
评卷得分
评卷签名
说明:
以写小论文、报告等形式的考查课不必用此页答题纸,直接在试题上判分(请教师出题时把此说明删除!
)。
1、程序概述
图像处理(imageprocessing),即用计算机对图像进行分析,以达到所需结果的技术。
图像处理往往指的是指数字图像处理,其中数字图像指的是用数字摄像机、扫描仪等设备经过采样和量化后得到的一个用来再现图片信息的一个点阵。
而数字图像处理技术的内容涵盖了图像数字化、图像编码、图像增强、图像复原、图像分割和图像分析等各个领域。
本程序采用MicrosoftVisualC++6.0语言编写,配合了附加的更新补丁MicrosoftPlatformSDKFebruary2003开发包,以及在工程中内嵌的CImage图像处理类进行开发,编译时也可选择用MicrosoftVisualStudio2010或以上版本进行项目的自动转换和编译。
这个程序的功能包括了图像的空域上和频域上的增强、空域和频域之间的变换、形态学的一些计算,以及一些有关图像分割的算法,另外包括了笔刷绘图和对话框输入的功能。
2、图像的空域增强
2.1图像的指数变换
图像的指数变换是关于图像每个点的一种非线性的变换,其功能是将图像整体变暗,并强化图像的明亮区域。
其计算方法是将图像的颜色取值压缩并平移到[-1,1]后取以e为底的乘方,然后乘以255.0/e,代码如下:
voidCImageProcessingView:
:
OnPower()
{
//TODO:
Addyourcommandhandlercodehere
//图像的指数变换
inti,j;//循环变量
BYTE*mByte;//主图像某点像素的颜色数组,顺序是蓝、绿、红(BYTE是无符号8位整数)
doublee=2.718281828;
intr=0,g=0,b=0;//rgb颜色值和uv颜色值
for(j=0;jfor(i=0;i//将图像的颜色取值压缩并平移到[-1,1]后取以e为底的乘方,然后乘以255.0/e
mByte=(BYTE*)m_Image.GetPixelAddress(i,j);//获取(i,j)位置的主图像像素
数组
r=(int)(exp(mByte[2]/127.5-1.0)*255.0/e);
g=(int)(exp(mByte[1]/127.5-1.0)*255.0/e);
b=(int)(exp(mByte[0]/127.5-1.0)*255.0/e);
//值溢出时取边界值
if(r<0){
r=0;
}
if(r>255){
r=255;
}
if(g<0){
g=0;
}
if(g>255){
g=255;
}
if(b<0){
b=0;
}
if(b>255){
b=255;
}
//应用新的颜色值
mByte[2]=r;
mByte[1]=g;
mByte[0]=b;
}
}
recordUndo();//备份当前图片,以供撤销操作
preshow=false;//显示的是主图片
tempshow=false;
Invalidate();//刷新屏幕
}
运行效果如下图所示:
应用前应用后
2.2图像的对数变换
图像的对数变换与其指数变换相反,可以将图像整体变亮,并强化图像暗的部分,算法是将图像的颜色取值压缩到[0,e](小于1/e的部分的部分按1/e算)后取对数变成[-1,1],然后整体加1,再重新放大到[0,255],如下代码:
voidCImageProcessingView:
:
OnLogarithm()
{
//TODO:
Addyourcommandhandlercodehere
//图像的对数变换
inti,j;//循环变量
BYTE*mByte;//主图像某点像素的颜色数组,顺序是蓝、绿、红(BYTE是无符号8位
整数)
doublee=2.718281828;
intr=0,g=0,b=0;//rgb颜色值和uv颜色值
for(j=0;jfor(i=0;i//将图像的颜色取值压缩到[0,e](小于1/e的部分的部分按1/e算)后取对数变成[-1,1],然后整体加1,再重新放大到[0,255]
mByte=(BYTE*)m_Image.GetPixelAddress(i,j);//获取(i,j)位置的主图像像素数组
r=mByte[2]==0?
0:
(int)((log(mByte[2]*e/255.0)+1.0)*127.5+0.5);
g=mByte[1]==0?
0:
(int)((log(mByte[1]*e/255.0)+1.0)*127.5+0.5);
b=mByte[0]==0?
0:
(int)((log(mByte[0]*e/255.0)+1.0)*127.5+0.5);
//值溢出时取边界值
if(r<0){
r=0;
}
if(r>255){
r=255;
}
if(g<0){
g=0;
}
if(g>255){
g=255;
}
if(b<0){
b=0;
}
if(b>255){
b=255;
}
//应用新的颜色值
mByte[2]=r;
mByte[1]=g;
mByte[0]=b;
}
}
recordUndo();//备份当前图片,以供撤销操作
preshow=false;//显示的是主图片
tempshow=false;
Invalidate();//刷新屏幕
}
处理结果:
应用前应用后
2.3图像的直方图均衡化
直方图均衡化处理的目的就是对图像的每个点的像素亮度进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。
通过这种方法,亮度可以更好地在直方图上分布。
这样就可以用于增强局部的对比度而不影响整体的对比度。
这个运算首先需要统计各种颜色出现的频率的直方图,由于原图片往往是彩色图片,事实上,对彩色分量rgb分别做均衡化,会产生奇异的点,图像不和谐。
一般采用的是用yuv空间进行亮度的均衡即可。
所以,这里也仅统计了yuv空间中的y值的直方图:
int*CImageProcessingView:
:
statZft(){
//计算各亮度(yuv中的y值)出现次数的直方图
//全局变量intzft[255]已定义,表示各个亮度的出现次数的直方图
//其中Y=0.30R+0.59G+0.11B,U=0.493(B-Y),V=0.877(R-Y)
inti,j;//循环变量
BYTE*mByte;//主图像某点像素的颜色数组,顺序是蓝、绿、红(BYTE是无符号8位
整数)
for(i=0;i<256;i++){
zft[i]=0;
}
intbrightness;//yuv中的y值
for(j=0;jfor(i=0;imByte=(BYTE*)m_Image.GetPixelAddress(i,j);//获取(i,j)位置的主图
像像素数组
brightness=(mByte[0]*114+mByte[1]*587+mByte[2]*299)/1000;//从红绿
蓝信息中获取yuv中的y(亮度)值信息
if(brightness<0||brightness>255){
continue;
}
zft[brightness]++;
}
}
returnzft;//返回统计数组
}
要将这个直方图显示出来,需要求出zft数组的最大值zmax,然后每条的高度h=zft[i]*hmax/zmax,这里的zft[i]表示某个亮度出现的次数,hmax表示的是能够显示的最大高度,直方图的显示结果如下图(左端表示0,右端表示255):
要使得这个直方图分布变得可以均匀地分布在0-255的范围内,需要统计zft[i]数组的前n项和cdf[i],即颜色亮度值(y值)的累计分布,然后利用这个公式
即可根据某个点的原始亮度计算出它均衡化后的亮度h(v),其中cdf(v)表示的是某个量度v的累计次数分布,累积分布函数最小值cdfmin表示的是cdf数组中的最小的非零值,M和N分别代表了图像的长宽像素个数,而L则是灰度级数(如本例中,图像的y值为8位深度,则灰度级数共有2^8=256级数)。
具体的实现代码如下:
voidCImageProcessingView:
:
OnZftpj()
{
//TODO:
Addyourcommandhandlercodehere
//直方图均衡化
CZFTDialogdlg;//对话框显示颜色亮度值频率分布直方图
dlg.newTitle="直方图均衡化";
if(dlg.DoModal()!
=IDOK){
return;
}
intcdf[256];//颜色亮度值(y值)的累计分布直方图
inti=0,j=0;//循环变量
intr=0,g=0,b=0,y=0,u=0,v=0;//rgb颜色值和uv颜色值
intrate=0;//比率
BYTE*mByte;//主图像某点像素的颜色数组,顺序是蓝、绿、红(BYTE是无符号8位
整数)
cdf[0]=zft[0];//计算颜色亮度值累计分布直方图的第一个值
intcdfmin=0;//累计分布直方图非零数
for(j=1;j<256;j++){//计算累计分布直方图
cdf[j]=cdf[j-1]+zft[j];
if(cdfmin==0&&cdf[j]!
=0){
cdfmin=cdf[j];
}
}
if(cdfmin>=wid*hei){//在图片只有一个颜色的情况下不处理
return;
}
for(j=0;jfor(i=0;i//按公式计算出新的亮度值
mByte=(BYTE*)m_Image.GetPixelAddress(i,j);//获取(i,j)位置的主图
像像素数组
r=mByte[2];
g=mByte[1];
b=mByte[0];
y=(int)(255*(cdf[y]-cdfmin)/(double)(wid*hei-cdfmin)+0.5);
u=493*(b-y)