/* affine.c */ #include #include #include #include "mypgm.h" #define BLACK 0 #define WHITE 255 #define PI 3.141592654 void affine(double x_rot, double y_rot, double x_expan, double y_expan, int x_move, int y_move) /* affine transformation of input image */ /* by backward transformation and bilinear interpolation */ /* input: image1[y][x] -------- output: image2[y][x] */ { double affine[2][2], beta[2]; double det, i_affine[2][2], i_beta[2]; double x_new, y_new, x_frac, y_frac; double gray_new; int gv_new; int x, y, m, n; x_size2 = x_size1; y_size2 = y_size1; /* forward affine transformation */ affine[0][0] = x_expan * cos(x_rot*PI/180.0); affine[0][1] = y_expan * sin(y_rot*PI/180.0); affine[1][0] = x_expan * sin(x_rot*PI/180.0); affine[1][1] = y_expan * cos(y_rot*PI/180.0); beta[0] = x_move; beta[1] = y_move; /* determination of inverse affine transformation */ det = affine[0][0]*affine[1][1] - affine[0][1]*affine[1][0]; if (det == 0.0) { i_affine[0][0] = 1.0; i_affine[0][1] = 0.0; i_affine[1][0] = 0.0; i_affine[1][1] = 1.0; i_beta[0] = -beta[0]; i_beta[1] = -beta[1]; } else { i_affine[0][0] = affine[1][1]/det; i_affine[0][1] = -affine[0][1]/det; i_affine[1][0] = -affine[1][0]/det; i_affine[1][1] = affine[0][0]/det; i_beta[0] = -i_affine[0][0]*beta[0]-i_affine[0][1]*beta[1]; i_beta[1] = -i_affine[1][0]*beta[0]-i_affine[1][1]*beta[1]; } /* output image generation by inverse affine transformation and bilinear transformation */ for (y = 0; y < y_size2; y++) { for (x = 0; x < x_size2; x++) { x_new = i_beta[0] + i_affine[0][0]*(x-x_size2/2.0) + i_affine[0][1]*(y-y_size2/2.0) + x_size2/2.0; y_new = i_beta[1] + i_affine[1][0]*(x-x_size2/2.0) + i_affine[1][1]*(y-y_size2/2.0) + y_size2/2.0; m = (int)floor(x_new); n = (int)floor(y_new); x_frac = x_new - m; y_frac = y_new - n; if (m >= 0 && m+1 < x_size2 && n >= 0 && n+1 < y_size2) { gray_new = (1.0 - y_frac)*((1.0 - x_frac)*image1[n][m] + x_frac *image1[n][m+1]) + y_frac *((1.0 - x_frac)*image1[n+1][m] + x_frac *image1[n+1][m+1]); image2[y][x] = (unsigned char)gray_new; } else if (m+1 == x_size2 && n >= 0 && n < y_size2 || n+1 == y_size2 && m >= 0 && m < x_size2) { image2[y][x] = image1[n][m]; } else { image2[y][x] = WHITE; } } } } main( ) { double x_rot, y_rot, x_expan, y_expan; int x_move, y_move; load_image_data( ); /* Input of image1 */ /* affine parameters specification */ printf("Please enter affine parameters!\n\n"); printf("X rotation degrees (in real) = "); scanf("%lf", &x_rot); printf("Y rotation degrees (in real) = "); scanf("%lf", &y_rot); printf("X expansion rate (in real) = "); scanf("%lf", &x_expan); printf("Y expansion rate (in real) = "); scanf("%lf", &y_expan); printf("X translation (in integer) = "); scanf("%d", &x_move); printf("Y translation (in integer) = "); scanf("%d", &y_move); printf("\n"); affine(x_rot, y_rot, x_expan, y_expan, x_move, y_move); save_image_data( ); /* Output of image2 */ return 0; }