[终稿]实验4 图像几何变换—哈哈镜制作
实验4 图像几何变换—哈哈镜制作
一( 实验目的
熟悉图像的基本格式和数据结构。掌握图像几何变换的原理。
二(实验原理
1. 图像平移
将图像中所有的点都按照指定的平移量水平、垂直移动。设(x, y)是原图像上的一点,00图像水平平移量为t,垂直平移量为t,则平移后点(x, y)的坐标变为(x, y)。xy0011
(x, y)与(x, y)之间的关系为: 0011
xxt,,,10x (1) ,yyt,,10y,
以矩阵的形式
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
示为:
xtx10,,,,,,10x,,,,,,yty,01 (2) 10y,,,,,,,,,,,,10011,,,,,,
它的逆变换:
xtx10,,,,,,,01x,,,,,,yty,,01 (3) 01y,,,,,,,,,,,,10011,,,,,,
平移后的图像中每个像素的颜色是由原图像中的对应点颜色确定的。图像平移处理
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
如图1所示。
2. 图像旋转
通常是以图像的中心为圆心旋转,按顺时针方向旋转,如图2所示。
旋转前:
xrb,cos,0 (4) ,yrb,sin0,
旋转a角度后:
xrbarbarbaxconaya,,,,,,coscoscossinsinsin,,100 (5)
yrbarbarbaxaya,,,,,,sinsincoscossinsincos,,100
以矩阵的形式表示为:
y?, y) (x00
r (x, y) 11
r
a b x?
O
图2 旋转示意图
xaaxcossin0,,,,,,10,,,,,,yaay,,sincos0 (6) 10,,,,,,,,,,,,10011,,,,,,
(6)式中,坐标系是以图像的中心为原点,向右为x轴正方向,向上为y轴正方向。它和
以图像左上角为原点,向右为x轴正方向,向下为y轴正方向的坐标系之间的转换关系如图
3所示。
x?y O??
(x, y) x?
O ?
y ?
图3 两种坐标系间的转换关系图 设图像的宽度为w,高度为h,容易得到:
xwx100.5,,,,,,,?,,,,,,yhy,,010.5 (7) ,?,,,,,,,,,,,,10011,,,,,,
逆变换为:
xwx100.5,,,,,,,?,,,,,,,yhy,,010.5 (8) ?,,,,,,,,,,,,,10011,,,,,,
有了以上公式,可以把变换分成三步:
第一步,将坐标系?变成?;
第二步,将该点顺时针旋转a角度;
第三步,将坐标系?变回?。
这样,我们就得到了变换矩阵,它是上面三个矩阵的级联。那么对于新图像中的每一点,
就可以根据对应原图中的点,得到它的灰度。如果超出原图范围,则填成白色。要注意的是,
由于有浮点运算,计算出来点的坐标可能不是整数,采用取整处理或插值来处理。
3. 图像缩放
假设x轴放大因子为c, y轴放大因子为d,缩放的变换矩阵为:
xcx100,,,,,,01,,,,,,ydy,010 (9) 01,,,,,,,,,,,,10011,,,,,,
三(实验步骤
哈哈镜的制作程序实现伪代码如下: 哈哈镜程序框架
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "math.h"
#define DOWNRESIZE 0 // 缩小
#define UPRESIZE 1 // 放大
#define HORAO 2 // 水平外凹
#define HORTU 3 // 水平外凸
#define LADDER 4 // 梯形变形
#define TRIANGLE 5 // 三角形变形
#define SSHAPE 6 // S形变形
#define WAVESHAPE 7 // 波浪形变形
#define RANGE 100 // 水平外凹或外凸的幅度 #define PI 3.1415926
// 哈哈镜制作
int main( int argc, char** argv )
{
IplImage* pImg; //声明IplImage指针
IplImage* pImg1; //声明IplImage指针
int i,j;
int method = 0;
CvSize size;
double tmp;
method = DOWNRESIZE;
//method = HORAO;
//载入图像
pImg = cvLoadImage( "./1.bmp", 0);
cvNamedWindow( "Image", 1 );//创建窗口
cvShowImage( "Image", pImg );//显示图像
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg->imageSize,
pImg->height, pImg->width, pImg->nChannels);
switch(method)
{
// 图像缩小
case DOWNRESIZE:
size = cvGetSize(pImg);
size.width = (size.width>>3)<<2; // 在OpenCV里边~widthStep必须是4的倍
数~从而实现字节对齐~有利于提高运算速度。
size.height = size.height>>1;
pImg1 = cvCreateImage( size, IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;i
height;i++)
for(j=0;jwidth;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i*2*pImg->width+j*2];
}
break;
// 图像放大
case UPRESIZE:
/* 添加代码 */
break;
// 水平外凹
case HORAO:
pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
{
tmp = RANGE*sin(i*PI/pImg1->height);
for(j=tmp;jwidth-tmp;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
}
}
break;
// 水平外凸
case HORTU:
/* 添加代码 */
break;
// 梯形变形
case LADDER:
/* 添加代码 */
break;
// 三角形变形
case TRIANGLE:
/* 添加代码 */
break;
// S形变形
case SSHAPE:
/* 添加代码 */
break;
// 波浪形变形
case WAVESHAPE:
/* 添加代码 */
break;
default:
printf("no method support\n");
break;
}
// 显示结果
cvNamedWindow( "Image1", 1 );//创建窗口
cvShowImage( "Image1", pImg1 );//显示图像
cvWaitKey(0); //等待按键
//销毁窗口 释放内存
cvDestroyWindow( "Image" );//销毁窗口
cvReleaseImage( &pImg ); //释放图像
cvDestroyWindow( "Image1" );//销毁窗口
cvReleaseImage( &pImg1 ); //释放图像
return 0;
}
四(实验仪器
1. 计算机;
2. VC++程序;
3. 移动式存储器(软盘、U盘等)。
4. 记录用的笔、纸。
五(实验
报告
软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载
内容
1. 叙述实验过程;
2. 提交实验的原始图像和结果图像。
六(思考
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
1. 如果新图中有一点(x, y),按照公式错误~未找到引用源。得到的(x, y)不在原图1100
中该怎么办,
2. 编程实现基于零阶和一阶灰度插值法的图像放大技术,比较两种灰度内插
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
的效
果。
3. 编程实现图像放大、缩小、三角形、梯形、S形以及内凹和外凹等功能。
#include"StdAfx.h"
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "math.h"
#define DOWNRESIZE 0 // 缩小
#define UPRESIZE 1 // 放大
#define HORAO 2 // 水平外凹 #define HORTU 3 // 水平外凸 #define LADDER 4 // 梯形变形
#define TRIANGLE 5 // 三角形变形
#define SSHAPE 6 // S形变形
#define WAVESHAPE 7 // 波浪形变形
#define RANGE 100 // 水平外凹或外凸的幅度 #define PI 3.1415926
// 哈哈镜制作
int main( int argc, char** argv )
{
IplImage* pImg; //声明IplImage指针
IplImage* pImg1; //声明IplImage指针
int i,j;
int method = 5;
CvSize size;
double tmp;
//载入图像
pImg = cvLoadImage( "Lena.jpg", 0);
cvNamedWindow( "Image", 1 );//创建窗口
cvShowImage( "Image", pImg );//显示图像
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg->imageSize,
pImg->height, pImg->width, pImg->nChannels);
switch(method)
{
// 图像缩小
case DOWNRESIZE:
size = cvGetSize(pImg);
size.width = (size.width>>3)<<2; // 在OpenCV里边,widthStep必须是4的倍
数,从而实现字节对齐,有利于提高运算速度。
size.height = size.height>>1;
pImg1 = cvCreateImage( size, IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
for(j=0;jwidth;j++)
{
pImg1->imageData[i*pImg1->width+j] = pImg->imageData[i*2*pImg->width+j*2];
}
break;
// 图像放大
case UPRESIZE:
size = cvGetSize(pImg);
size.width = (size.width<<3)>>2; // 在OpenCV里边,widthStep必须是4的倍数,从而实现字节对齐,有利于提高运算速度。
size.height = size.height<<1;
pImg1 = cvCreateImage( size, IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
for(j=0;jwidth;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i/2*pImg->width+j/2];
}
break;
// 水平外凹
case HORAO:
pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
{
tmp = RANGE*sin(i*PI/pImg1->height);
for(j=(int)tmp;jwidth-tmp;j++)
{
pImg1->imageData[i*pImg1->width+j] = pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
}
}
break;
// 水平外凸
case HORTU:
pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n",
pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
{
tmp = RANGE+RANGE*sin(i*PI/pImg1->height+PI);
for(j=(int)tmp;jwidth-tmp;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
}
}
break;
// 梯形变形
case LADDER:
pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
{
tmp = i*0.3;
for(j=(int)tmp;jwidth-tmp;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
}
}
break;
// 三角形变形
case TRIANGLE:
pImg1 = cvCreateImage( cvGetSize(pImg), IPL_DEPTH_8U, 1);
printf("imageSize: %d height: %d, width: %d, nChannels: %d\n", pImg1->imageSize, pImg1->height, pImg1->width, pImg1->nChannels);
for(i=0;iheight;i++)
{
tmp = i*0.5;
for(j=(int)tmp;jwidth-tmp;j++)
{
pImg1->imageData[i*pImg1->width+j] =
pImg->imageData[i*pImg->width+(int)((j-tmp)*(pImg->width)/(pImg->width-2*tmp))];
}
}
break;
// S形变形
case SSHAPE:
/* 添加代码 */
break;
// 波浪形变形
case WAVESHAPE:
/* 添加代码 */
break;
default:
printf("no method support\n");
break;
}
// 显示结果
cvNamedWindow( "Image1", 1 );//创建窗口
cvShowImage( "Image1", pImg1 );//显示图像
cvWaitKey(0); //等待按键
//销毁窗口 释放内存
cvDestroyWindow( "Image" );//销毁窗口
cvReleaseImage( &pImg ); //释放图像
cvDestroyWindow( "Image1" );//销毁窗口
cvReleaseImage( &pImg1 ); //释放图像
return 0;