Presentation is loading. Please wait.

Presentation is loading. Please wait.

제 5 장 기하학적 처리.

Similar presentations


Presentation on theme: "제 5 장 기하학적 처리."— Presentation transcript:

1 제 5 장 기하학적 처리

2 학습목표 다음 기하학적 처리의 개념을 설명할 수 있고 프로그램을 작성할 수 있다 역방향 사상과 보간법에 대해 설명할 수 있다
확대 축소 회전 대칭 역방향 사상과 보간법에 대해 설명할 수 있다

3 개 요 기하학적 처리란? 임의의 기하학적 변환에 의하여 화소들의 위치를 변경하는 처리 확대/축소 회전 이동

4 확대(픽셀 복제 방법) 배율만큼 픽셀을 반복적으로 복사 확대 배율이 정수일 경우에 사용가능
100 110 120 130 100 110 120 130 <가로 세로 방향으로 두 배씩 확대>

5 확대(픽셀 복제 방법) 픽셀 단위의 세밀한 편집에 활용 <원래 영상>
<영상을 8배 확대하여 편집하는 화면>

6 확대(픽셀 복제 방법) - 단점 확대된 영상에 계단 현상 발생 영상이 매끄럽지 못함 확대 배율이 실수인 경우 처리 어려움

7 역방향 사상과 양선형 보간법 확대 결과 영상에서 계단 현상을 줄일 수 있음 확대 비율이 실수이어도 처리 가능

8 역방향 사상 역방향 사상 역방향 사상 가로 세로 방향으로 2배씩 확대하는 경우의 역방향 사상 입력 영상 출력 영상

9 보간법 (Interpolation) 역방향 사상의 결과가 정수가 아닐 수 있음
목적 영상 화소 (1,1)은 원시 영상의 (0.5, 0.5)로 사상됨  (0.5, 0.5)는 원시 영상에 존재하지 않음  (0,0), (0,1), (1,0), (1,1) 화소들을 보간함으로써 해결

10 보간법 입력 영상의 화소 값 계산 방법 역방향 사상에 의해 계산된 점 주위의 네 개의 화소들의 값에 가중치를 곱하여 합함
원시 화소 E A B X축 보간 화소 최종 보간 화소 X 역방향 사상의 결과가 정수가 아니어서 입력 영상에서 픽셀값을 곧바로 구할 수 없을때에 픽셀값을 계산하는 방법을 살펴 보겠습니다. 역방향 사상에 의해 계산된 주소가 정수가 아닐 때의 상황을 그림으로 도식화하면 아래 그림과 같습니다. 그림에서 보라색 마름모꼴로 표시된 위치는 역방향 사상에 의해 계산된 위치를 나타냅니다. 역방향 사상의 값이 어떻게 되든지 그 주위에는 그림과 같이 청록색으로 표시되어 있는 4개의 픽셀이 위치하게 됩니다. 역방향 사상된 위치의 픽셀 값을 X라고 하고 주위의 4개의 픽셀 값을 A, B, C, D라 할때에 X값을 계산하는 식이 그림 오른쪽에 나타나 있습니다. 식에서 알파와 베타는 역방향 사상된 위치가 좌측 상단 픽셀로부터 얼마 만큼 떨어져 있는지의 비율을 나타내는 값으로써 0에서 1까지의 값을 가집니다. 식에서는 A, B 값과 알파 값을 이용하여 E 값과 F 값을 먼저 구하고 있습니다. E 값과 F 값은 좌측 픽셀로부터 떨어져있는 거리에 비례하여 값이 변하게 됩니다. 예를 들어 A의 값의 0이고 B위 값이 100일 경우에 알파가 0.5이면 E의 값은 50이되고 알파가 0.1이면 E의 값은 10이 되며 알파가 0.7이면 E의 값은 70이 됩니다. 즉 좌측 픽셀이 0이고 우측 픽셀이 100이므로 좌측에서 우측으로 이동할 수록 값이 커지는 것을 알 수 있습니다. E와 F값을 구한 다음에는 E와 F 그리고 베타 값을 이용하여 X값을 구합니다. 즉, 세로 방향으로 어느 위치에 있는지에 비례하여 X값이 결정됩니다. 예를 들어 E가 50이고 F가 100이고 베타가 0.5라면 X위 값은 50과 100의 중간 값인 75가 될 것입니다. 이상에서 살펴보았듯이 자로 방향으로 보간을 수행한 다음에 세로 방향으로 보간을 한번더 수행하므로 이를 양선형 보간법이라고 합니다 가로 방향과 세로 방향 각각은 값이 알파와 베타의 1차식에 따라 변화하므로 선형보간이라하고 가로 방향의 선형 보간을 수행 한 다음에 세로 방향의 선형 보간을 수행하므로 양선형 보간이라 하는 것입니다. C D F 10 10

11 보간법 적용 예 (1,1) 100 110 120 130 I(0.5, 0.5)의 주위 네 픽셀 : I(0,0)=100, I(0,1)=110, I(1,0)=120, I(1,1)=130 가로 방향 보간 : E(0, 0.5) = I(0,0)*0.5 + I(0,1)*0.5 = 100* *0.5 = 105 F(1, 0.5) = I(1,0)*0.5 + I(1,1)*0.5 = 120* *0.5 = 125 세로 방향 보간 : O(0.5, 0.5) = E(0, 0.5)*0.5 + F(1, 0.5)*0.5 = 105 * * 0.5 = 115 11

12 축소(서브샘플링 방법 이용) 서브샘플링 축소 배율만큼 건너뛰면서 픽셀 값을 취하는 방법 예) x, y 방향으로 2배씩 축소
모든 짝수 행과 열의 화소를 출력 영상에 복사 문제점 영상의 상세한 세부 항목을 상실 해결책 서브샘플링 전에 영상을 흐리게 하여 어느 정도 해결 가능

13 축소(서브샘플링 방법 이용) 서브샘플링에 의한 축소

14 축소(서브샘플링 방법 이용) 서브샘플링에 의한 축소의 문제점 영상의 세밀한 정보를 잃어버릴 수 있음

15 축소(서브샘플링 방법 이용) 영상을 흐리게 한 다음 서브샘플링 적용

16 축소(평균값 필터링 방법 이용) 블록을 평균값으로 대치 평균값 입력 영상 출력 영상 13 4 8 2 9 6 7 25 16 10

17 축소(평균값 필터링 방법 이용) 예) <출력 영상> <입력 영상>

18 축소(평균값 필터링 방법 이용)

19 회전 원점을 중심으로 점 (xsource,ysource)를 반시계 방향으로 θ만큼 회전한 점 (xdest, ydest)

20 회전의 고려 사항 - 1 전방향 사상을 이용한 회전 <전방향 사상 이용>
출력 영상에서 픽셀 값을 할당 받지 못한 빈 곳이 발생 <전방향 사상 이용>

21 회전의 고려 사항 - 1 역방향 사상을 이용하여 문제 해결 <시계방향으로 회전>
원점을 중심으로 점 (xdest, ydest) 를 시계 방향으로 θ만큼 회전한 점이 (xsource,ysource)가 됨 θ ( x source ,y ) dest , y <시계방향으로 회전>

22 회전의 고려 사항 - 2 회전의 중심 앞에서 사용한 식은 원점을 기준으로 한 회전임 결과 영상에서 잘리는 부분이 많이 발생
 영상의 중심점을 기준으로 한 회전으로 문제 해결 <입력 영상> <원점 기준 회전> <영상 중심점 기준 회전>

23 회전의 고려 사항 - 2 영상의 중심점 (Cx, Cy)를 기준으로 하는 회전

24 회전의 고려 사항 - 3 화면 좌표계와 수학적 좌표계
화면 좌표계 : 좌측 상단이 원점 수학적 좌표계 : 좌측 하단이 원점 두 좌표계의 차이로 인하여 영상이 반시계 방향으로 회전되지 않고 시계 방향으로 회전됨 화면 좌표를 수학적 좌표로 변환한 다음에 회전시키고 다시 화면 좌표로 변환함으로써 문제 해결

25 회전의 고려 사항 - 3 좌표계 변환 후 회전

26 회전의 고려 사항 - 3 좌표계 변환과 회전 결과 반시계 방향으로 30도 회전 입력 영상 좌표계 변환을 하지 않은 경우
한 경우

27 회전의 고려사항 - 4 출력 영상의 크기 고려 입력 영상과 출력 영상의 크기를 같게 하면 출력 영상에서 잘려나가는 부분이 발생
출력 영상의 크기를 미리 계산하여 역방향 사상을 적용해야 함 출력 영상의 크기 회전 각도에 따라 달라짐

28 회전의 고려 사항 - 4 출력 영상의 크기 계산 방법 W H’ H a b c W’ W’ H’ W’ H’ W : 입력 영상의
너비 y H : 입력 영상의 높이 W’ : 출력 영상의 너비 H’ : 출력 영상의 높이 W 90 - θ W cos (90 - θ ) H’ H a b θ H cos θ θ 90 - θ c x H cos (90 - θ ) W cos θ W’ W’ = H cos (90 - θ ) + W cos θ H’ = H cos θ + W cos (90 θ )

29 회전의 고려 사항 - 4 출력 영상의 크기를 고려한 회전 입력 영상 출력 영상

30 대칭 입력 영상 좌우 대칭 상하 대칭

31 대칭 변환의 구현 (흑백 영상) 좌우 대칭 상하 대칭 for (y = 0; y < imageHeight; y++)
for (x = 0; x < imageWidth; x++) resultImg[y][x] = inputImg[y][imageWidth x]; for (y = 0; y < imageHeight; y++) for (x = 0; x < imageWidth; x++) resultImg[imageHeight y][x] = inputImg[y][x];

32 실습

33 픽셀 복제 방법을 이용한 확대 메뉴막대에 [기하학적처리] 메뉴 추가 부메뉴 추가 메뉴 이름 : 기하학적 처리
이름 : 확대(픽셀 복제) ID : ID_GEOMETRY_ZOOMIN_PIXEL_COPY

34 픽셀 복제 방법을 이용한 확대 CImageProView 클래스에 OnGeometryZoominPixelCopy() 함수를 추가하고 다음과 같이 편집 void CImageProView::OnGeometryZoominPixelCopy() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->GeometryZoominPixelCopy(); viewMode = TWO_IMAGES_SCALED; Invalidate(FALSE); }

35 픽셀 복제 방법을 이용한 확대 ImageProView.cpp 파일의 앞부분에 상수 정의 추가 // 추가한 후
#define TWO_IMAGES #define THREE_IMAGES #define TWO_IMAGES_SCALED 4

36 픽셀 복제 방법을 이용한 확대 CImageProDoc 클래스에 GeometryZoominPixelCopy() 함수 추가하고 편집 void CImageProDoc::GeometryZoominPixelCopy() { int i, y, x; gImageWidth = imageWidth * 3; gImageHeight = imageHeight * 3; gResultImg = (unsigned char **) malloc(gImageHeight * sizeof(unsigned char *)); for (i = 0; i < gImageHeight; i++) { gResultImg[i] = (unsigned char *) malloc(gImageWidth * depth); } for (y = 0; y < gImageHeight; y++) for (x = 0; x < gImageWidth; x++) gResultImg[y][x] = inputImg[y/3][x/3];

37 픽셀 복제 방법을 이용한 확대 확대 결과 영상 저장을 위한 변수 선언 // Attributes public:
unsigned char **inputImg; // 입력 영상의 기억 장소에 대한 포인터 변수 unsigned char **inputImg2; // 입력 영상의 기억 장소에 대한 포인터 변수 unsigned char **resultImg; // 출력 영상의 기억 장소에 대한 포인터 변수 int imageWidth; // 영상의 가로 크기 int imageHeight; // 영상의 세로 크기 int depth; // 1 = 흑백 영상, 3 = 컬러 영상 // 결과 영상의 크기가 변화되는 기하학적 처리를 위해 새로이 추가되는 코드 int gImageWidth; // 크기가 변한 결과 영상의 가로 크기 int gImageHeight; // 크기가 변한 결과 영상의 세로 크기 unsigned char **gResultImg; // 크기가 변한 결과 영상에 대한 포인터 변수

38 픽셀 복제 방법을 이용한 확대 gResultImg 변수값 초기화 CImageProDoc::CImageProDoc() {
// TODO: add one-time construction code here inputImg = NULL; inputImg2 = NULL; resultImg = NULL; gResultImg = NULL; // 추가되는 코드 }

39 픽셀 복제 방법을 이용한 확대 OnDraw() 함수 수정 void CImageProView::OnDraw(CDC* pDC) {
CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; if (pDoc->depth == 1) { for(int y=0; y < pDoc->imageHeight; y++) // 입력 영상 출력 for(int x=0; x < pDoc->imageWidth; x++) pDC->SetPixel(x, y, RGB(pDoc->inputImg[y][x], pDoc->inputImg[y][x], pDoc->inputImg[y][x]));

40 픽셀 복제 방법을 이용한 확대 if (viewMode == THREE_IMAGES) {
for(int y=0; y< pDoc->imageHeight; y++) // 두번째 입력 영상 출력 for(int x=0; x< pDoc->imageWidth; x++) pDC->SetPixel(x+pDoc->imageWidth+30, y, RGB(pDoc->inputImg2[y][x], pDoc->inputImg2[y][x], pDoc->inputImg2[y][x])); for(int y=0; y< pDoc->imageHeight; y++) // 결과 영상 출력 pDC->SetPixel(x+pDoc->imageWidth*2+60, y, RGB(pDoc->resultImg[y][x], pDoc->resultImg[y][x], pDoc->resultImg[y][x])); }

41 픽셀 복제 방법을 이용한 확대 else if (viewMode == TWO_IMAGES_SCALED) {
for(int y=0; y< pDoc->gImageHeight; y++) // 크기가 변한 결과 영상 출력 for(int x=0; x< pDoc->gImageWidth; x++) pDC->SetPixel(x+pDoc->imageWidth+30, y, RGB(pDoc->gResultImg[y][x], pDoc->gResultImg[y][x], pDoc->gResultImg[y][x])); } else { for(int y=0; y< pDoc->imageHeight; y++) // 결과 영상 출력 for(int x=0; x< pDoc->imageWidth; x++) RGB(pDoc->resultImg[y][x], pDoc->resultImg[y][x], pDoc->resultImg[y][x]));

42 픽셀 복제 방법을 이용한 확대 else if (pDoc->depth == 3) {
for(int y=0; y < pDoc->imageHeight; y++) // 입력 영상 출력 for(int x=0; x < pDoc->imageWidth; x++) pDC->SetPixel(x, y, RGB(pDoc->inputImg[y][3*x], pDoc->inputImg[y][3*x+1], pDoc->inputImg[y][3*x+2])); if (viewMode == THREE_IMAGES) { for(int y=0; y< pDoc->imageHeight; y++) // 두번째 입력 영상 출력 for(int x=0; x< pDoc->imageWidth; x++) pDC->SetPixel(x+pDoc->imageWidth+30, y, RGB(pDoc->inputImg2[y][3*x], pDoc->inputImg2[y][3*x+1], pDoc->inputImg2[y][3*x+2]));

43 픽셀 복제 방법을 이용한 확대 for(int y=0; y< pDoc->imageHeight; y++) // 결과 영상 출력 for(int x=0; x< pDoc->imageWidth; x++) pDC->SetPixel(x+pDoc->imageWidth*2+60,y, RGB(pDoc->resultImg[y][3*x], pDoc->resultImg[y][3*x+1], pDoc->resultImg[y][3*x+2])); } else { pDC->SetPixel(x+pDoc->imageWidth+30, y,

44 컴파일 및 실행 프로그램을 컴파일하고 실행시킨 다음에 “Lenna-64x64.pgm" 파일을 열어서 [확대 (픽셀 복제)] 연산을 적용 44

45 양선형 보간법을 이용한 확대 [기하학적처리] 메뉴에 부메뉴 추가 이름 : 확대 (양선형보간법)
ID : ID_GEOMETRY_ZOOMIN_INTERPOLATION

46 양선형 보간법을 이용한 확대 CImageProView 클래스에 OnGeometryZoominInterpolation() 함수 추가 void CImageProView::OnGeometryZoominInterpolation() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->GeometryZoominInterpolation(); viewMode = TWO_IMAGES_SCALED; Invalidate(FALSE); }

47 양선형 보간법을 이용한 확대 CImageProDoc 클래스에 GeometryZoominInterpolation() 함수 추가
void CImageProDoc::GeometryZoominInterpolation() { int i, y, x; float src_x, src_y; // 원시 화소 위치 float alpha, beta; int scale_x, scale_y; // x 방향과 y 방향으로의 확대 비율 int E, F; // x 방향으로 보간된 결과 값 int Ax, Ay, Bx, By, Cx, Cy, Dx, Dy; // 보간에 사용될 4개 픽셀의 좌표 scale_x = 3; scale_y = 3;

48 양선형 보간법을 이용한 확대 // 결과 영상의 크기 설정 gImageWidth = imageWidth * scale_x;
gImageHeight = imageHeight * scale_y; // 결과 영상을 저장할 기억장소 공간 할당 gResultImg = (unsigned char **) malloc(gImageHeight * sizeof(unsigned char *)); for (i = 0; i < gImageHeight; i++) { gResultImg[i] = (unsigned char *) malloc(gImageWidth * depth); }

49 양선형 보간법을 이용한 확대 for (y = 0; y < gImageHeight; y++)
for (x = 0; x < gImageWidth; x++) { // 원시 영상에서의 픽셀 좌표 계산 src_x = x / (float) scale_x; src_y = y / (float) scale_y; alpha = src_x - x / scale_x; beta = src_y - y / scale_y; // 보간에 사용된 4 픽셀의 좌표 계산 Ax = x / scale_x; Ay = y / scale_y; Bx = Ax + 1; By = Ay; Cx = Ax; Cy = Ay + 1; Dx = Ax + 1; Dy = Ay + 1;

50 양선형 보간법을 이용한 확대 // 픽셀 위치가 영상의 경계를 벗어나는지 검사
if (Bx > imageWidth - 1) Bx = imageWidth - 1; if (Dx > imageWidth - 1) Dx = imageWidth - 1; if (Cy > imageHeight - 1) Cy = imageHeight - 1; if (Dy > imageHeight - 1) Dy = imageHeight - 1; // x 방향으로 보간 E = (int) (inputImg[Ay][Ax] * (1-alpha) + inputImg[By][Bx] * alpha); F = (int) (inputImg[Cy][Cx] * (1-alpha) + inputImg[Dy][Dx] * alpha); // y 방향으로 보간 gResultImg[y][x] = (unsigned char) (E * (1-beta) + F * beta); }

51 컴파일 및 실행 프로그램을 컴파일하고 실행시킨 다음에 “Lenna-64x64.pgm" 파일을 열어서 [확대 (양선형보간법)] 연산을 적용 51

52 서브샘플링을 이용한 축소 [기하학적처리] 메뉴에 부메뉴 추가 이름 : 축소 (서브샘플링)
ID : ID_GEOMETRY_ZOOMOUT_SUBSAMPLING

53 서브샘플링을 이용한 축소 CImageProView 클래스에 OnGeometryZoomoutSubsampling() 함수 추가
void CImageProView::OnGeometryZoomoutSubsampling() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->GeometryZoomoutSubsampling(); viewMode = TWO_IMAGES_SCALED; Invalidate(FALSE); }

54 서브샘플링을 이용한 축소 CImageProDoc 클래스에 GeometryZoomoutSubsampling() 함수 추가
void CImageProDoc::GeometryZoomoutSubsampling() { int i, y, x; int src_x, src_y; int scale_x = 3, scale_y = 3; // 결과 영상의 크기 계산 gImageWidth = imageWidth / scale_x; gImageHeight = imageHeight / scale_y; // 결과 영상 저장을 위한 기억장소 할당 gResultImg = (unsigned char **) malloc(gImageHeight * sizeof(unsigned char *)); for (i = 0; i < gImageHeight; i++) { gResultImg[i] = (unsigned char *) malloc(gImageWidth * depth); }

55 서브샘플링을 이용한 축소 for (y = 0; y < gImageHeight; y++)
for (x = 0; x < gImageWidth; x++) { src_y = y*scale_y; src_x = x*scale_x; if (src_x > imageWidth - 1) src_x = imageWidth - 1; if (src_y > imageHeight - 1) src_y = imageHeight - 1; gResultImg[y][x] = inputImg[src_y][src_x]; }

56 서브샘플링을 이용한 축소 프로그램을 컴파일하고 실행 “lines.pgm" 파일은 다음 [축소(서브샘플링)] 연산 적용

57 평균값 필터링을 이용한 축소 [기하학적 처리] 메뉴에 항목 추가 이름 : 축소 (평균값필터링)
ID : ID_GEOMETRY_ZOOMOUT_AVG

58 평균값 필터링을 이용한 축소 CImageProView 클래스에 OnGeometryZoomoutAvg() 함수 추가
void CImageProView::OnGeometryZoomoutAvg() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->GeometryZoomoutAvg(); viewMode = TWO_IMAGES_SCALED; Invalidate(FALSE); }

59 평균값 필터링을 이용한 축소 CImageProDoc 클래스에 GeometryZoomoutAvg() 함수 추가
void CImageProDoc::GeometryZoomoutAvg() { int i, j, x, y; int sum; int src_x, src_y; int scale_x = 3, scale_y = 3; // 결과 영상의 크기 계산 gImageWidth = imageWidth / scale_x + 1; gImageHeight = imageHeight / scale_y + 1; // 결과 영상을 저장할 기억장소 할당 gResultImg = (unsigned char **) malloc(gImageHeight * sizeof(unsigned char *)); for (i = 0; i < gImageHeight; i++) { gResultImg[i] = (unsigned char *) malloc(gImageWidth * depth); }

60 평균값 필터링을 이용한 축소 for (y=0; y < imageHeight; y = y + scale_y)
for (x=0; x < imageWidth; x = x + scale_x) { // 필터 윈도우 내의 픽셀값 합계 계산 sum=0; for (i=0; i<scale_y; i++) for (j=0; j<scale_x; j++) { src_x = x + j; src_y = y + i; if (src_x > imageWidth - 1) src_x = imageWidth - 1; // 영상의 경계 검사 if (src_y > imageHeight - 1) src_y = imageHeight - 1; sum += inputImg[src_y][src_x]; } sum = sum / (scale_x * scale_y); // 평균값 계산 if (sum > 255) sum=255; if (sum < 0) sum = 0; gResultImg[y/scale_y][x/scale_x] = (unsigned char) sum; // 결과 값 저장

61 평균값 필터링을 이용한 축소 프로그램을 컴파일하고 실행 “lines.pgm" 파일은 다음 [축소(평균값필터링)] 연산 적용

62 회전 [기하학적 처리] 메뉴에 회전 연산을 위한 부메뉴 추가 이름 : 회전 ID : ID_GEOMETRY_ROTATE

63 회전 CImageProView 클래스에 OnGeometryRotate() 함수 추가
void CImageProView::OnGeometryRotate() { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (pDoc->inputImg == NULL) return; pDoc->GeometryRotate(); viewMode = TWO_IMAGES_SCALED; Invalidate(FALSE); }

64 회전 CImageProDoc 클래스에 GeometryRotate() 함수 추가 #define PI 3.14159
void CImageProDoc::GeometryRotate() { int y, x, x_source, y_source, Cx, Cy; float angle; int Oy; int i, xdiff, ydiff; Oy = imageHeight - 1; angle = PI / * 30.0; // 30도를 라디안 값의 각도로 변환 Cx = imageWidth / 2; // 회전 중심의 x좌표 Cy = imageHeight / 2; // 회전 중심의 y좌표

65 회전 // 결과 영상 크기 계산 gImageWidth =(int)(imageHeight * cos(PI / angle) + imageWidth * cos(angle)); gImageHeight =(int)(imageHeight * cos(angle) + imageWidth * cos(PI / angle)); // 결과 영상을 저장할 기억장소 할당 gResultImg = (unsigned char **) malloc(gImageHeight * sizeof(unsigned char *)); for (i = 0; i < gImageHeight; i++) { gResultImg[i] = (unsigned char *) malloc(gImageWidth * depth); } // 결과 영상의 x 좌표 범위 : -xdiff ~ gImageWidth - xdiff - 1 // 결과 영상의 y 좌표 범위 : -ydiff ~ gImageHeight - ydiff - 1 xdiff = (gImageWidth - imageWidth) / 2; ydiff = (gImageHeight - imageHeight) / 2;

66 회전 for (y = -ydiff; y < gImageHeight - ydiff; y++)
for (x = -xdiff; x < gImageWidth - xdiff; x++) { // 변환 단계 // 단계 : 원점이 영상의 좌측 하단에 오도록 y 좌표 변환 // 단계 : 회전 중심이 원점에 오도록 이동 // 단계 : 각도 angle 만큼 회전 // 단계 : 회전 중심이 원래 위치로 돌아가도록 이동 x_source =(int) (((Oy - y) - Cy) * sin(angle) + (x - Cx) * cos(angle) + Cx); y_source =(int) (((Oy - y) - Cy) * cos(angle) - (x - Cx) * sin(angle) + Cy); // 단계 : 원점이 영상의 좌측 상단에 오도록 y 좌표 변환 y_source = Oy - y_source; if (x_source < 0 || x_source > imageWidth - 1 || y_source < 0 || y_source > imageHeight - 1) gResultImg[y+ydiff][x+xdiff] = 255; else gResultImg[y+ydiff][x+xdiff] = inputImg[y_source][x_source]; }

67 회전 프로그램을 컴파일하고 실행 “화성탐사선.pgm" 파일을 열고 [회전] 연산 적용


Download ppt "제 5 장 기하학적 처리."

Similar presentations


Ads by Google