天津工业大学数字图像处理实验报告.docx
《天津工业大学数字图像处理实验报告.docx》由会员分享,可在线阅读,更多相关《天津工业大学数字图像处理实验报告.docx(17页珍藏版)》请在冰点文库上搜索。
天津工业大学数字图像处理实验报告
数字图像处理实验报告
实验一打开BMP文件,变灰度图,显示灰度直方图
1、BMP文件的打开
1.1算法理论描述
BMP文件主要有位图文件头、位图信息头、调色板、位图像素数据几部分组成。
可以通过C++中的CFILE类来读取BMP文件。
对于BMP图像文件的打开,可以通过声明一个Image对象,使用Image中的DrawImage函数打开。
1.2C++核心程序代码
Invalidate();//使上次绘图无效,准备重新绘制
UpdateWindow();
CDC*pDC=GetDC();//获取设备上下文
Graphicsgraph(pDC->GetSafeHdc());
Imageimage(filePathName);//什么Image对象,filePathName是要读取的文件名
CRectwinRect;//声明一个矩形区域
GetClientRect(winRect);//获取要画图区域大小
graph.DrawImage(&image,0,0,winRect.Width(),winRect.Height());//绘制图像
ReleaseDC(pDC);
1.3实验结果与分析
BMP格式图片打开效果如图1.1所示。
图1.1BMP文件的显示
2、BMP文件变灰度图
2.1算法理论描述
灰度图的原理就是使彩色图中的R、G、B三个分量值相等的过程。
通常有以下三种方法:
方法一:
平均值法
每个像素的三原色值等于R、G、B三分量的平均值,公式为:
R=G=B=(R+G+B)/3;
方法二:
最大值法
每个像素的三原色值等于R、G、B三分量的最大值,公式为:
R=G=B=max(R,G,B)
方法三:
加权平均值法
加权平均值法给予R、G、B三分量不同的权值然后相加,公式如下:
R=G=B=0.299R+0.587G+0.144B
2.2C++核心程序代码
下面代码是使用了方法三,加权平均值法
boolConvertImageToGray(constCString&imagePath)//imagePath是图片的存放路径
{
Bitmapbitmap(imagePath);//创建位图对象
if(bitmap.GetLastStatus()!
=Ok)
{returnfalse;}
intnWidth=bitmap.GetWidth();//获取位图宽
intnHeight=bitmap.GetHeight();//获取位图高
Bitmapimage(nWidth,nHeight);
//创建新的位图对象
Rectrect(0,0,nWidth,nHeight);//创建矩形区域
Graphicsgraph(&image);
ColorMatrixcolorMatrix={
0.299f,0.229f,0.299f,0.0f,0.0f,
0.578f,0.578f,0.578f,0.0f,0.0f,
0.144f,0.144f,0.144f,0.0f,0.0f,
0.0f,0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,0.0f,1.0f,
};//构建颜色变换矩阵
ImageAttributesimageAttr;
imageAttr.SetColorMatrix(&colorMatrix);
graph.DrawImage(&bitmap,rect,0,0,nWidth,nHeight,UnitPixel,&imageAttr);
}
2.3实验结果与分析
由图1.1变换后的灰度图如图2.1所示。
图2.1灰度图
3、由灰度图绘制灰度直方图
3.1算法理论描述
设u(k)表示灰度值为k的个数,k的取值范围从0到255。
我们首先建立一个255维的数组,设为histogram[255],然后我们一次读取灰度图的每一点的灰度值k,然后令histogram[k]加一。
当统计完所有的像素后,我们可以以横坐标为灰度值,纵坐标为个点灰度值的个数绘制出灰度直方图。
3.2C++核心程序代码
下面是统计各像素值个数的C++核心代码:
everyLineByte=mydib.GetBytesPerLine();
//获取图像每行字节数
m_dibWidth=mydib.GetWidth();
//获取图像宽度
m_dibHeight=mydib.GetHeight();
//获取图像高度
m_lpDIBBits=mydib.GetDibs();
//获取图像像素的偏移地址
下面是绘制直方图的C++核心代码:
for(inti=0;i<256;i++)
{
pDC->MoveTo(i+10,280);
pDC->LineTo(i+10,281-(int)(m_EPCount[i]*256/MaxPixel));
}
Note:
pDC是绘图窗口的句柄,可以通过如下语句获取。
CWnd*pWnd=GetDlgItem(窗口ID值);
CDC*pDC=pWnd->GetDC();
for(i=0;i{
for(j=0;j{
lpSrc=m_lpDIBBits+everyLineByte*i+j;
//获取要读取像素点的地址
histogram[*(lpSrc)]++;
//改点像素值加一
}
}
3.3实验结果与分析
由图2.1绘制的灰度直方图如图3.1所示。
实验二灰度图的二值化
1、算法理论描述
图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。
将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。
其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。
所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。
2、C++核心程序代码
BITMAPINFO*bitmapinfo=mydib.GetBITMAPINFO();//指向BITMAPINFO的指针
BITMAPINFOHEADER*bitmapinfoheader;
bitmapinfoheader=(BITMAPINFOHEADER*)bitmapinfo;//bitmapinfo强制类型转换为BITMAPINFOHEADER型指针
bitmapinfoheader++;//bitmapinfoheader自增,指向调色板
RGBQUAD*rgbquad=(RGBQUAD*)bitmapinfoheader;//BITMAPINFOHEADER型指针强制类型转换为RGBQUAD型
RGBQUADrgb;
intk=0;
//下面是根据像素值不同而将调色板的各种颜色进行不同的变换
for(k=0;k<256;k++)
{rgb=*(rgbquad+k);
if(k<128)//阈值小于为黑色
{
rgb.rgbRed=0;
rgb.rgbBlue=0;
rgb.rgbGreen=0;
}
else//阈值大于为白色
{
rgb.rgbRed=255;
rgb.rgbBlue=255;
rgb.rgbGreen=255;
}
*(rgbquad+k)=rgb;
}
3、实验结果与分析
原始灰度图如图3.1所示。
图3.1原始灰度图
变换后的二值化图像如3.2所示。
图3.2二值化图像
实验三伪彩色增强
1、算法理论描述
伪彩色增强是把黑白图像的各个不同灰度级按照线性或非线性的映射函数变换成不同的彩色,得到一幅彩色图像的技术。
使原图像细节更易辨认,目标更容易识别。
伪彩色增强的方法主要有密度分割法、灰度级-彩色变换和频率域伪彩色增强三种。
下面,重点说明一下灰度级-彩色变换方法。
根据色度学原理,将原图像f(x,y)的灰度范围分段,经过红、绿、蓝三种不同变换函数TR(.)、TG(.)和TB(.),变成三基色分量IR(x,y)、IG(x,y)、IB(x,y),然后用它们分别去控制彩色显示器的红、绿、蓝电子枪,便可以在彩色显示器的屏幕上合成一幅彩色图像。
伪彩色处理过程框图如图1.1。
图1.1伪彩色处理过程框图
灰度级-彩色变换典型变换函数如图1.2所示。
图1.2灰度级-彩色变换典型变换函数
2、C++核心程序代码
BITMAPINFO*bitmapinfo=mydib.GetBITMAPINFO();//指向BITMAPINFO的指针
BITMAPINFOHEADER*bitmapinfoheader;
bitmapinfoheader=(BITMAPINFOHEADER*)bitmapinfo;//bitmapinfo强制类型转换为BITMAPINFOHEADER型指针
bitmapinfoheader++;//bitmapinfoheader自增,指向调色板
RGBQUAD*rgbquad=(RGBQUAD*)bitmapinfoheader;//BITMAPINFOHEADER型指针强制类型转换为RGBQUAD型
RGBQUADrgb;
intk=0;
//下面是根据像素值不同而将调色板的各种颜色进行不同的变换
for(k=0;k<256;k++)
{
rgb=*(rgbquad+k);
if(k<128)//绿色变换
{rgb.rgbGreen=0;}
elseif(k<192)
{rgb.rgbGreen=4*(rgb.rgbGreen-128);}
else
{rgb.rgbGreen=255;}
if(k<64)//红色变换
{rgb.rgbRed=4*rgb.rgbRed;}
elseif(k<192)
{rgb.rgbRed=255;}
else
{rgb.rgbRed=1020-4*rgb.rgbRed;}
if(k<64)//蓝色变换
{rgb.rgbBlue=255;}
elseif(k<128)
{rgb.rgbBlue=510-4*rgb.rgbBlue;}
else
{rgb.rgbBlue=0;}
*(rgbquad+k)=rgb;
}
3、实验结果与分析
原始灰度图如图3.1所示。
图3.1原始灰度图
伪彩色增强后如图3.2所示。
图3.2伪彩色增强后图像
实验四图像的边缘检测
1、算法理论描述
边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。
图像属性中的显著变化通常反映了属性的重要事件和变化。
这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。
边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。
图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。
有许多方法用于边缘检测,它们的绝大部分可以划分为两类:
基于查找一类和基于零穿越的一类。
基于查找的方法通过寻找图像一阶导数中的最大和最小值来检测边界,通常是将边界定位在梯度最大的方向。
基于零穿越的方法通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点。
常用的边缘检测算有梯度边缘检测算子、Roberts边缘检测算子、Soble边缘检测算子、拉普拉斯边缘检测算子、Kirsch边缘检测算子、Canny边缘检测算子等几种。
2、Matlab程序代码
%图像的边缘检测
I=imread('ai.bmp');%读取图像
AI=rgb2gray(I);%图像变为灰度图
BY1=edge(AI,'roberts');%应用roberts进行边缘检测
BY2=edge(AI,'sobel');%应用sobel进行边缘检测
BY3=edge(AI,'Prewitt');%应用Prewitt进行边缘检测
BY4=edge(AI,'Canny');%应用Canny进行边缘检测
subplot(2,3,1),imshow(I),title('原图像')%显示原图像并加标题
subplot(2,3,2),imshow(AI),title('灰度图')%显示灰度图像并加标题
subplot(2,3,3),imshow(BY1),title('roberts边缘检测')%显示roberts边缘检测原图像并加标题
subplot(2,3,4),imshow(BY2),title('sobel边缘检测')%显示sobe边缘检测原图像并加标题
subplot(2,3,5),imshow(BY3),title('Prewitt边缘检测')%显示Prewitt边缘检测原图像并加标题
subplot(2,3,6),imshow(BY4),title('Canny边缘检测')%显示Canny边缘检测原图像并加标题
3、实验结果与分析
原图像、灰度图及各种边缘检测结果如图3.1所示。
图3.1原图像、灰度图及各种边缘检测结果
实验五图像的加减运算
1、算法理论描述
在图像的代数运算中,加法与减法运算在图像的增强处理中最为有用。
两幅图像
和h
的加法与减法运算分别表示为
g(x,y)=f(x,y)+h(x,y)
w(x,y)=f(x,y)-h(x,y)
图像的差是通过计算两幅图像所有对应像素点的差得到的。
减法运算最主要的作用是增强两幅图像的差异。
2、Matlab程序代码
a=imread('add1.bmp');%读取图像
b=imread('add2.bmp');%读取图像
c=imadd(a,b);%图像a和b相加,得到图像c
figure
(1),imshow(c);%显示图像c
d=imsubtract(c,b);%图像c减去b,得到图像d
figure
(2),imshow(d);%显示图像d
3、实验结果与分析
图像a如图3.1所示。
图3.1图像a
图像b如图3.2所示。
图3.1图像b
图像a与b相加后得到图像c,图像c如图3.3所示
图3.3相加后的图像c
分析:
图像a与b相加后左下角字体之所以与图像b字体颜色不同,一是由于两个图像的像素值相加后若
大于255,则该点像素值为255;二是由于图像a左下角的像素值不为0,与b图像字体相加后像素值大于b图像字体像素值。
图像c与b相减后得到图像d,图像d如图3.4所示
图3.4相减后的图像d
分析:
图像c与b相加后左下角字体之所以没有恢复到原来图像a,是由于两个图像的像素值相加后若
大于255,则该点像素值为255,然后在做减法不可能得到原来的像素值。