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

Java 给定仿射变换,如何确定旋转、镜像、缩放等。?,java,geometry,Java,Geometry,我正在解决一个问题,我在分析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]] 旋转/镜像图像:

我正在解决一个问题,我在分析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]]
旋转/镜像图像:

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]]
给定一个仿射变换实例,我假设可以确定:

  • 鳞片
  • 斯卡利
  • 轮换

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

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

软件包有很多选择,例如or

将分解为旋转、缩放和另一个旋转

下面是一个使用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=%f\n",
                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 decomp)或旋转比例剪切(QR decomp)

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

软件包有很多选择,例如or

将分解为旋转、缩放和另一个旋转

下面是一个使用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=%f\n",
                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 decomp)或旋转比例剪切(QR decomp)

是的,可以将矩阵分解为一系列旋转和缩放-但是您期望的输出是什么?我正在考虑编写一个转换类,以返回一个新模型,该模型以十进制表示角度(旋转)和百分比(scaleX/scaley).是的,可以将矩阵分解为一系列旋转和缩放-但是您期望的输出是什么?我正在考虑编写一个转换类,以返回一个新模型,该模型使用角度(旋转)和百分比(scaleX/scaley)的十进制表示。