|
Rotation operator rotates a pixel by a degree θ from position (x1, y1) to (x2, y2). Overflowed new positions (x2, y2) are mostly ignored. Rotation process is generally used to correct images. Equation (1) is the process formula to find new x2 and y2.
(1)
x0, y0 : center of coordinate system.
As we know a pixel is in 3-byte integer format. Because sin and cos conversions must be truncated many parts of image corrupt and becomes pixelized. To overcome this problem a simple technique can be used. When pixels are intersected after rotating, it is searched for neighborhood relations and it is put in an empty nearby location.
(a)
 (b) (c)
Figure 1. Angelina (a) original image, (b) +45° rotated counter-clock wise and (c) -45° rotated clockwise.
C Source Code
Below there is only rotation procedure. You can reach complete source code from here.
int Rotate_Arbitrary(long **img_data, long **s_tmp, double angle, long width, long height) { long i, j, origin_x, origin_y, x2, y2, in_ragion; double x1, y1;
for(i=0;i<height;i++) { for(j=0;j<width;j++) { s_tmp[i][j] = -1; } } // origin is the middle of image origin_x = width/2; origin_y = height/2;
for(i=0;i<height;i++) { for(j=0;j<width;j++) { // calculate the new place of i,j x1 = j - origin_x; y1 = i - origin_y; x2 = cos(angle * TO_RAD)*x1 - sin(angle * TO_RAD)*y1 + origin_x; y2 = sin(angle * TO_RAD)*x1 + cos(angle * TO_RAD)*y1 + origin_y;
if ( (y2 >= 0) && (y2 < height) && (x2 >= 0) && (x2 < width)) { if (s_tmp[y2][x2] == -1) s_tmp[y2][x2] = img_data[i][j]; else { // is this coordinates in the ragion or outside? if (((y2-1) >= 0) && ((y2+1) < height)&&((x2-1) >= 0)&&((x2+1) < width)) in_ragion = 1; else in_ragion = 0; // check the neighbours and if it is -1 set it as rotated pixel if ((in_ragion == 1) && (s_tmp[y2-1][x2] == -1) ) s_tmp[y2-1][x2] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2-1][x2+1] == -1)) s_tmp[y2-1][x2+1] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2+1][x2] == -1)) s_tmp[y2+1][x2] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2+1][x2+1] == -1)) s_tmp[y2+1][x2+1] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2+1][x2] == -1)) s_tmp[y2+1][x2] = img_data[i][j]; if ((in_ragion == 1) &&(s_tmp[y2+1][x2-1] == -1)) s_tmp[y2+1][x2-1] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2][x2-1] == -1)) s_tmp[y2][x2-1] = img_data[i][j]; if ((in_ragion == 1) && (s_tmp[y2-1][x2-1] == -1)) s_tmp[y2-1][x2-1] = img_data[i][j]; } } } }
for(i=0;i<height;i++) { for(j=0;j<width;j++) { if (s_tmp[i][j] == -1) img_data[i][j] = 0; else img_data[i][j] = s_tmp[i][j]; } }
return 0; } References
[1]: Robert Fisher, Simon Perkins, Ashley Walker, Erik Wolfart, “HYPERMEDIA IMAGE PROCESSING REFERENCE”, http://www.dai.ed.ac.uk/HIPR2/, 2002.
|