javascript图像处理—仿射变换深度理解

 更新时间:2013年01月16日 09:06:37   作者:  
上一篇文章,我们讲解了图像金字塔,这篇文章我们来了解仿射变换,仿射?任何仿射变换都可以转换成,乘以一个矩阵(线性变化),再加上一个向量(平移变化),接下来详细介绍,感兴趣的朋友可以了解下
前言

上一篇文章,我们讲解了图像金字塔,这篇文章我们来了解仿射变换。

仿射?

任何仿射变换都可以转换成,乘以一个矩阵(线性变化),再加上一个向量(平移变化)。

实际上仿射是两幅图片的变换关系。

例如我们可以通过仿射变换对图片进行:缩放、旋转、平移等操作。

一个数学问题

在解决仿射问题前,我们来做一个数学题。

如图,对于点(x1, y1),相对于原点旋转一个角度a,那么这个点到哪里了呢?

我们将坐标系变成极坐标系,则点(x1, y1)就变成了(r, β),而旋转后变成(r, α+ β)。

转回直角坐标系,则旋转后的点变成了(cos(α+ β) * r, sin(α+ β) * r)。

然后利用公式

cos(α+β)=cosαcosβ-sinαsinβ

sin(α+β)=sinαcosβ+cosαsinβ

以及原来点为(cosβ * r, sinβ * r),于是很容易得出新的点为(x1 * cosα - y1 * sinα, x1 * sinaα + y1 * cosα)。

我们可以从中推导出旋转变换公式

那么平移就相对简单很多了,就相当于加上一个向量(c, d)就行了。

获得变换矩阵函数实现

通常我们使用2 \times 3矩阵来表示仿射变换。

A = \begin{bmatrix} a_{00} & a_{01} \\ a_{10} & a_{11} \end{bmatrix}_{2 \times 2} B = \begin{bmatrix} b_{00} \\ b_{10} \end{bmatrix}_{2 \times 1} M = \begin{bmatrix} A & B \end{bmatrix} =\begin{bmatrix} a_{00} & a_{01} & b_{00} \\ a_{10} & a_{11} & b_{10}\end{bmatrix}_{2 \times 3}

其中A是旋转缩放变换,B是平移变换。则结果T满足:

T = A \cdot \begin{bmatrix}x \\ y\end{bmatrix} + B 或者 

T = M \cdot [x, y, 1]^{T}

即:T = \begin{bmatrix} a_{00}x + a_{01}y + b_{00} \\ a_{10}x + a_{11}y + b_{10} \end{bmatrix}

复制代码 代码如下:

var getRotationArray2D = function(__angle, __x, __y){
var sin = Math.sin(__angle) || 0,
cos = Math.cos(__angle) || 1,
x = __x || 0,
y = __y || 0;

return [cos, -sin, -x,
sin, cos, -y
];
};

这样我们就得到了一个仿射变换矩阵。

当然这个实现本身是有一定问题的,因为这个原点被固定在左上角了。

仿射变换实现

复制代码 代码如下:

var warpAffine = function(__src, __rotArray, __dst){
(__src && __rotArray) || error(arguments.callee, IS_UNDEFINED_OR_NULL/* {line} */);
if(__src.type && __src.type === "CV_RGBA"){
var height = __src.row,
width = __src.col,
dst = __dst || new Mat(height, width, CV_RGBA),
sData = new Uint32Array(__src.buffer),
dData = new Uint32Array(dst.buffer);

var i, j, xs, ys, x, y, nowPix;

for(j = 0, nowPix = 0; j < height; j++){
xs = __rotArray[1] * j + __rotArray[2];
ys = __rotArray[4] * j + __rotArray[5];
for(i = 0; i < width; i++, nowPix++, xs += __rotArray[0], ys += __rotArray[3]){

if(xs > 0 && ys > 0 && xs < width && ys < height){

y = ys | 0;
x = xs | 0;

dData[nowPix] = sData[y * width + x];
}else{
dData[nowPix] = 4278190080; //Black
}
}
}
}else{
error(arguments.callee, UNSPPORT_DATA_TYPE/* {line} */);
}
return dst;
};

这个函数先把矩阵数据变成32位形式,操作每个元素就等同于操作每一个像素。

然后遍历所有元素,对对应的点进行赋值。

效果

 

相关文章

  • JavaScript多种页面刷新方法小结

    JavaScript多种页面刷新方法小结

    这篇文章主要介绍了JavaScript多种页面刷新方法小结,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • JS 实现导航菜单中的二级下拉菜单的几种方式

    JS 实现导航菜单中的二级下拉菜单的几种方式

    这篇文章主要介绍了JS 实现导航菜单中的二级下拉菜单的几种方式的相关资料,这里提供了三种方式,和实例代码,需要的朋友可以参考下
    2016-10-10
  • 详解前端安全之JavaScript防http劫持与XSS

    详解前端安全之JavaScript防http劫持与XSS

    作为前端,一直以来都知道HTTP劫持与XSS跨站脚本、CSRF跨站请求伪造。防御这些劫持最好的方法是从后端入手,前端能做的太少。而且由于源码的暴露,攻击者很容易绕过防御手段。但这不代表我们去了解这块的相关知识是没意义的,本文的许多方法,用在其他方面也是大有作用。
    2021-05-05
  • javascript中返回顶部按钮的实现

    javascript中返回顶部按钮的实现

    这篇文章主要介绍了使用javascript实现博客园页面右下角返回顶部按钮的思路及源码,非常不错,这里推荐给小伙伴们
    2015-05-05
  • 微信小程序实现上传图片裁剪图片过程解析

    微信小程序实现上传图片裁剪图片过程解析

    这篇文章主要介绍了微信小程序实现上传图片裁剪图片过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • js判断变量是否空值的代码

    js判断变量是否空值的代码

    判断变量是否空值undefined, null, '', false, 0, [], {} 均返回true,否则返回false
    2008-10-10
  • JS数组交集、并集、差集的示例代码

    JS数组交集、并集、差集的示例代码

    本篇文章主要介绍了JS数组交集、并集、差集的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • js智能获取浏览器版本UA信息的方法

    js智能获取浏览器版本UA信息的方法

    下面小编就为大家带来一篇js智能获取浏览器版本UA信息的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • 对采用动态原型方式无法展示继承机制得思考

    对采用动态原型方式无法展示继承机制得思考

    今天看书,作者讨论到能否采用动态原型方法展示继承机制,给出的答案是:不能。原因是prototype对象的唯一性。看下面代码(这段代码不正确,却值得研究)
    2009-12-12
  • javascript实现固定侧边栏

    javascript实现固定侧边栏

    这篇文章主要为大家详细介绍了javascript实现固定侧边栏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02

最新评论