图像的几何变换

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1实验目的、要求

实验目的:

(1)掌握图像在空间域进行基本变换的原理与相关方法。

(2)能使用VC++实现图像平移变换、镜像变换、旋转变换、缩放变换的功能。

实验要求:

A部分:

(1)使用VC++设计程序:实现图像平移变换,图像缩放、图像裁剪、图像对角线镜像。

(2)使用VC++设计程序:对一幅高度与宽度均相等的图像,实现逆时针90度旋转。B部分:

(1)包括A部分全部要求。

(2)使用VC++设计程序:对任意一幅图像(高度与宽度可以不相等),实现任意角度的旋转。

(3)研究放大图像时使用的插值算法,使用VC++实现常见的三种图像插值算法:最近邻插值,双线性插值,立方卷积插值。通过实验验证其效果。

2实验原理

图像的平移:通过直角坐标系的平移变换公式:

x ‘ = x +dx

y’ = y + dy

注:(x,y)为源图像的坐标,(x’, y’)为新图像的坐标,dx对应x的偏移量,dy对应y的偏移量。即:平移之后新图像上坐标为(x’, y’)的像素点的颜色值,应该等于原图像上坐标为(x, y)的像素点的颜色值,以下类似。

图像的镜像:镜像分为水平镜像和垂直镜像

垂直镜像计算公式如下(图像大小为宽度为M,高度为N):

x’ = x

y’ = N – 1 – y

水平镜像计算公式为:

x’ = M – 1 – x

y’ = y

对角线镜像(对角线为左上角至右下角)计算公式:

x’ = M – 1 – x

y’ = N – 1 – y

图像的旋转:图像的旋转计算公式如下:

X’ = X *COS Q – Y *SIN Q

Y’ = X *SIN Q + Y*COS Q

注:(x,y)为源图像的坐标,(x’, y’)为新图像的坐标。

图像缩放:设原图像大小为宽度M、高度N,调整后宽度为k1×M、高度为k2×N,则:

Img.New(x,y) = Img.Old(x/k1, y/k2)

图像插值:当放大图像时,像素也相应地增加,增加的过程就是插值程序自动选择信息较好的像素作为增加的像素,而并非只使用临近的像素,所以在放大图像时,图像看上去会比较平滑、干净。常用插值算法包括:

最近邻插值:近邻取样插值的缩放算法,直接取Color0颜色作为缩放后点的颜色

双线性插值:需要考虑(Sx,Sy)坐标点周围4个颜色值Color0\Color1\Color2\Color3,把(Sx,Sy)到A\B\C\D坐标点的距离作为系数来把4个颜色混合出缩放后点的颜色立方卷积插值:考虑映射点周围16个点(4x4)的颜色来计算最终的混合颜色

3主要设备、器材

硬件环境:AMD A8-4500M 1.90G/4G RAM

软件环境:操作系统:WIN7

开发工具:Micrsoft Visual C++ 6.0

4实验步骤及原始数据记录

关键代码说明:

图像平移:

void CImageProcessingView::OnGeoTranslation()

{

// 实验图像平移

MessageBox("请在这里添加图像平移的代码");

// 可以参考图像裁剪的代码:CImageProcessingView::OnGeoCut()

// 获得当前文档对象

CImageProcessingDoc* pDoc = GetDocument();

// 判断图像是否已被加载

if( pDoc->m_pDibInit->IsEmpty() )

{

MessageBox("图像未加载");

return;

}

int width = pDoc->m_pDibInit->GetImageWidth();

int height = pDoc->m_pDibInit->GetImageHeight();

int bitCount = pDoc->m_pDibInit->GetImageBitCount();

// 将m_pDibInit 拷贝至m_pDibTest

pDoc->m_pDibTest->CloneDib(pDoc->m_pDibInit);

// 设置pDoc->m_pDibTest 为全白图像

int i, j;

RGBQUAD rgbQuad1;

rgbQuad1.rgbBlue = 255;

rgbQuad1.rgbGreen = 255;

rgbQuad1.rgbRed = 255;

rgbQuad1.rgbReserved = 0;

for(i=0; i

{

for(j=0; j

{

pDoc->m_pDibTest->SetPixel(i,j,&rgbQuad1);

}

}

// 实验删除BEGIN

int shiftX = 30;

int shiftY = 50;

for(i=0; i

{

for(j=0; j

{

rgbQuad1 = pDoc->m_pDibInit->GetPixel(i,j);

pDoc->m_pDibTest->SetPixel(i+shiftX, j+shiftY, &rgbQuad1);

}

}

// 实验删除END

// 交换m_pDibInit 与m_pDibTest 指针

CDib* pTmp = pDoc->m_pDibInit;

pDoc->m_pDibInit = pDoc->m_pDibTest;

pDoc->m_pDibTest = pTmp;

// 设置脏标记

pDoc->SetModifiedFlag(TRUE);

// 更新视图

pDoc->UpdateAllViews(NULL);

}

图像缩放:

void CImageProcessingView::OnGeoResizing()

{

// 实验图像缩放

MessageBox("请在这里添加图像缩放的代码");

// 可以参考图像裁剪的代码:CImageProcessingView::OnGeoCut()

// 获得当前文档对象

CImageProcessingDoc* pDoc = GetDocument();

// 判断图像是否已被加载

if( pDoc->m_pDibInit->IsEmpty() )

{

MessageBox("图像未加载");

return;

}

int width = pDoc->m_pDibInit->GetImageWidth();

int height = pDoc->m_pDibInit->GetImageHeight();

int bitCount = pDoc->m_pDibInit->GetImageBitCount();

相关文档
最新文档