数字图像处理上机报告.docx
《数字图像处理上机报告.docx》由会员分享,可在线阅读,更多相关《数字图像处理上机报告.docx(57页珍藏版)》请在冰豆网上搜索。
![数字图像处理上机报告.docx](https://file1.bdocx.com/fileroot1/2023-6/9/a07c4e33-7263-4671-93c3-3a86f49107b1/a07c4e33-7263-4671-93c3-3a86f49107b11.gif)
数字图像处理上机报告
昆明理工大学
数字图像处理实验综合报告
学号:
姓名:
指导教师:
桂进斌
实验一、bmp位图的读取与显示
一、实验目的:
1、在visual2010下使用C语言编写读取bmp图像数据并显示的对话框。
二、实验原理:
1、bmp图像概述:
BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:
设备相关位图(DDB)和设备无关位图(DIB),使用非常广。
它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。
BMP文件的图像深度可选lbit、4bit、8bit及24bit。
BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。
由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。
2、bmp图像组成:
(1)位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;
(2)位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
(3)调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
(4)位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
三、实验内容以及实验步骤:
1、实验内容:
编写读取bmp图像数据并显示的MFC框架。
2、实验步骤:
(1)生成一名为dip(学生使用自己的名字)的基于MFC的应用程序框架:
选择file菜单new选项,在打开的窗口中选择project选项,选中MFC。
并在projectname输入dip,选择存放project的位置;
(2)在应用程序中加入具体的函数和变量:
a、在CdipView.h中加入如入变量:
public:
intm_x;
HBITMAPm_Bmp;
LPVOIDm_ColorList;
LPBYTEm_Image;
LPBITMAPINFOHEADERm_DibHead;
enumallocate{None,crtallocate,heapallocate};
allocatem_nBmpallocate;
allocatem_nImageallocate;
DWORDm_ImageSize;
intm_nPalette;
HANDLEm_hFile;
HANDLEm_hMap;
LPVOIDm_lpvFile;
HPALETTEm_hPalette;
HGLOBALm_hGlob;
利用ClassWizard向CdipView类中加入如下成员函数。
voidzftjh(unsignedchar*lpDib,longlWidth,longlHeight);
voidSetPaletteSize(intnBitCount);
voidClear();
BOOLReadFile(CFile*pFile);
BOOLSetPalette();
BOOLGetPalette();
BOOLDibToDC(CDC*pDC,CSizesize);
BOOLMemToDib(LPVOIDlmem);
CSizeGetDibSize();
b、利用资源编辑器,在主菜单中添加消息响应函数OnFileOpen(),具体方法为打开管理窗口,在资源栏中展开资源文件,选择menu并打开,双击“IDR_MAINFRAME”,选择“文件”菜单下“打开”子菜单,右击在快捷菜单中选择“添加事件处理程序”,选择“CDipView类”,添加消息响应函数,单击“编辑”,并加入如下代码:
CFileDialogfiledlg(TRUE,"bmp","*.bmp");
if(filedlg.DoModal()!
=IDOK)
return;
CFilemyfile;
myfile.Open(filedlg.GetPathName(),CFile:
:
modeRead);
if(ReadFile(&myfile)==TRUE)
Invalidate();
SetPalette();
c、修改OnDraw()函数,添加如下代码:
BeginWaitCursor();
CSizeDibSize=GetDibSize();
DibSize.cx*=m_x;
DibSize.cy*=-m_x;
DibToDC(pDC,DibSize);
EndWaitCursor();
d、在CDipView类的构造函数中加入:
m_Image=NULL;
m_DibHead=NULL;
e、在初始化函数OnInitialUpdate()中加入如下代码替换原来的代码:
•m_x=25;
•CSizeMaxSize(24000,32000);
•CSizeMinSize(MaxSize.cx/100,MaxSize.cy/100);
•SetScrollSizes(MM_HIMETRIC,MaxSize,MaxSize,MinSize);
(3)运行程序,观察实验结果。
四、实验结果:
1、程序代码:
intm_x;
HBITMAPm_Bmp;
LPVOIDm_ColorList;
LPBYTEm_Image;
LPBITMAPINFOHEADERm_DibHead;
enumallocate{None,crtallocate,heapallocate};
allocatem_nBmpallocate;
allocatem_nImageallocate;
DWORDm_ImageSize;
intm_nPalette;
HANDLEm_hFile;
HANDLEm_hMap;
LPVOIDm_lpvFile;
HPALETTEm_hPalette;
HGLOBALm_hGlob;
CSizeCDipView:
:
GetDibSize()
{
if(m_DibHead==NULL)
returnCSize(0,0);
returnCSize((int)m_DibHead->biWidth,(int)m_DibHead->biHeight);
}
BOOLCDipView:
:
MemToDib(LPVOIDlmem)
{
Clear();
m_DibHead=(LPBITMAPINFOHEADER)lmem;
SetPaletteSize(m_DibHead->biBitCount);
m_Image=(LPBYTE)m_ColorList+sizeof(RGBQUAD)*m_nPalette;
GetPalette();
returnTRUE;
}
BOOLCDipView:
:
DibToDC(CDC*pDC,CSizesize)
{
if(m_DibHead==NULL)
returnFALSE;
if(m_hPalette!
=NULL)
{
HDChdc=pDC->GetSafeHdc();
:
:
SelectPalette(hdc,m_hPalette,TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
:
:
StretchDIBits(pDC->GetSafeHdc(),0,0,size.cx,size.cy,
0,0,m_DibHead->biWidth,m_DibHead->biHeight,
m_Image,(LPBITMAPINFO)m_DibHead,DIB_RGB_COLORS,SRCCOPY);
returnTRUE;}
2、运行结果:
实验二、bmp位图的二值化与反色
一、实验目的:
1、理解图像的象素操作。
理解二值化与反色的本质。
二、实验原理:
1、图像的二值化的基本原理:
图像的二值化处理就是将图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。
即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
2、实现的方法:
图像二值化处理的方法包括全局阈值法、局部阈值法。
全局阈值法是指在二值化过程中只使用一个全局阈值T的方法。
它将图像的每个像素的灰度值与T进行比较,若大于T,则取为前景色(白色);否则,取为背景色。
典型的全局阈值法包括Otsu方法。
Otsu算法的设计思想:
设阀值将图像分割成两组,一组灰度对应目标,另一组灰度对应背景,则这两组灰度值的类内方差最小,两组的类间方差最大。
对图像设阈值将图像分割成两组,一组灰度对应目标,另一组灰度对应背景,则这两组灰度值的类内方差最小,两组的类间方差最大。
局部阈值法是用像素灰度值和此像素邻域的局部灰度特性来确定该像素的阈值的,当照明不均匀,有突发噪声,或者背景灰度变化较大时,局部阈值确定技术必须根据像素的坐标位置关系自动确定不同阈值,实施动态的自适应二值化处理。
比较典型的局部二值化算法有Bernsen方法。
Bersen算法的设计思想:
把灰度阈值选取为随像素位置变化而变化的函数,它是一种动态选择阈值的自适应方法。
3、图像的反色原理与实现:
对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。
如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理。
三、实验内容以及实验步骤:
1、实验内容:
编写程序实现bmp图像的二值化与反色。
2、实验步骤:
(1)根据实验一的结果,在开发环境下的资源编辑器中,在主菜单下添加一名为“点运算”的菜单。
并添加两个分别名为“二值化”与“反色”的子菜单项。
分别给它们名为“IDM_ERZH”、“IDM_FANCE”的ID;
(2)打开classwizard,分别为下述两菜单项加入相应的消息映射函数;
(3)在函数体中加入反色的实现代码;
(4)编写具体的功能代码并保存;
(5)运行程序,观察实验结果。
四、实验结果:
1、程序代码:
voidCLN3View:
:
OnFS()//反色
{
CClientDCdc(this);
CClientDC*pDC=&dc;
if(m_DibHead==NULL)
MessageBox("获取文件头失败!
","错误",MB_OK);
if(m_hPalette!
=NULL)
{
HDChdc=pDC->GetSafeHdc();
:
:
SelectPalette(hdc,m_hPalette,TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
intx=m_DibHead->biWidth;
inty=m_DibHead->biHeight;
unsignedchar*TmpBmp=newunsignedchar[m_ImageSize];
memset(TmpBmp,255,x*y);
chartemp;
for(inti=0;ifor(intj=0;j{
temp=m_Image[i*x*3+j];
TmpBmp[i*x*3+j]=255-temp;
}
//memcpy(m_Image,TmpBmp,x*y);
:
:
StretchDIBits(pDC->GetSafeHdc(),500,0,((400<=(m_DibHead->biWidth))?
400:
(m_DibHead->biWidth))
((400<=(m_DibHead->biHeight))?
400:
(m_DibHead->biHeight)),0,0,m_DibHead->biWidth,m_DibHead->biHeight,
TmpBmp,(LPBITMAPINFO)m_DibHead,DIB_RGB_COLORS,SRCCOPY);
delete[]TmpBmp;
TmpBmp=NULL;
}
2、运行结果:
五、实验结果分析:
算法可以得到比较理想的分割效果,分割效率也比较高,此法选出来的阈值比较稳定,分割质量有一定的保证,因而得到广泛的应用,是较为实用的全局二值化算法 ,Bersen 算法容易把背景本身当作两类来处理,此时用这种算法不能正确地分出前景和背景,改进的Bernsen算法是典型的局部二值化算法,分割效果比较清晰,可以把图像正确地二值化。
全局阈值法的优缺点:
全局阈值方法依然存在一些不足,主要表现在:
若目标与背景之间灰度差不明显,可能出现大块黑色区域,甚至丢失整幅图像的信息;仅利用一维灰度直方图分布,没有结合图像的空间相关信息,处理效果不好;当图像中有断裂现象或者背景有一定噪声时,无法得到预期效果,选择不同的初始灰度也会产生不一样的二值化图像。
局部阈值法的优缺点:
局部阈值法一般用于识别干扰比较严重、品质较差的图像,相对整体阈值方法有更广泛的应用,但也存在缺点和问题,如实现速度慢、不能保证图像连通性以及容易出现伪装现象等。
实验三、图像灰度变换
一、实验目的:
深入理解图像灰度变换的基本原理,学习编程实现图像灰度变换,并分析各种算法的效果。
二、实验原理:
1、灰度变换:
基于点操作的增强方法,它将每一个像素的灰度值按照一定的数学变换公式转换为一个新的灰度值,如增强处理中的对比度增强。
对比度增强可以采用线性拉伸和非线性拉伸。
线性拉伸可以将原始输入图像中的灰度值不加区别地扩展。
如果要求对局部扩展拉伸某一范围的灰度值,或对不同范围的灰度值进行不同的拉伸处理时,采用分段线性拉伸。
非线性拉伸常采用对数扩展和指数扩展。
对数扩展拉伸低亮度去,压缩高亮度区;指数扩展拉伸了高亮区,压缩了低亮度区。
2、线性灰度变换:
当图像由于成像时曝光不足或过度, 由于成像设备的非线性或图像记录设备动态范围太窄等因素, 都会产生对比度不足的弊病, 使图像中的细节分辨不清。
这时如将图像灰度线性扩展, 常能显著改善图像的主观质量。
在线性灰度变换中,灰度执照完全线性变换函数进行变换。
该线性灰度线性变换函数f ( r ) 是一个一维线性函数:
y(r)=k*r+b;分段线性灰度变换 ,为了突出感兴趣的目标或者灰度区间, 相对抑制那些不感兴趣的灰度区域, 可采用分段线性法。
常用的是三段线性变换。
分段线性变换称为图像直方图的拉伸, 它与完全线性变换类似, 其不同之处在于其变换函数是分段的。
3、非线性拉伸不是对图像的整个灰度范围进行扩展,而是有选择的对某一灰度范围进行扩展,其他范围的灰度值则有可能被压缩。
非线性拉伸在整个灰度值范围内采用统一的变换函数,利用变换函数的数学性质实现对不同灰度值区间的扩展与压缩。
当用某些非线性函数作为图像的映射函数时,可实现图像灰度的非线性变换, 如利用对数函数、指数函数等可实现对数变换和指数变换。
三、实验内容以及实验步骤:
1、实验内容:
学习编程实现图像灰度变换,并分析各种算法的效果。
2、实验步骤:
(1)打开菜单编辑器,在主菜单中添加一菜单项,选中弹出式选项,修改菜单名称为“灰度变换”。
然后建立一下级菜单,给菜单一个ID号,修改caption为“线性变换”,打开类向导,建立消息响应函数,实现图像灰度分段线性变换。
按照同样的办法实现图像对数变换和旋转变换。
(2)编写代码并保存。
(3)运行程序,观察实验结果。
四、实验结果:
1、程序代码:
(1)分段线性变换代码如下:
voidCLN3View:
:
OnXXBH()//线性变换
{
CClientDCdc(this);
CClientDC*pDC=&dc;
if(m_DibHead==NULL)
MessageBox("获取文件头失败!
","错误",MB_OK);
if(m_hPalette!
=NULL)
{
HDChdc=pDC->GetSafeHdc();
:
:
SelectPalette(hdc,m_hPalette,TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
intx=m_DibHead->biWidth;
inty=m_DibHead->biHeight;
unsignedchar*TmpBmp=newunsignedchar[m_ImageSize];
//for(y=0;y+y1//for(x=0;x+x1unsignedchartemp;inta1=1,a2=2,a3=3,a4=90;
for(inti=0;ifor(intj=0;j{
temp=m_Image[i*x*3+j];
if((temp*a1+10)>0&&(temp*a1+10)<50)
TmpBmp[i*x*3+j]=temp*a1+10;
if((temp*a2+10)>50&&(temp*a2+10)<100)
TmpBmp[i*x*3+j]=temp*a2+10;
if((temp*a3+10)>100&&(temp*a3+10)<180)
TmpBmp[i*x*3+j]=temp*a3+10;
if((temp*a4+10)>180&&(temp*a3+10)<255)
TmpBmp[i*x*3+j]=temp*a4+10;
else
TmpBmp[i*x*3+j]=255;
}
//memcpy(m_Image,TmpBmp,x*y);
:
:
StretchDIBits(pDC->GetSafeHdc(),500,0,((400<=(m_DibHead->biWidth))?
400:
(m_DibHead->biWidth))
((400<=(m_DibHead->biHeight))?
400:
(m_DibHead->biHeight)),0,0,m_DibHead->biWidth,m_DibHead->biHeight,
TmpBmp,(LPBITMAPINFO)m_DibHead,DIB_RGB_COLORS,SRCCOPY);
delete[]TmpBmp;
TmpBmp=NULL;
}
(2)对数变换代码如下:
voidCLN3View:
:
On32775()//对数变换
{
CClientDCdc(this);
CClientDC*pDC=&dc;
if(m_DibHead==NULL)
MessageBox("获取文件头失败!
","错误",MB_OK);
if(m_hPalette!
=NULL)
{
HDChdc=pDC->GetSafeHdc();
:
:
SelectPalette(hdc,m_hPalette,TRUE);
}
pDC->SetStretchBltMode(COLORONCOLOR);
intx=m_DibHead->biWidth;
inty=m_DibHead->biHeight;
unsignedchar*TmpBmp=newunsignedchar[m_ImageSize];
memset(TmpBmp,255,x*y);
chartemp;
floatt;
for(inti=0;ifor(intj=0;j{
temp=m_Image[i*x*3+j];
if(TmpBmp[i*x*3+j]>255)
TmpBmp[i*x*3+j]=255;
else
{
t=temp;
t=50*log(1+t);
TmpBmp[i*x*3+j]=(unsignedchar)(t);
}
}
//memcpy(m_Image,TmpBmp,x*y);
:
:
StretchDIBits(pDC->GetSafeHdc(),500,0,((400<=(m_DibHead->biWidth))?
400:
(m_DibHead->biWidth))
((400<=(m_DibHead->biHeight))?
400:
(m_DibHead->biHeight)),0,0,m_DibHead->biWidth,m_DibHead->biHeight,
TmpBmp,(LPBITMAPINFO)m_DibHead,DIB_RGB_COLORS,SRCCOPY);
delete[]TmpBmp;
TmpBmp=NULL;
}
2、运行结果:
五、实验结果分析:
我们可以看到经过分段线性变换后的图像与原图像相比细节信息有损失,但图像的视觉效果有所改善,图像对比度增强。
经过对数处理后的图像细节有所损失,视觉效果有所改善,但图像清晰度降低,层次降低。
实验四、图像基本运算
一、实验目的:
掌握图像平移、镜像、旋转、放大缩小的基本原理及实现过程。
二、实验原理:
1、
利用矩阵变换实现图像平移、旋转、镜像及缩放处理,掌握变换前后数据的变化,掌握基本的插值方法。
2、图像几何变换:
图像几何变换又称为空间变换,是将一幅图像中的坐标位置映射到另外一幅图像中的新坐标位置。
它不改变图像的像素值,只是在图像平面上进行像素的重新安排。
通过几何变换,可以根据应用的需要使原图像产生大小、形状和位置等各方面的变化。
也就是说,几何变换可以改变像素点所在的几何位置以及图像中各物体之间的空间位置关系,这种运算可以被看成是将各物体在图像内移动,特别是图像具有一定的规律性时,一个图像可以由另一个图像通过做几何变换来产生。
几何变换可以分为图像的位置变换(平移、镜像、旋转)、形状变换(放大、缩小和剪切)以及图像的复合变换。
(1)图像的平移:
图像平移是将一幅图像中所有的点都按照指定的平移量在水平、垂直方向移动,平移后的图像与原图像相同。
平移后的图像上的每一点都可以在原图像中找到。
如果不想丢失被移出的部分图像,可以将新生成的图像宽度扩大|tx |,高度扩大| ty |;
(2)图像镜像变换原理:
图像的镜像变换分为两种:
一种是水平镜像,另外一种是垂直镜像。
图像的水平镜像操作是将图像的左半部分和右半部分以图像垂直中轴线为中心镜像进行对换;图像的垂直镜像操作是将图像上半部分和下半部分以图像水平中轴线为中心镜