Rotating a 2D Pixel Array by 90 Degrees

Rotating a 2D pixel array by 90 degrees

This can be done without using any extra space, so called In-place matrix transposition (not exact the same). Remember to do some mirroring after the transposition.

  1. If the image is square

    Sample Image

  2. If the image is not square

    • For non-square matrices, the algorithms are more complicated. Many of the algorithms prior to 1980 could be described as "follow-the-cycles" algorithms. That is, they loop over the cycles, moving the data from one location to the next in the cycle. In pseudocode form:

    Sample Image

C - Rotate a image by 90 degree (right and left) using one array - bitmap

You can use the rotation matrix.
The rotation matrix for 90 degrees is simply

  [0 -1
1 0]

here you can see how to do matrix multiplication in c if you need.

How do you rotate a two dimensional array?

Here it is in C#

int[,] array = new int[4,4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 }
};

int[,] rotated = RotateMatrix(array, 4);

static int[,] RotateMatrix(int[,] matrix, int n) {
int[,] ret = new int[n, n];

for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
ret[i, j] = matrix[n - j - 1, i];
}
}

return ret;
}

Algorithm to rotate an image 90 degrees in place? (No extra memory)

This might help: In-place matrix transposition.

(You might also have to do some mirroring after the transposition, as rlbond mentions).

Rotating a bitmap and transform the resulting coordinates in float format back to integer x,y values for pixel array

What if you invert the rotation and calculate backwards

new_x, new_x -> old_x, old_y

That would resolve the rounding errors.

for new_pixel_coordinates:
old_pixel_coordinates = inverse_rotate(new_pixel_coordinates)
color = lookup_color(old_bitmap, old_pixel_coordinates)
color_new_picture(new_bitmap, new_pixel_coordinates, color)

python rotate image by 90 degrees without using any libs

You can rotate a grid of pixels by 90° by a combination of transposition and reflection. You can do this in pure Python by using zip to transpose, and reversed to reflect.

Here's a short demo that does a 90° clockwise rotation.

# Some fake pixels
data = [
[(100, 101, 102), (105, 106, 107), (110, 111, 112), (115, 116, 117)],
[(120, 121, 122), (125, 126, 127), (130, 131, 132), (135, 136, 137)],
[(140, 141, 142), (145, 146, 147), (150, 151, 152), (155, 156, 157)],
[(160, 161, 162), (165, 166, 167), (170, 171, 172), (175, 176, 177)],
[(180, 181, 182), (185, 186, 187), (190, 191, 192), (195, 196, 197)],
]

new = [list(reversed(t)) for t in zip(*data)]
for row in new:
print(row)

output

[(180, 181, 182), (160, 161, 162), (140, 141, 142), (120, 121, 122), (100, 101, 102)]
[(185, 186, 187), (165, 166, 167), (145, 146, 147), (125, 126, 127), (105, 106, 107)]
[(190, 191, 192), (170, 171, 172), (150, 151, 152), (130, 131, 132), (110, 111, 112)]
[(195, 196, 197), (175, 176, 177), (155, 156, 157), (135, 136, 137), (115, 116, 117)]

But seriously, it's faster (and simpler) to do this sort of thing with a library, unless the images are really small. If you don't want to use PIL, you can do it with Numpy.

How can I rotate a 2d array by LESS than 90°, to the best approximation?

Ok here it is as promised. First C++ code:

//---------------------------------------------------------------------------
#include <math.h>
//---------------------------------------------------------------------------
const int xs=7; // matrix size
const int ys=7;
const int x0=3; // rotation center cell
const int y0=3;
const float deg=M_PI/180.0;
int A[xs][ys]=
{
{0,0,0,9,0,0,0},
{0,0,0,9,0,0,0},
{0,0,0,9,0,0,0},
{9,9,9,9,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
};
int B[xs][ys];
//---------------------------------------------------------------------------
void rotcw(int x0,int y0,float ang) // rotate A -> B by angle ang around (x0,y0) CW if ang>0
{
int x,y,ix0,iy0,ix1,iy1,q;
float xx,yy,fx,fy,c,s;
// circle kernel
c=cos(-ang); s=sin(-ang);
// rotate
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
// offset so (0,0) is center of rotation
xx=x-x0;
yy=y-y0;
// rotate (fx,fy) by ang
fx=float((xx*c)-(yy*s));
fy=float((xx*s)+(yy*c));
// offset back and convert to ints and weights
fx+=x0; ix0=floor(fx); fx-=ix0; ix1=ix0+1; if (ix1>=xs) ix1=ix0;
fy+=y0; iy0=floor(fy); fy-=iy0; iy1=iy0+1; if (iy1>=ys) iy1=iy0;
// bilinear interpolation A[ix0+fx][iy0+fy] -> B[x][y]
if ((ix0>=0)&&(ix0<xs)&&(iy0>=0)&&(iy0<ys))
{
xx=float(A[ix0][iy0])+(float(A[ix1][iy0]-A[ix0][iy0])*fx);
yy=float(A[ix0][iy0])+(float(A[ix1][iy0]-A[ix0][iy0])*fx);
xx=xx+((yy-xx)*fy); q=xx;
} else q=0;
B[x][y]=q;
}
}
//---------------------------------------------------------------------------

Here 7x7 preview 15 deg steps:

preview

It may be need a bit tweaking of the center by half of cell or something (the center is bleeding too much to my liking)

Matrix A is source and B is target ...

You can also add tresholding ... like:

if (q>=5) q=9; else q=0;


Related Topics



Leave a reply



Submit