实验报告模板
- 格式:doc
- 大小:644.09 KB
- 文档页数:12
图像分析与计算机视觉实践报告
课题:
专业:
班级:
姓名: 一、实验目的
了解图像平移旋转和缩放的原理,通过Visual C++实现图像的平移旋转和缩放。
二、实验理论说明
图像平移:
设(X0,Y0)是原图像的一点,图像的水平平移量为Tx,垂直平移量为Ty,平移后的坐标为(X1,Y1),平移后的坐标变为TyYYTxXX0101,用矩阵表示为:1010001100111TyTxYXYX。
图像缩放:
图像缩放是指图像的大小按照指定的比率放大或缩小。假设图像x轴方向的缩放比率Sx,y轴方向的缩放比率Sy,相应的变换表达式为:
1*0*01000000100111SyYSxXSySxYXYX
图像旋转:
旋转一般是指将图像围绕某一指定点旋转一定的角度。
设原图像的坐标为P0(X0,Y0),绕原点逆时针旋转角度θ到点P1(X1,Y1),旋转公式为:
1000cossin0sincos100111YXYX。
三、实验主要程序
平移代码: void CImageProcessingView::OnJhbhPy()
{
if(numPicture==0) {
AfxMessageBox("载入图片后才能空间平移!",MB_OK,0);
return;
}
//定义采样对话框也是用来空间变换平移的坐标
CImagePYDlg dlg;
if( dlg.DoModal()==IDOK ) //显示对话框
{
//采样坐标最初为图片的自身像素
if( dlg.m_xPY>m_nWidth || dlg.m_yPY>m_nHeight ) {
AfxMessageBox("图片平移不能为超过原图长宽!",MB_OK,0);
return;
}
AfxMessageBox("图片空间变换-平移!",MB_OK,0);
//打开临时的图片 读写文件
FILE *fpo = fopen(BmpName,"rb");
FILE *fpw = fopen(BmpNameLin,"wb+");
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
fread(m_pImage,m_nImage,1,fpo);
unsigned char *ImageSize;
ImageSize=new unsigned char[m_nImage]; //new和delete有效的进行动态内存的分配和释放
int Place; //建立临时坐标 记录起始坐标(0,0)平移过来的位置
int m_pImagePlace; //原始图像平移为(0,0) 图像把它平移到Place位置
unsigned char black; //填充黑色='0'
Place=dlg.m_yPY*m_nWidth*3; //前m_yPY行都要填充为黑色
black=0; //颜色为黑色
m_pImagePlace=0; //图像处事位置为(0,0),把该点像素平移过去
int countWidth=0; //记录每行的像素个数,满行时变回0
int number=0; //数字记录使用的像素行数,平移时使用
for(int i=0 ; i
{
/*如果每行的像素填满时清为0*/ if(countWidth==m_nWidth*3) {
countWidth=0;
}
/*第一部分:到平移后像素位置前面的所有像素点赋值为黑色*/
if(i
ImageSize[i]=black; //赋值为黑色
continue;
}
/*第二部分:平移区域的左边部分赋值为黑色*/
else if(i>=Place && countWidth
ImageSize[i]=black; //赋值为黑色
countWidth++;
continue;
}
/*第三部分:图像像素平移区域*/
else if(i>=Place && countWidth>=dlg.m_xPY*3)
{
ImageSize[i]=m_pImage[m_pImagePlace];
m_pImagePlace++;
countWidth++;
if(countWidth==m_nWidth*3)
{
number++;
m_pImagePlace=number*m_nWidth*3;
}
}
}
fwrite(ImageSize,m_nImage,1,fpw);
fclose(fpo);
fclose(fpw);
numPicture = 2;
level=200; //200表示几何变换
Invalidate();
}
}
旋转代码:
void CImageProcessingView::OnJhbhTxxz()
{
if(numPicture==0) { AfxMessageBox("载入图片后才能空间旋转!",MB_OK,0);
return;
}
//定义对话框并调用对话框
CImageXZDlg dlg;
if( dlg.DoModal()==IDOK ) //显示对话框
{
AfxMessageBox("图片空间变换-旋转图像!",MB_OK,0);
//读写文件
FILE *fpo = fopen(BmpName,"rb");
FILE *fpw = fopen(BmpNameLin,"wb+");
fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);
fread(m_pImage,m_nImage,1,fpo);
/*new和delete有效的进行动态内存的分配和释放*/
unsigned char *ImageSize;
ImageSize=new unsigned char[m_nImage];
int Place; //记录图像每行的位置,便于图像旋转
/*定义PA=3.14时使用的方法是arcsin(1.0/2)*6即为π*/
double PA;
PA=asin(0.5)*6;
/*把输入的0-360的正整数度数转换为角度,30度=π/6*/
double degree;
degree=PA*dlg.m_xzds/180; //调用dlg.m_xzds(旋转度数)
//对应的二维矩阵 注意图像矩阵从左下角开始处理 它最终要转换成一维存储
int X,Y; //图像变换前通过一维矩阵转换为二维
int XPlace,YPlace;
//输出转换为的角度
CString str;
str.Format("转换后的角度=%f",degree);
AfxMessageBox(str);
//图像旋转处理
for(int i=0 ; i
{
//原图:一维矩阵转换为二维矩阵 X=(i/3)%m_nWidth;
Y=(i/3)/m_nWidth;
//注意错误:X=i/m_nHeight Y=i%m_nWidth; 只输出最后1/3
//图像旋转为:a(x,y)=x*cos-y*sin b(x,y)=x*sin+y*cos
XPlace=(int)(X*cos(degree)-Y*sin(degree));
YPlace=(int)(X*sin(degree)+Y*cos(degree));
//在转换为一维图想输出
if( (XPlace>=0 && XPlace<=m_nWidth) && (YPlace>=0 &&
YPlace<=m_nHeight) )
{
Place=YPlace*m_nWidth*3+XPlace*3;
//在图像范围内赋值为该像素
if(Place+2
{
ImageSize[i]=m_pImage[Place];
i++;
ImageSize[i]=m_pImage[Place+1];
i++;
ImageSize[i]=m_pImage[Place+2];
}
//否则赋值为黑色
else
{
ImageSize[i]=0;
i++;
ImageSize[i]=0;
i++;
ImageSize[i]=0;
}
}
//否则赋值为黑色
else
{
ImageSize[i]=0;
i++;
ImageSize[i]=0;
i++;
ImageSize[i]=0;
}
}
fwrite(ImageSize,m_nImage,1,fpw);