给定仿射变换,如何确定旋转、镜像、缩放等



我正在处理一个分析PDF图像的问题。有时图像会被调整大小、旋转、镜像等。我可以访问PDF上下文矩阵作为仿射变换:

例如:

调整大小的图像:

AffineTransform[[432.2279052734375, 0.0, 90.0], [0.0, 150.67495727539062, 555.257080078125]]

旋转/镜像图像:

AffineTransform[[593.25, 0.0, 0.0], [0.0, -768.0, 768.1500244140625]]

给定一个仿射变换实例,我假设可以确定:

  • scaleX
  • 比例尺Y
  • 旋转
  • 剪切

不幸的是,我的几何技能缺乏(至少可以说(。有人能给我指出进行这些计算的正确方向吗?

可以将仿射变换表示为平移、旋转、反射、缩放和剪切的序列。计算它们的方法称为矩阵分解

软件包有很多选择,例如JAMA包或Apache Commons Math。

奇异值分解(SVD(将分解为旋转、缩放和另一个旋转。

以下是一个使用JAMA计算剪切SVD的样本,并从中提取旋转角度和比例因子:

import Jama.*;
public class Demo {
public static void main(String[] args) {
double[][] vals = {{1, 1}, {0, 2}};
Matrix a = new Matrix(vals);
SingularValueDecomposition svd = a.svd();
Matrix u = svd.getU();
Matrix v = svd.getV();
double[] s = svd.getSingularValues();
System.out.printf("rotate=%f scaleX=%f scaleY=%f rotate=%fn",
Math.toDegrees(Math.atan2(u.get(0, 1), u.get(0, 0))),
s[0], s[1],
Math.toDegrees(Math.atan2(v.get(0, 1), v.get(0, 0))));
}
}

输出告诉你这是一个76度的旋转,然后是缩放X和缩放Y,然后是58度的旋转:

rotate=-58.282526 scaleX=2.288246 scaleY=0.874032 rotate=-76.717474

注意:如果您的转换涉及到翻转图像,则此代码将不起作用。JAMA中的SVD例程将镜像与其中一个旋转集中在一起。由于您只有2x2矩阵,您可能需要考虑编写自己的专用SVD实现。

使用其他矩阵分解,您可以获得其他表示,例如剪切尺度剪切(LU反编译(或旋转尺度剪切(QR反编译(

最新更新