본문 바로가기
Theory/Image Processing

13 기하학적 변환 (22.11.25)

by Orangetasteboy 2023. 6. 22.

이동 변환

  • 이동 변환 실행 결과

 

영상 회전

  • 회전 변환
 
  • 45도 회전에서 출력 영상의 좌표가 정수가 아님
  • 그림과 같이 구현 가능한가?
    • 출력영상도 정수 좌표에만 값이 존재해야 한다!!
img_out[0][0] = img[0][0];
img_out[70.7][70.7] = img[100][0];
img_out[70.7][-70.7] = img[0][100];
img_out[141.4][0] = img[100][100];

 

  • 회전 변환의 역변환
  • 회전 변환 : 영상의 어떤 점을 중심으로 회전시키기

 

  • 프로그래밍 : 영상 회전 시키기
    • cos, sin 함수로 인해 그 결과는 실수값을 가짐
void Rotation(double theta, int** img, int height, int width, int** img_out)
{
    double rad = theta/180.0 * CV_PI; // degree  rad로 변환

    for (int y_prime = 0; y_prime < height; y_prime ++) {
        for (int x_prime = 0; x_prime < width; x_prime ++) {

              int y = -x_prime*sin(rad) + y_prime*cos(rad); 
              int x = x_prime*cos(rad) + y_prime*sin(rad);

              if (x < 0 || x >= width || y < 0 || y >= height) continue;
              else img_out[y_prime][x_prime] = BilinearInterpolation(y, x, img, height, width);
        }
    }
}

 

  • 영상 회전 실행 결과
 
  • 프로그래밍 : 영상 중심을 축으로 영상 회전 시키기
  • 영상 회전 실행 결과

 

어파인 변환

  • 영상 가운데를 중심으로 한 변환식
  • 변환식
  • 어파인 변환은 너무 많은 경우의 수를 포함하므로, 영상의 가운데를 중심으로 적용되는 경우만으로 제한
void AffineTransform(double a, double b, double c, double d, 
	int y0, int x0, int y0_prime, int x0_prime,
	int** img, int height, int width, int** img_out)
{
   double a_prime = d / (a*d - b*c), b_prime = -b / (a*d - b*c);
   double c_prime = -c / (a*d - b*c), d_prime = a / (a*d - b*c);

   for (int y_prime = 0; y_prime < height; y_prime++) {
        for (int x_prime = 0; x_prime < width; x_prime++) {

             int y = c_prime * (x_prime - x0_prime) + d_prime * (y_prime - y0_prime) + y0;
             int x = a_prime * (x_prime - x0_prime) + b_prime * (y_prime - y0_prime) + x0;

             if (x < 0 || x >= width || y < 0 || y >= height) continue;
             else img_out[y_prime][x_prime] = BilinearInterpolation(y, x, img, height, width);
        }
   }
}
void AffineTransform(double a, double b, double c, double d, 
	int y0, int x0, int y0_prime, int x0_prime,
	int** img, int height, int width, int** img_out);
void main()
{
   int height, width;
   int** img = (int**)ReadImage("lena.png", &height, &width);
   int** img_out = (int**)IntAlloc2(height, width);
 
   // 어파인 변환 계수 설정
   double a = 1.0, b = 0.0;
   double c = 0.0, d = 1.0;
   // 입력 영상 및 출력 영상의 가운데를 회전축으로 설정
   int y0 = height / 2, x0 = width / 2;
   int y0_prime = height / 2, x0_prime = width / 2;

   AffineTransform(a, b, c, d, y0, x0, y0_prime, x0_prime, img, height, width, img_out);

   ImageShow("입력영상보기", img, height, width);
   ImageShow("출력영상보기", img_out, height, width);
}

 

  • 어파인 변환 실행 결과

댓글