实验4 图像几何变换—哈哈镜制作

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
gDownRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+1];
rUpLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2];
rUpRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2];
printf("%d,%d",pImg->width,pImg->height);
switch(method)
{
//最邻近插值图像缩小
caseDOWNRESIZE:
size = cvSize(q*pImg->width,q*pImg->height);
pImg1 = cvCreateImage(size,pImg->depth,pImg->nChannels);
{
pImg1->imageData[i*pImg1->widthStep+j*3+0]=b;
pImg1->imageData[i*pImg1->widthStep+j*3+1]=g;
pImg1->imageData[i*pImg1->widthStep+j*3+2]=r;
}
}
break;
//水平外凹
intint_srcX=(int)srcX;
intint_srcY=(int)srcY;
floatfloat_srcX=srcX-int_srcX;
floatfloat_srcY=srcY-int_srcY;
unsignedcharbUpLeft, bUpRight, bDownLeft, bDownRight;
任课教师:曹丽
《数字图像处理》
(2012-2013学年第2学期)




学号:E10640204
姓名:张慧
班级:10电科(2)班
一.实验目的
熟悉图像的基本格式和数据结构。掌握图像几何变换的原理。
二.实验原理
1.图像平移
将图像中所有的点都按照指定的平移量水平、垂直移动。设(x0,y0)是原图像上的一点,图像水平平移量为tx,垂直平移量为ty,则平移后点(x0,y0)的坐标变为(x1,y1)。
r=(rUpLeft*(1-float_srcX)*(1-float_srcY)+rUpRight*float_srcX*(1-float_srcY)+
rDownLeft*(1-float_srcX)*float_srcY+rDownRight*float_srcX*float_srcY);
if(int_srcY>=0 && int_srcY<=pImg->height*2 && int_srcX>=0 && int_srcX<=pImg->width*2)
(x0,y0)与(x1,y1)之间的关系为:
(1)
以矩阵的形式表示为:
(2)
它的逆变换:
(3)
平移后的图像中每个像素的颜色是由原图像中的对应点Hale Waihona Puke Baidu色确定的。图像平移处理流程如图1所示。
2.图像旋转
通常是以图像的中心为圆心旋转,按顺时针方向旋转,如图2所示。
旋转前:
(4)
旋转a角度后:
(5)
以矩阵的形式表示为:
{
ints=(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp));
for(intk=0;k<pImg->nChannels;k++)
{
pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];
for(j=0;j<pImg1->width;j++)
{
floatsrcX=(float)(j*((float)pImg->width/(float)pImg1->width));
floatsrcY=(float)(i*((float)pImg->height/(float)pImg1->height));
bDownLeft*(1-float_srcX)*float_srcY+bDownRight*float_srcX*float_srcY);
g=(gUpLeft*(1-float_srcX)*(1-float_srcY)+gUpRight*float_srcX*(1-float_srcY)+
gDownLeft*(1-float_srcX)*float_srcY+gDownRight*float_srcX*float_srcY);
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
#defineDOWNRESIZE 0//缩小
#defineq 0.5//缩小倍数
#defineUPRESIZE 1//放大
#definez 1.5//放大倍数
#defineHORAO 2//水平外凹
gUpLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+1];
gUpRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+1];
gDownLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+1];
caseHORAO:
pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels);
for(i=0;i<pImg1->height;i++)
{
tmp = RANGE*sin(i*PI/pImg1->height);
for(j=tmp;j<pImg1->width-tmp;j++)
for(j=tmp;j<pImg1->width-tmp;j++)
{
ints=(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp));
for(intk=0;k<pImg->nChannels;k++)
{
pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];
unsignedchargUpLeft, gUpRight, gDownLeft, gDownRight;
unsignedcharrUpLeft, rUpRight, rDownLeft, rDownRight;
unsignedcharb, g, r;
bUpLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+0];
for(i=0;i<pImg1->height;i++)
for(j=0;j<pImg1->width;j++)
{
floatsrcX=(float)(j*((float)pImg->width/(float)pImg1->width));
floatsrcY=(float)(i*((float)pImg->height/(float)pImg1->height));
图2旋转示意图
(6)
(6)式中,坐标系是以图像的中心为原点,向右为x轴正方向,向上为y轴正方向。它和以图像左上角为原点,向右为x轴正方向,向下为y轴正方向的坐标系之间的转换关系如图3所示。
图3两种坐标系间的转换关系图
设图像的宽度为w,高度为h,容易得到:
(7)
逆变换为:
(8)
有了以上公式,可以把变换分成三步:
}
}
}
break;
//水平外凸
caseHORTU:
pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels);
for(i=0;i<pImg1->height;i++)
{
tmp = RANGE*sin(i*PI/pImg1->height+PI)+RANGE;
第一步,将坐标系Ⅰ变成Ⅱ;
第二步,将该点顺时针旋转a角度;
第三步,将坐标系Ⅱ变回Ⅰ。
这样,我们就得到了变换矩阵,它是上面三个矩阵的级联。那么对于新图像中的每一点,就可以根据对应原图中的点,得到它的灰度。如果超出原图范围,则填成白色。要注意的是,由于有浮点运算,计算出来点的坐标可能不是整数,采用取整处理或插值来处理。
bUpRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+0];
bDownLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+0];
bDownRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+0];
intint_srcX=(int)srcX;
intint_srcY=(int)srcY;
for(intk=0;k<pImg1->nChannels;k++)
{
pImg1->imageData[i*pImg1->widthStep+j*pImg1->nChannels+k]=(uchar)pImg->imageData[int_srcY*pImg->widthStep+int_srcX*pImg->nChannels+k];
#defineHORTU 3//水平外凸
#defineLADDER 4//梯形变形
#defineTRIANGLE 5//三角形变形
#defineSSHAPE 6// S形变形
#defineROTATE 7//图片旋转
#defineTRANSLATION 8//图片平移
#defineUNDAFORM 9//波浪形
}
}
break;
//双线性插值图像放大
caseUPRESIZE:
size=cvSize(z*pImg->width,z*pImg->height);
pImg1 = cvCreateImage(size,pImg->depth,pImg->nChannels);
for(i=0;i<pImg1->height;i++)
printf("请输入数字0—7,选择你需要的变换:\n");
scanf("%d",&method);
//载入图像
pImg = cvLoadImage("gg.bmp", 1);
cvNamedWindow("Image", 1 );//创建窗口
cvShowImage("Image", pImg );//显示图像
rDownLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2];
rDownRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2];
b=(bUpLeft*(1-float_srcX)*(1-float_srcY)+bUpRight*float_srcX*(1-float_srcY)+
#defineRANGE 100//水平外凹或外凸的幅度
#definePI 3.1415926
//哈哈镜制作
intmain(intargc,char** argv )
{
IplImage* pImg;//声明IplImage指针
IplImage* pImg1;//声明IplImage指针
inti,j;
intx,y;
intmethod;
CvSize size;
doubletmp;
intangle = 45;
doublefactor;
floatm[6];
intwidth_rotate;
intheight_rotate;
CvMat M = cvMat (2, 3, CV_32F, m);
printf("0:缩小\n1:放大\n2:水平外凹\n3:水平外凸\n4:梯形变形\n5:三角形变形\n6: S形变形\n7:图片旋转\n8:图片平移\n");
3.图像缩放
假设x轴放大因子为c,y轴放大因子为d,缩放的变换矩阵为:
(9)
三.实验仪器
1.计算机;
2.VC++程序;
3.移动式存储器(软盘、U盘等)。
4.记录用的笔、纸。
四、实验报告内容
实验代码:
#include"stdafx.h"
#include"cv.h"
#include"highgui.h"
相关文档
最新文档