将一个二维像素数组旋转90度

12

我有一个像素数据数组,用于表示一张图像。我获取的图像已经被旋转了270度。因此,我尝试再次将其旋转90度以获得正确的图像。我尝试使用转置算法,通过将data[x][y]更改为data[y][x],但我认为这不是正确的方法。请问有没有人可以指导我如何进行旋转?


那是唯一的方法。你可以并行处理来加快速度。 - Eddy_Em
4个回答

25

如果您有old_data[rows][cols]new_data[cols][rows],则:

for(int i=0; i<cols; i++) {
    for(int j=0; j<rows; j++) {
        new_data[i][j] = old_data[rows-1-j][i];
    }
}

这应该将 old_data 顺时针旋转90度。


是的,没错。我用一个小矩阵试过了。 :) 只要确保输入图像的顺序为MxN,则输出图像的顺序为NxM。 - raj raj
谢谢,我现在正在尝试。 - 0xC0DED00D

16

如果您想使用O(1)空间就地进行操作,可以按照以下步骤进行:

  1. 通过交换 data [i] [j] data [j] [i] 来转置矩阵:

for (int i = 0; i < n; i += 1) {
    for (int j = i+1; j < n; j += 1) {
        swap(data[i][j], data[j][i]);
    }
}
  • 将每行或每列反转,分别进行+90度或-90度的旋转。例如,对于+90度的旋转:

  • for (int i = 0; i < n; i += 1) {
        for (int j = 0; j < n/2; j += 1) {
            swap(data[i][j], data[i][n-1-j]);
        }
    }
    

    12
    这可以在不使用任何额外空间的情况下完成,称为 原地矩阵转置(不完全相同)。记得在转置后进行一些镜像操作。
    1. 如果图像是正方形
    如果图像是正方形,则:
    2. 如果图像不是正方形
    对于非正方形矩阵,算法更加复杂。1980年之前的许多算法可以描述为“跟随循环”算法。也就是说,它们循环遍历循环,并将数据从循环中的一个位置移动到下一个位置。伪代码如下:

    3

    要将图像(2D矩阵)旋转90度,您可以通过在旋转90度后的初始状态和最终状态之间映射出一种模式来轻松完成此操作。


    a[i][j] => a[m][n]
    a[0][0] => a[0][2]
    a[0][1] => a[1][2]
    a[0][2] => a[2][2]
    a[1][0] => a[0][1]
    a[1][1] => a[1][1]
    a[1][2] => a[2][1]
    a[2][0] => a[0][0]
    a[2][1] => a[1][0]
    a[2][2] => a[2][0]
    

    现在解决方案很明显。所有的J都转换成M和N = (矩阵大小(2) - I)。

    const rotateImage = (a) => {
      let size = a.length;
      let results = new Array(size);
      for (let i = 0; i < size; i++) {
        results[i] = new Array(size);
      }
      for (let i = 0; i < size; i++) {
        for (let j = 0; j < size; j++) {
          results[j][(size - 1) - i] = a[i][j];
        }
      }
      return results;
    }
    
    console.log(rotateImage([
      [1, 2, 3],
      [4, 5, 6],
      [7, 8, 9]
    ]));


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接