VC++图像处理程序实验.docx
《VC++图像处理程序实验.docx》由会员分享,可在线阅读,更多相关《VC++图像处理程序实验.docx(48页珍藏版)》请在冰点文库上搜索。
VC++图像处理程序实验
数字图像处理实验指导书
天津理工大学计算机科学与通信学院
杨淑莹
2009-4-16
目录
数字图像处理实验指导书1
1.总述3
2.试验题目3
2.1实验
(一)3
2.2实验
(二)17
2.3.实验(三)26
2.4实验(四)32
1.总述
数字图像处理课程实验使学生将理论和实际结合起来,增强学生的动手编程能力。
其目的使学生将所学内容灵活运用和掌握,拓展学生的思维。
本文档详细描述了数字图像处理的四次实验的实验目的和实验步骤,及较为详细的编程代码以及实验效果。
2.试验题目
2.1实验
(一)
◆实验名称图像的特效显示
◆软件环境windowsVC++6.0
◆实验目的
1.实现图像颜色修改处理。
2.将图像中的红气球物体左右、上下、对称复制。
3.实现图像的渐隐显示。
4.自行设计图像的几何变换显示。
◆实验内容(应包括实验题目、实验要求、实验任务等)
1.实现图像颜色修改处理
要求:
显示一幅位图,实现图像颜色修改处理。
(1)在左视图中打开一幅bmp位图,包括256色或真彩色位图
(2)制作一个【图像颜色修改处理】菜单,将消息映射到右视图中,在右视图
中显示位图,完成图像颜色修改处理显示功能。
2.将图像中的红气球物体左右、上下、对称复制。
要求:
在左视图中打开一幅256色的灰度bmp位图。
将图像中的红气球物体左右、上下、对称复制。
(1)在左视图中打开一幅bmp位图,包括256色或真彩色位图
(2)制作一个【红气球复制】菜单,将消息映射到右视图中,在右视图
中,完成将图像中的红气球物体左右、上下、对称复制功能。
3.实现图像渐隐显示。
要求:
显示一幅位图,实现图像渐隐显示。
(1)在左视图中打开一幅bmp位图,包括256色或真彩色位图
(2)制作一个【图像渐隐显示】菜单,将消息映射到右视图中,在右视图
中显示位图,完成图像图像渐隐显示功能。
4.自行设计图像的几何变换。
(选作)
要求:
自行设计图像的几何变换。
(1)在左视图中打开一幅bmp位图,包括256色或真彩色位图
(2)制作一个【自行设计图像的几何变换】菜单,将消息映射到右视图中,在右视图中自行设计图像的特效显示,完成图像的几何变换功能。
◆实验过程与实验结果(可包括实验实施的步骤、算法描述、流程、结论)
.图像颜色修改处理
编程思路:
该程序只针对24位彩色位图,不适用于灰度位图。
当原图的像素点为蓝色时,将显示屏幕上该位置的像素点像素值置为绿色,否则不变,将原图像素值赋给新图。
程序代码:
voidCDynSplitView2:
:
OnYansexiugai()
{
//刷新屏幕
CDC*pDC=GetDC();
CRectrect(0,0,1000,1000);
CBrushbrush(RGB(255,255,255));
pDC->FillRect(&rect,&brush);
//复制图像数据
clearmem();
CDSplitDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc->statedoc&&state2==1)
{
BYTE*pBitmapData=CDibNew1->GetData();
LPBITMAPINFOpBitmapInfo=CDibNew1->GetInfo();
intbitmapHeight=CDibNew1->GetHeight();
intbitmapWidth=CDibNew1->GetWidth();
LPBYTEtemp;
temp=newBYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()*3];
memset(temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);
for(intj=0;j{
for(inti=0;i{
if(pBitmapData[j*bitmapWidth*3+i*3]==255&&pBitmapData[j*bitmapWidth*3+i*3+1]==0
&&pBitmapData[j*bitmapWidth*3+i*3+2]==0)
{
temp[j*bitmapWidth*3+i*3]=0;
temp[j*bitmapWidth*3+i*3+1]=255;
temp[j*bitmapWidth*3+i*3+2]=0;
}
else
{
temp[j*bitmapWidth*3+i*3]=pBitmapData[j*bitmapWidth*3+i*3];
temp[j*bitmapWidth*3+i*3+1]=pBitmapData[j*bitmapWidth*3+i*3+1];
temp[j*bitmapWidth*3+i*3+2]=pBitmapData[j*bitmapWidth*3+i*3+2];
}
}
}
:
:
StretchDIBits(pDC->GetSafeHdc(),
0,0,bitmapWidth,bitmapHeight,
0,0,bitmapWidth,bitmapHeight,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
memcpy(pBitmapData,temp,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);
deletetemp;
}
}
实验效果
2.将图像中的红气球物体左右、上下、对称复制。
代码设计思路:
将气球画在图的上部四分一处,但图的大小为1,显示时将图像的上部四分一处复制四次,分别显示在左图。
程序核心代码:
voidCDynSplitView2:
:
OnHongqiqiufuzhi()
{
//TODO:
Addyourcommandhandlercodehere
inti,j;
//刷新屏幕
CDC*pDC=GetDC();
CRectrect(0,0,1000,1000);
CBrushbrush(RGB(255,255,255));
pDC->FillRect(&rect,&brush);
//复制图像数据
clearmem();
CDSplitDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc->statedoc&&state2==1)
{
BYTE*pBitmapData=CDibNew1->GetData();
LPBITMAPINFOpBitmapInfo=CDibNew1->GetInfo();
intbitmapHeight=CDibNew1->GetHeight();
intbitmapWidth=CDibNew1->GetWidth();
LPBYTEtemp;
temp=newBYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()*3];
memset(temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);
for(j=0;j{
for(i=0;i{
temp[j*bitmapWidth*3+i*3]=pBitmapData[j*bitmapWidth*3+i*3];
temp[j*bitmapWidth*3+i*3+1]=pBitmapData[j*bitmapWidth*3+i*3+1];
temp[j*bitmapWidth*3+i*3+2]=pBitmapData[j*bitmapWidth*3+i*3+2];
}
}
:
:
StretchDIBits(pDC->GetSafeHdc(),
0,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
0,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
:
:
StretchDIBits(pDC->GetSafeHdc(),
bitmapWidth/2,0,bitmapWidth/2,bitmapHeight/2,
0,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
:
:
StretchDIBits(pDC->GetSafeHdc(),
0,0,bitmapWidth/2,bitmapHeight/2,
0,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
:
:
StretchDIBits(pDC->GetSafeHdc(),
bitmapWidth/2,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
0,bitmapHeight/2,bitmapWidth/2,bitmapHeight/2,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
memcpy(pBitmapData,temp,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);
deletetemp;
}
}
实验效果
3.图像渐隐显示
编程思路:
先记录下图想的每个像素点的像素值,显示的时候先将屏幕显示原图,将循环显示n次,这里设n从256,255,…,2,1,0。
每一次显示像素值的n/256倍,图像的像素点计算一遍后,显示一次,重复执行上述过程,直至屏幕上所有的像素点全变黑。
程序代码:
voidCDynSplitView2:
:
OnTuxiangjianyin()
{
//刷新屏幕
CDC*pDC=GetDC();
CRectrect(0,0,1000,1000);
CBrushbrush(RGB(255,255,255));
pDC->FillRect(&rect,&brush);
//复制图像数据
clearmem();
CDSplitDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc->statedoc&&state2==1)
{
BYTE*pBitmapData=CDibNew1->GetData();
LPBITMAPINFOpBitmapInfo=CDibNew1->GetInfo();
intbitmapHeight=CDibNew1->GetHeight();
intbitmapWidth=CDibNew1->GetWidth();
if(CDibNew1->GetRGB())//Hasacolortable
{
CPalette*hPalette=CreateBitmapPalette(CDibNew1);
CPalette*hOldPalette=pDC->SelectPalette(hPalette,true);
pDC->RealizePalette();
LPBYTEtemp,temp1,temp2;
temp=newBYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()];
memset(temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth());
for(intn=256;n>=0;n--)
{
temp1=pBitmapData;
temp2=temp;
for(intj=0;j{
for(inti=0;i{
*temp2=(*temp1)*(n)/256;
temp1++;
temp2++;
}
}
:
:
StretchDIBits(pDC->GetSafeHdc(),0,0,bitmapWidth,bitmapHeight,
0,0,bitmapWidth,bitmapHeight,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
Sleep(10);
}
pDC->SelectPalette(hOldPalette,true);
:
:
DeleteObject(hPalette);
deletetemp;
}
else
{
LPBYTEtemp;
temp=newBYTE[CDibNew1->GetHeight()*CDibNew1->GetWidth()*3];
memset(temp,0,CDibNew1->GetHeight()*CDibNew1->GetWidth()*3);
for(intm=256;m>=0;m--)
{
for(intj=0;j{
for(inti=0;i{
temp[j*bitmapWidth*3+i*3]=pBitmapData[j*bitmapWidth*3+i*3]*(m)/256;
temp[j*bitmapWidth*3+i*3+1]=pBitmapData[j*bitmapWidth*3+i*3+1]*(m)/256;
temp[j*bitmapWidth*3+i*3+2]=pBitmapData[j*bitmapWidth*3+i*3+2]*(m)/256;
}
}
:
:
StretchDIBits(pDC->GetSafeHdc(),
0,0,bitmapWidth,bitmapHeight,
0,0,bitmapWidth,bitmapHeight,
temp,pBitmapInfo,
DIB_RGB_COLORS,SRCCOPY);
Sleep(10);
}
deletetemp;
}
}
}
实验效果
4.自行设计图像的几何变换
放大后做水平、垂直镜像
编程思路:
取得原图的数据区指针;通过对话框获得放大整数比例:
X,Y,更改图像的宽度和高度;每个像素依稀次循环,计算该像素在原图像中的坐标,将原图的像素值赋给目标像素相应X*Y个值。
放大过程完成。
取得原图的数据区指针;开辟一个同样大小的缓冲区;每个像素依次循环,在水平镜像中,将原图中的像素点的水平坐标变成镜像后的坐标(用图像的宽度减去坐标值)在显示到图像上。
垂直景镜像中,则对垂直坐标做相应的处理。
(1)放大后做镜像程序代码:
voidCDynSplitView2:
:
OnFangdashuipingjingxiang()
{
clearmem();
floatxzoom,yzoom;
CDlgSuoFangdlg;//定义对话框
dlg.m_XZoom=2.0;
dlg.m_YZoom=2.0;
//显示对话框,提示用户设定窗口上下限
if(dlg.DoModal()!
=IDOK)
{
return;//返回
}
xzoom=dlg.m_XZoom;
yzoom=dlg.m_YZoom;
deletedlg;//删除对话框
//源图像的宽度和高度
LONGwide;
LONGheight;
//缩放后图像的宽度和高度
LONGnewwide;
LONGnewheight;
LONGnewLineBytes;
LPBYTEtemp;
//获取图像的宽度和高度
wide=CDibNew1->GetWidth();
height=CDibNew1->GetHeight();
if(CDibNew1->m_pBitmapInfoHeader->biBitCount<9)
{
//计算缩放后的图像宽度和高度
newwide=(LONG)(wide*xzoom+0.5);
newheight=(LONG)(height*yzoom+0.5);
newLineBytes=(newwide*8+31)/32*4;
//分配内存,以保存新DIB
temp=newBYTE[newLineBytes*newheight];
memset(temp,0,newLineBytes*newheight);
CDibNew1->m_pData=CDibNew1->FangDa(temp,xzoom,yzoom,wide,height,newLineBytes,newheight);
CDibNew1->SetWidth(newwide);
CDibNew1->SetHeight(newheight);
CDibNew1->JingXiang(TRUE);//调用水平镜像处理函数
Invalidate();//调用刷新函数
}
else
{
//计算缩放后的图像宽度和高度
newwide=(LONG)(wide*xzoom*3);
newheight=(LONG)(height*yzoom);
//分配内存,以保存新DIB
temp=newBYTE[newwide*newheight];
memset(temp,0,newwide*newheight);
CDibNew1->m_pData=CDibNew1->FangDa(temp,xzoom,yzoom,wide,height,newwide,newheight);
CDibNew1->SetWidth(newwide/3);
CDibNew1->SetHeight(newheight);
CDibNew1->JingXiang(TRUE);//调用水平镜像处理函数
Invalidate();//调用刷新函数
}
}
放大代码:
LPBYTETeXiaoXianShiDib:
:
FangDa(LPBYTEtemp,floatxzoom,floatyzoom,LONGwide,LONGheight,LONGnewwide,LONGnewheight)
{
//指向源图像的指针
LPBYTEp_data;
LPBYTEtemp1;
//指向源象素的指针
LPBYTElpSrc;
//指向缩放图像对应象素的指针
LPBYTElpDst;
inti;
intj;
//象素在源DIB中的坐标
inti0;
intj0;
p_data=this->GetData();
//获取图像的宽度
intk1=(int)yzoom;
intk2=(int)xzoom;
if(m_pBitmapInfoHeader->biBitCount<9)//灰度图像
{
temp1=newBYTE[newwide*newheight];
memset(temp1,(BYTE)255,newwide*newheight);
//针对图像每行进行操作
for(j=0;j{
//针对图像每列进行操作
for(i=0;i{
lpDst=(LPBYTE)temp1+newwide*j+i;
i0=(int)(i/xzoom+0.5);
j0=(int)(j/yzoom+0.5);
if((i0>=0)&&(i0=0)&&(j0{
lpSrc=(LPBYTE)p_data+wide*j0+i0;
*lpDst=*lpSrc;
}
}
}
temp=temp1;
returntemp;
}
else//24位彩色
{
//分配内存,以保存新DIB
temp1=newBYTE[newwide*newheight*4];
memset(temp1,255,newwide*newheight*4);
intr,g,b;
//针对图像每行进行操作
for(j=0;j{
//针对图像每列进行操作
for(i=0;i{
lpSrc=(LPBYTE)p_data+wide*j*3+i*3;
r=*lpSrc+