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

更新时间:2023-07-20 17:56:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

任课教师:曹丽

《数字图像处理》

(2012-2013学年第2学期)

实 验 报 告

姓名: 张慧

班级:10电科(2)班

学号:E10640204

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

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

一. 实验目的

熟悉图像的基本格式和数据结构。掌握图像几何变换的原理。 二.实验原理

1. 图像平移

将图像中所有的点都按照指定的平移量水平、垂直移动。设(x0, y0)是原图像上的一点,图像水平平移量为tx,垂直平移量为ty,则平移后点(x0, y0)的坐标变为(x1, y1)。

(x0, y0)与(x1, y1)之间的关系为:

以矩阵的形式表示为:

x1 x0 tx

y y t0y 1

(1)

x1 10tx x0 y 01ty y0 1

1 001 1

(2)

它的逆变换:

x0 10 tx x1 y 01 t0y y1 1 001 1

(3)

平移后的图像中每个像素的颜色是由原图像中的对应点颜色确定的。图像平移处理流程如图1所示。

2. 图像旋转

通常是以图像的中心为圆心旋转,按顺时针方向旋转,如图2所示。 旋转前:

旋转a角度后:

x0 rcosb

y rsinb 0

(4)

x1 rcos b a rcosbcosa rsinbsina x0cona y0sinay1 rsin b a rsinbcosa rcosbsina x0sina y0cosa

(5)

以矩阵的形式表示为:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

图2 旋转示意图

x1 cosasina0 x0 y sinacosa0 1 y0 1 0 01 1

(6)

(6)式中,坐标系是以图像的中心为原点,向右为x轴正方向,向上为y轴正方向。它和以图像左上角为原点,向右为x轴正方向,向下为y轴正方向的坐标系之间的转换关系如图3所示。

yⅠ

图3 两种坐标系间的转换关系图

xⅡ

设图像的宽度为w,高度为h,容易得到:

x 100.5w xⅡ y 0 10.5h yⅡ 1 00 1 1

(7)

逆变换为:

xⅡ 10 0.5w x y 0 10.5hⅡ y 1 00 1 1

(8)

有了以上公式,可以把变换分成三步:

第一步,将坐标系Ⅰ变成Ⅱ; 第二步,将该点顺时针旋转a角度; 第三步,将坐标系Ⅱ变回Ⅰ。

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

这样,我们就得到了变换矩阵,它是上面三个矩阵的级联。那么对于新图像中的每一点,就可以根据对应原图中的点,得到它的灰度。如果超出原图范围,则填成白色。要注意的是,由于有浮点运算,计算出来点的坐标可能不是整数,采用取整处理或插值来处理。

3. 图像缩放

假设x轴放大因子为c, y轴放大因子为d,缩放的变换矩阵为:

x0 y

c0

0 0d 1 00三.实验仪器

1. 计算机; 2. VC++程序;

3. 移动式存储器(软盘、U盘等)。 4. 记录用的笔、纸。

四、 实验报告内容 实验代码:

#include "stdafx.h" #include "cv.h" #include "highgui.h" #include "stdio.h" #include "stdlib.h" #include "math.h"

#define DOWNRESIZE 0 // 缩小 #define q 0.5 //缩小倍数 #define UPRESIZE 1 // 放大 #define z 1.5 //放大倍数 #define HORAO 2 // 水平外凹 #define HORTU 3 // 水平外凸 #define LADDER 4 // 梯形变形 #define TRIANGLE 5 // 三角形变形 #define SSHAPE 6 // S形变形 #define ROTATE 7 // 图片旋转 #define TRANSLATION 8 // 图片平移 #define UNDAFORM 9//波浪形

#define RANGE 100 // 水平外凹或外凸的幅度

0 x10

y 11

1

9)

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

#define PI 3.1415926

// 哈哈镜制作

int main( int argc, char** argv ) {

IplImage* pImg; //声明IplImage指针 IplImage* pImg1; //声明IplImage指针 int i,j;

int x,y; int method; CvSize size; double tmp;

int angle = 45; double factor;

float m[6]; int width_rotate; int height_rotate;

CvMat M = cvMat (2, 3, CV_32F, m);

printf("0: 缩小\n1: 放大\n2: 水平外凹\n3: 水平外凸\n4: 梯形变形\n5: 三角形变形\n6: S形变形printf("请输入数字0—7,选择你需要的变换:\n"); scanf("%d",&method);

\n7: 图片旋转\n8: 图片平移\n");

//载入图像

pImg = cvLoadImage( "gg.bmp", 1); cvNamedWindow( "Image", 1 );//创建窗口 cvShowImage( "Image", pImg );//显示图像

printf("%d,%d",pImg->width,pImg->height); switch(method) {

// 最邻近插值图像缩小 case DOWNRESIZE:

size = cvSize(q*pImg->width,q*pImg->height); for(i=0;i<pImg1->height;i++)

for(j=0;j<pImg1->width;j++) {

float srcX=(float)(j*((float)pImg->width/(float)pImg1->width)); float srcY=(float)(i*((float)pImg->height/(float)pImg1->height)); int int_srcX=(int)srcX; int int_srcY=(int)srcY;

for(int k=0;k<pImg1->nChannels;k++)

pImg1 = cvCreateImage(size,pImg->depth,pImg->nChannels);

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

pImg1->imageData[i*pImg1->widthStep+j*pImg1->nChannels+k]=(uchar)pImg->imageData[int_srcY*pImg->widthStep+int_srcX*pImg->nChannels+k];

b=(bUpLeft*(1-float_srcX)*(1-float_srcY)+bUpRight*float_srcX*(1-float_srcY)+

rUpLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2]; rUpRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2]; rDownLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2]; rDownRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+2];

unsigned char bUpLeft, bUpRight, bDownLeft, bDownRight; unsigned char gUpLeft, gUpRight, gDownLeft, gDownRight; unsigned char rUpLeft, rUpRight, rDownLeft, rDownRight; unsigned char b, g, r;

bUpLeft=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+0]; 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]; 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]; gDownRight=pImg->imageData[int_srcY*pImg->widthStep+int_srcX*3+1];

}

}

break;

// 双线性插值图像放大 case UPRESIZE:

size=cvSize(z*pImg->width,z*pImg->height); for(i=0;i<pImg1->height;i++)

for(j=0;j<pImg1->width;j++) {

float srcX=(float)(j*((float)pImg->width/(float)pImg1->width)); float srcY=(float)(i*((float)pImg->height/(float)pImg1->height)); int int_srcX=(int)srcX; int int_srcY=(int)srcY; float float_srcX=srcX-int_srcX; float float_srcY=srcY-int_srcY;

pImg1 = cvCreateImage(size,pImg->depth,pImg->nChannels);

bDownLeft*(1-float_srcX)*float_srcY+bDownRight*float_srcX*float_srcY);

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

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);

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 && { }

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;

int_srcX<=pImg->width*2)

break;

// 水平外凹 case HORAO:

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++) {

int s=(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp)); for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];

} break;

}

}

// 水平外凸 case HORTU:

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); for(i=0;i<pImg1->height;i++) {

tmp = RANGE*sin(i*PI/pImg1->height+PI)+RANGE; for(j=tmp;j<pImg1->width-tmp;j++) {

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];

} break;

}

}

// 梯形变形 case LADDER:

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); for(i=0;i<pImg1->height;i++) {

tmp=(pImg1->width-RANGE)/2-i*(pImg1->width-RANGE)/(2*pImg1->height); for(j=tmp;j<pImg1->width-tmp;j++) {

int s=(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp)); for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];

} break;

}

}

// 三角形变形 case TRIANGLE:

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); for(i=1;i<pImg1->height;i++) {

for(j=1;j<i*pImg1->width/pImg1->height;j++) {

int s = (int)(pImg1->height*j/i); for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];

}

}

}

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

// S形变形 case SSHAPE:

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); for(i=0;i<pImg->height;i++) {

tmp = RANGE*sin(2*i*PI/pImg1->height+PI)+RANGE; for(j=tmp;j<pImg->width-(2*RANGE-tmp);j++) {

int s=(int)((j-tmp)*(pImg->width)/(pImg->width-RANGE*2)); for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg1->nChannels+k]=pImg->imageData[i*pImg->widthStep+s*pImg->nChannels+k];

} break;

}

}

//波浪形

case UNDAFORM:

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); for(i=0;i<pImg->height;i++) {

for(j=0;j<pImg->width;j++) {

int s=(int)((4*i+pImg->height+pImg->height*sin(j*2*PI/pImg->width))/6); for(int k=0;k<pImg->nChannels;k++) {

pImg1->imageData[s*pImg1->widthStep+j*pImg1->nChannels+k]=pImg->imageData[i*pImg->widthStep+j*pImg->nChannels+k];

//图片旋转 case ROTATE:

width_rotate=int(pImg->height*fabs(sin (-angle * CV_PI / 180.))+pImg->width*fabs(cos height_rotate=int(pImg->width*fabs(sin (-angle * CV_PI / 180.))+pImg->height*fabs(cos pImg1 = cvCreateImage(cvSize(width_rotate,height_rotate),pImg->depth,pImg->nChannels);

} break;

}

}

(-angle * CV_PI / 180.))); (-angle * CV_PI / 180.)));

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

m[1] = (float)sin (-angle * CV_PI / 180.); m[3] = -m[1]; m[4] = m[0];

// 将旋转中心移至图像中间 m[2] = pImg->width * 0.5f; m[5] = pImg->height * 0.5f;

cvGetQuadrangleSubPix (pImg, pImg1, &M);

break;

//图片平移

case TRANSLATION: {

for(i=0;i<pImg1->height-x;i++) {

for(j=0;j<pImg1->width-y;j++) {

for(int k=0;k<pImg1->nChannels;k++) {

pImg1 = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); printf("输入x,y:\n"); scanf("%d,%d",&x,&y);

if(x>=0&&y>=0)

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[(i+x)*pImg->wi

}

else if(x<0&&y>=0) {

for(i=-x;i<pImg1->height;i++) {

for(j=0;j<pImg1->width-y;j++) {

for(int k=0;k<pImg1->nChannels;k++) {

}

}

}

dthStep+(j+y)*pImg->nChannels+k];

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[(i+x)*pImg->wi

}

}

}

dthStep+(j+y)*pImg->nChannels+k];

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

else if(x>=0&&y<0) {

for(i=0;i<pImg1->height-x;i++) {

for(j=-y;j<pImg1->width;j++) {

for(int k=0;k<pImg1->nChannels;k++) {

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[(i+x)*pImg->wi

} else {

for(i=-x;i<pImg1->height;i++) {

for(j=-y;j<pImg1->width;j++) {

for(int k=0;k<pImg1->nChannels;k++) {

}

}

}

dthStep+(j+y)*pImg->nChannels+k];

pImg1->imageData[i*pImg1->widthStep+j*pImg->nChannels+k]=pImg->imageData[(i+x)*pImg->wi }

}

break;

printf("no method support\n"); break; default:

}

}

}

dthStep+(j+y)*pImg->nChannels+k];

// 显示结果

cvNamedWindow( "Image1", 1);//创建窗口 cvShowImage( "Image1", pImg1 );//显示图像 cvWaitKey(0); //等待按键

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

//销毁窗口 释放内存

cvDestroyWindow( "Image" );//销毁窗口 cvReleaseImage( &pImg ); //释放图像 cvDestroyWindow( "Image1" );//销毁窗口 cvReleaseImage( &pImg1 ); //释放图像

return 0; } 原图:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

缩小:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

放大:

太大了 ,不能截图 内凹:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

外凸:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

梯形:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

三角形:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

S形:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

波浪形:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

旋转:

vc++实现图像放大、缩小、平移、旋转、各种哈哈镜变形

平移:

本文来源:https://www.bwwdw.com/article/xr31.html

Top