一,图像变换与映射
我们在进行图像处理时常常需要对图像进行变换。比如对图像进行缩放,旋转,平移等。图像变换的本质是将像素点的坐标通过某一种函数关系,映射到另外的位置。假设变换前图像为I(x,y),变换后图像为I’(x’,y’),则变换前后的图像之间存在下列关系

(x′y′)=(f(x,y)g(x,y))I(x,y)=I′(x′,y′)=I′(f(x,y),g(x,y))(1)

\begin{pmatrix}x'\\y'\end{pmatrix}=\begin{pmatrix}f(x,y)\\g(x,y)\end{pmatrix} \\ I(x,y)=I'(x',y')=I'(f(x,y),g(x,y)) \tag 1

(xy)=(f−1(x′,y′)g−1(x′,y′))I′(x′,y′)=I(x,y)=I(f−1(x′,y′),g−1(x′,y′))(2)

\begin{pmatrix}x\\y\end{pmatrix}=\begin{pmatrix}f^{-1}(x',y')\\g^{-1}(x',y')\end{pmatrix} \\ I'(x',y')=I(x,y)=I(f^{-1}(x',y'),g^{-1}(x',y')) \tag 2
公式(1)我们已知原图像到目标图像的坐标变换(f(x,y),g(x,y)),因此我们可以知道原图像的一点在变换后在目标图像的位置,我们称为向前映射。
相反,公式(2)中我们知道目标图像的一点(x’,y’)在变换前在原图像上的位置 (f−1(x′,y′),g−1(x′,y′))(f^{-1}(x',y'),g^{-1}(x',y')),我们称为向后映射。

二、插值:向前映射与向后映射
我们知道,通常情况下,一个整数位置(x,y)经过图像变换后,往往都位于非整数位置。此时就要采用插值技术。此时对于向前映射和向后映射,需要采取不同的策略。

下图为向前映射的示意图。输入图像上整数点坐标映射到输出图像之后,变成了非整数点坐标。因此,需要将其像素值按一定权重分配到其周围四个像素点上。对于输出图像而言,其整数点像素值周围会有很多输入图像像素映射过来,每个到其周围的非整数点像素值都会分配一定的灰度值到它上面,将这些分配而来的像素值叠加,就是输出图像整数点位置的像素值。由于这个分配、叠加的特性,向前映射法有时也叫像素移交映射。

因此,对于向前映射而言,输出图像某一点的像素值不能直接得到,需要遍历输入图像的所有像素值,对其进行坐标变换,分配像素值到整数位置,才能得到输出图像各像素点的像素值。这是向前映射法的缺点。

相比之下,向后映射法就比较直观。在这种情况下,我们知道输出图像上整数点位置(x’,y’)在变换前位于输入图像上的位置(x,y),一般来说这是个非整数点位置,利用其周围整数点位置的输入图像像素值进行插值,就得到了该点的像素值。我们遍历输出图像,经过坐标变换、插值两步操作,我们就能将其像素值一个个地计算出来,因此向后映射又叫图像填充映射。如下图所示。

插值算法我们采用双线性插值,如下图所示

这次我们先看向后插值。这种情况下输出图像上某点的像素值I’(x’,y’)映射到f(x,y),而f(x,y)由输入图像上四点像素值叠加而成

f(x,y)=(1−x)∗(1−y)∗f(0,0)+(1−x)∗y∗f(0,1)+x∗(1−y)∗f(1,0)+x∗y∗f(1,1)

f(x,y)=(1-x)*(1-y)*f(0,0)+(1-x)*y*f(0,1)+x*(1-y)*f(1,0)+x*y*f(1,1)
很容易验证四个权重系数之和为1,插值后图像亮度不变。
对向前插值,输入图像某点I(x,y)变换到输出图像(x’,y’)的位置,因此需要将其像素值分配到f(0,0),f(0,1),f(1,0),f(1,1)四个位置。分配方式为

f(0,0)=(1−x)∗(1−y)∗f(x,y)f(0,1)=(1−x)∗y∗f(x,y)f(1,0)=x∗(1−y)∗f(x,y)f(1,1)=x∗y∗f(x,y)

f(0,0)=(1-x)*(1-y)*f(x,y) \\ f(0,1)=(1-x)*y*f(x,y) \\ f(1,0)=x*(1-y)*f(x,y)\\ f(1,1)=x*y*f(x,y)
对向前映射而言,虽然分配系数之和为1。但输出图像上每个点的像素值是多个分配值叠加而成的,不能保证所有分配到其上的权重之和为1。因此必须记录下所有分配到其上的权重并累加起来,最后利用累加权重进行归一化,才能得到正确的插值结果。

三、结果验证
利用旋转变换来严重上述理论,规定图像从左到右为x轴正方向,从上到下为y轴正方向,原点位于左上角。逆时针旋转为正。则图像的旋转变换公式为

(x′y′)=(α−ββα)(xy)+((1−α)x0−βy0βx0+(1−α)y0)

\begin{pmatrix}x'\\y'\end{pmatrix}= \begin{pmatrix}\alpha&\beta\\-\beta&\alpha\end{pmatrix} \begin{pmatrix}x\\y\end{pmatrix}+ \begin{pmatrix}(1-\alpha)x_0-\beta y_0\\\beta x_0+(1-\alpha)y_0\end{pmatrix}
其中 α=s∗cos(θ),β=s∗sin(θ),s\alpha=s*cos(\theta),\beta=s*sin(\theta),s为缩放系数。
利用上式我们很容易进行向前映射。
要进行向后映射,我们需要将上式稍作变换,改写成以(x’,y’)表示(x,y)的形式。
使用OpenCV进行编程,分别使用向前映射和向后映射方法进行旋转变换,以下为变换结果
原图片

旋转30°,向后映射

旋转30°,向前映射

四、总结
向后映射比较直观,计算量也小,我们经常使用的图像变换都是采用向后映射的方法来处理。但向后映射需要知道变换的反变换公式,在上面旋转变换的情况,反变换很容易求出来。但在有些变换比较复杂的场合,这个反变换是很难得到的。此时就需要采用前向映射的方法进行变换了。从实验结果看,向前映射得到的结果与向后映射是一样的。

图像变换——向前映射和向后映射相关推荐

  1. 【图像处理】向前映射 和 向后映射

    这两个映射都是指将原图经过图片变换到新图的一个过程,只是方式不同. 向前映射的方法是,以原图每个像素为基准计算被它影响的新图像素. 向后映射的方法是,以新图每个像素为基准计算影响它的原图像素. 参考: ...

  2. Windows 映射网络驱动器后,一重新启动,映射就不见了的解决方法

    Windows 映射网络驱动器后,一重新启动,映射就不见了的解决方法 1.Windows建立了网络驱动器映射后在下次重启系统就没了,非常不方便,解决方法是映射的时候把"登录时重新连接&quo ...

  3. 【STM32】端口复用和重映射,完全重映射,部分重映射

    文章目录 端口复用 端口复用函数总结 端口重映射 完全重映射 完全重映射函数总结 部分重映射 端口复用 当 PA9,PA10 引脚作为串口 1 的 TX,RX 引脚使用的时候,那就是端口复用(相较于作 ...

  4. ARM的存储器映射与存储器重映射【转载】2009-12-14 10:29最近在用LPC2148,看到了一篇文章,感觉很有帮助,就转了过来。

    ARM的存储器映射与存储器重映射[转载]2009-12-14 10:29最近在用LPC2148,看到了一篇文章,感觉很有帮助,就转了过来. arm处理器本身所产生的地址为虚拟地址,每一个arm芯片内都 ...

  5. Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc)

    本篇文章主要介绍了"Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc)",主要涉及到Linux内核访问外设I/O--动态映射(ioremap) ...

  6. mysql映射超_Hibernate的映射类型 hibernate mysql映射类型

    (转)http://blog.csdn.net/zxy_snow/article/details/7214222 Hibernate的映射类型 hibernate mysql映射类型 1.Hibern ...

  7. 字符设备驱动高级篇5——静态映射表、动态映射结构体方式操作寄存器

    以下内容源于朱有鹏<物联网大讲堂>课程的学习整理,如有侵权,请告知删除. 一.静态映射表建立过程分析 1.建立映射表的三个关键部分 (1)映射表描述 具体物理地址和虚拟地址的值相关的宏定义 ...

  8. 分布式映射与集中式映射_K映射上的表达式映射和组包围

    分布式映射与集中式映射 In the previous article (Karnaugh Map 2, 3 and 4- variable) we have already discussed th ...

  9. Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc) (转载)

    [转](转)Linux内核访问外设I/O资源的方式-静态映射(map_desc)方式 Linux内核访问外设I/O资源的方式 Author: Dongas Date: 08-08-02 我们知道默认外 ...

最新文章

  1. 【博客话题】我与Linux的不解情缘
  2. HighNewTech:支付宝全球首发5G手机,四大逆天功能(防骗三折叠气味识别自由飞)!
  3. MFC中打开文件对话框:CFileDlg
  4. Vmware esxi忘记密码重置方法
  5. 【鲲鹏来了】华为云鲲鹏弹性云服务器 KC1一文全掌握(2)
  6. linux的进程/线程/协程系列5:协程的发展复兴与实现现状
  7. 《ArcGIS Runtime SDK for .NET开发笔记》 --Hello Word
  8. Shell之分支结构和循环结构
  9. css html设计网页完整代码,htmlcss完整的网页代码
  10. oracle 脚本怎么写,wincc与 oracle 数据通讯脚本如何写-工业支持中心-西门子中国...
  11. Hypermesh-优化案例学习笔记-cclip
  12. 拼多多电商玩家如何利用软件机器人快速采集平台数据
  13. 软路由安装openwrt系统
  14. R语言length()和lengths()的区别
  15. Android 对TextView添加删除线,下划线,加粗,斜体等效果
  16. Fault tolerant heap shim applied to current process. This is usually due to previous crashes
  17. IDEA部署项目到tomcat运行成功但是页面404的两种原因
  18. 如何学习黑客技术?初级黑客入门
  19. WIN7双系统卸载与重装Ubuntu
  20. 用计算机无法解决打印所有,解决打印机无法打印的10种方法

热门文章

  1. 基于java的婚恋交友相亲网
  2. SpringBoot-多环境开发控制
  3. 步进电机的计算机控制系统设计,基于.51单片机的步进电机控制系统设计.doc
  4. 毕业设计 stm32厨房环境检测系统 - 物联网 嵌入式 单片机
  5. 暑假教师计算机培训总结,暑假信息技术培训心得总结
  6. Altium Designer 18 原理图绘制
  7. Nodejs做后端,实现文件压缩下载的几种方案(archiver、compressing、linux的zip命令):
  8. AGM(遨格芯微)FPGA:AG10KL144 及 AG10KL144H转换注意事项
  9. css好看的银行卡号样式
  10. C语言学习 / 简易21点