이미지의 기하학적 변환

from MFC 2013. 5. 9. 11:02

픽셀의 확대,축소,회전, 상하좌우 역전,이동 등

 

순방향및 역방향

순방향은 그대로 기하학 처리하면 홀과 오버랩이 발생할 우려가 있다.

역방향은 이미 존재하는 원본영상에서 대응하는 픽셀들을 집어올 수 있으므로 홀이 생길 이유가 없다.

 

#include<math.h>를 사용하면

반올림:round(), 올림:ceil(); 내림:floor() 함수로 쉽게 구현할 수 있다.

 

오늘은 연산자의 기본에 대해 좀 공부를 했다.

L value : 메모리 공간

R value : 어떤값

참고로 증감연산자는 우선순위가 가장 높으며 L value가 무조건 필요하다.

 

참고로 a++이나 ++a나 기능은 똑같은거지만

a++는 업데이트 없이 오리지날값을 리턴하고, ++a는 업데이트된 값을 리턴하는것이다.

또한 증감연산자의 처리는 시스템마다 처리 방식이 다르므로 절대 같은 라인에 두번 이상 쓰지 않는게 좋다.

 

이제 다시 본분으로 돌아와서 기하학 처리로 돌아가자.

일단 이미지확대(줌인)부터 살펴보자.

void CtestDoc::OnZoomIn()
{
 // TODO: 여기에 명령 처리기 코드를 추가합니다.
 double scale = 1.6;
 int X_max = (int)(256*scale);
 int Y_max = (int)(256*scale);
 double x,y;
 int x_org, y_org;
 unsigned char *ZoomImage;

 ZoomImage = new unsigned char[Y_max * X_max];

 for(int y_new=0; y_new <Y_max; y_new++){
  for(int x_new=0; x_new < X_max; x_new++){
   x=x_new/scale;
   y=y_new/scale;
  
  x_org = (int)(x+0.5);
  y_org = (int)(y+0.5);

  if(x_org<0 || x_org>255 || y_org<0 || y_org>255){
   ZoomImage[y_new * X_max + x_new]=0;
  }
  else
   ZoomImage[y_new * X_max + x_new] = m_InputImage[y_org][x_org];
  
  }
 }

 for(int i=0; i<256; i++){
  for(int j=0; j<256; j++){
   m_OutputImage[i][j] = ZoomImage[i*X_max+j];
  }
 }
 delete[] ZoomImage;
 UpdateAllViews (NULL);
}
//출력결과

 

 

이미지 축소

void CtestDoc::OnZoomout()
{
 // TODO: 여기에 명령 처리기 코드를 추가합니다.
 double scale = 0.7;
 int X_max = (int)(256*scale);
 int Y_max = (int)(256*scale);
 double x, y;
 int x_org, y_org;
 unsigned char *ZoomImage;
 ZoomImage = new unsigned char[Y_max * X_max];
 for(int y_new = 0; y_new<Y_max; y_new++){
  for(int x_new=0; x_new<X_max; x_new++){
   x=x_new/scale;
   y=y_new/scale;

   x_org = (int)(x+0.5);
   y_org = (int)(y+0.5);
   if(x_org<0 || x_org>255 || y_org<0 || y_org>255){
    ZoomImage[y_new * X_max + x_new] = 0;
   }
   else
    ZoomImage[y_new * X_max + x_new] = m_InputImage[y_org][x_org];
  }
 }

 for(int i=0; i<Y_max; i++){
  for(int j=0; j<X_max; j++){
   m_OutputImage[i][j] = ZoomImage[i*X_max+j];
  }
 }
 delete[] ZoomImage;
 UpdateAllViews(NULL); 
}

 //출력결과

 

이미지 회전

void CtestDoc::OnRotation()
{
 // TODO: 여기에 명령 처리기 코드를 추가합니다.
 double rotationAngle = 135;
 int x_center=128;
 int y_center=128;
 double rotationAngleRad = (rotationAngle*3.13159265/180);
 double cosValue, sinValue;
 
 double x,y;
 int x_org, y_org;

 for(int y_new=0; y_new<256; y_new++){
  for(int x_new=0; x_new<256; x_new++){
   cosValue = cos(rotationAngleRad);
   sinValue = sin(rotationAngleRad);

   x=cosValue*(x_new - x_center) + sinValue * (y_new-y_center) + x_center;
   y=-sinValue*(x_new - x_center) + cosValue * (y_new-y_center) + y_center;

   x_org = (int)(x+0.5);
   y_org = (int)(y+0.5);

   if(x_org<0 || x_org>255 || y_org<0 || y_org>255){
    m_OutputImage[y_new][x_new] = 0;
   }
   else
    m_OutputImage[y_new][x_new] = m_InputImage[y_org][x_org];
  }
 }
 UpdateAllViews(NULL);
}

 

//결과

 

,