gpt4 book ai didi

java - 通过剪切任意角度旋转(Paeth算法)

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:36:55 25 4
gpt4 key购买 nike

我正在尝试编写 3 剪切旋转算法的 Java 实现 described by Alan Paeth .问题不在于值的计算,而在于将旋转的点拟合到图像网格上。在论文中,旋转是由以下计算给出的 3 个连续剪切执行的:

  1. x = x + α * y
  2. y= y + beta * x
  3. x = x + alpha * y

Alpha 和 Beta 是根据给定的角度(theta;以弧度为单位)通过以下公式计算得出的:

  • beta = sin(theta)
  • alpha = - tan(theta/2)

使用这些公式,点围绕坐标系的中心旋转。

为了更正负值,我将各自轴的最小计算坐标添加到每个点,以便最小值始终为 0。

到目前为止我的 Java 实现:

ShiftPoint[] val = new ShiftPoint[m*n];
double minX = 0,minY = 0, maxX = 0, maxY = 0;
double alpha = -1d* Math.tan(Math.toRadians(theta)/2d);
double beta = Math.sin(Math.toRadians(theta));
for(int a = 0; a < m; a++) {
for(int b = 0; b < n; b++) {
ShiftPoint temp = new ShiftPoint(a, b, values[a][b]);
double newX = b + alpha * a; //first shear
double newY = a + beta * newX; //second shear
newX += alpha * newY; //third shear
temp.setX(newX);
temp.setY(newY);
val[m * b + b] = temp;
}
}

注意: ShiftPoint 是一个简单的自写类,用于保存特定坐标和矩阵内的值(在图像处理的情况下:像素的 rgb 值)。这是计算的图形表示: enter image description here

问题:虽然计算值似乎是正确的并且图形表示显示旋转确实有效,但我不确定如何在图像(或二维数组)具有的固定网格上拟合计算值而不扭曲它。我也不完全理解 Paeths 论文中给出的实现(对于 x 轴剪切):

enter image description here

我知道 skewi 是计算值的整数部分,skewf 是小数部分,但是 width、height、oleft 和 left 应该是什么?另外:为什么他在第一次计算时将 y 值加 0.5 而没有考虑 x 值?

注意:我知道 Java 提供了旋转图像的简单方法,但我只是为了好玩而尝试实现这个特定的算法。我也知道可以通过网络搜索找到 3 - 5 个网站(例如 #1#2 )并尝试解释该算法,但首先他们不使用 java,其次他们主要引用示例实现由 Paeth 编写,因此它们不是很有用。

最佳答案

这种图像旋转方法背后的基本原则是双重的:

  • 定义一个坐标变换,将旋转图像中的 x 和 y 轴旋转到原始图像的 x 和 y 轴上
  • 通过在原始图像中对应点附近的值之间进行插值来计算旋转图像中的每个像素

第一步通常比较容易,涉及 x 和 y 坐标的简单线性组合。剪切变换(严格来说不是旋转,因为它们不保留每个像素的面积)只涉及 x -> x + alpha * y 之类的东西。

Paeth 的论文(可追溯到 1986 年)中给出的算法似乎是一种经过精心优化的方法,用于执行剪切变换的第二(插值)步骤。我认为这归结为沿 x 轴的分段线性插值,但以一种不需要对输出图像中的每个像素进行多次数组查找的形式编写。更清晰(但效率稍低)的方法可能涉及 skewf * pixel(x-skewi-1, y) + (1-skewf) * pixel(x-skewi, y)。

这种特殊的算法显然高度专门用于单轴倾斜。对于一般轮换,您可能需要更像 bilinear interpolation 的东西在每个 2x2 正方形像素上,这些像素围绕着与旋转图像中每个像素中心相对应的未旋转位置。 (计算这个中心像素值可能是 Paeth 代码中 y+0.5 的来源。)

考虑到我们现在拥有相对于 1986 年的计算能力,我怀疑如果您为这个双线性插值包含一个明确的公式,您的代码会更容易理解,即使它确实使用比 Paeth 的方法更多的数组查找,除非您真的需要最高性能。

关于java - 通过剪切任意角度旋转(Paeth算法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47619685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com