1 / 59

Chapter13. 실전 예제

Chapter13. 실전 예제. 데이터 정렬 프로그램 간단한 영상처리 프로그램 명중률 구하기 프로그램. 데이터 정렬 방법을 알아보고 각 정렬 방법의 처리 속도를 비교해본다 . C 언어를 이용해 영상을 처리하는 프로그램을 작성해본다 . 난수를 이용해 표적의 명중률을 계산하는 프로그램을 작성해본다. 1.1 선택 정렬. 데이터 정렬 : 데이터 값을 순서대로 재배치하는 것 선택 정렬 과정 ① 정렬되지 않은 리스트에서 가장 작은 원소를 찾음

hogan
Download Presentation

Chapter13. 실전 예제

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter13.실전 예제

  2. 데이터 정렬 프로그램 간단한 영상처리 프로그램 명중률 구하기 프로그램

  3. 데이터 정렬 방법을 알아보고 각 정렬 방법의 처리 속도를 비교해본다. C 언어를 이용해 영상을 처리하는 프로그램을 작성해본다. 난수를 이용해 표적의 명중률을 계산하는 프로그램을 작성해본다.

  4. 1.1 선택 정렬 • 데이터 정렬 : 데이터 값을 순서대로 재배치하는 것 • 선택 정렬 과정 • ① 정렬되지 않은 리스트에서 가장 작은 원소를 찾음 • ② 과정 ①에서 찾은 원소를 정렬되지 않은 리스트의 첫 번째 원소와 자리를 바꿈. • ③ 정렬되지 않은 리스트에서 제일 작은 값을 벽 앞 정렬된 리스트로 넘김. • ④ 가상의 벽을 현재 위치에서 하나 뒤로 이동해 검색 범위를 좁힘. 가상의 벽에 의해 정렬된 리스트, 정렬되지 않은 리스트로나뉨

  5. 1.1 선택 정렬 • 선택 정렬 • 선택 정렬이 진행될수록 정렬된 원소 수는 증가하고 정렬되지 않은 원소 수는 감소 • 원소가 정렬되지 않은 리스트에서 정렬된 리스트로 이동할 때마다 정렬 패스 1번 완료 • 정렬해야하는 데이터의 수가 n개라면 정렬 패스를 n-1번 반복

  6. 1.1 선택 정렬 • 선택 정렬 함수 소스 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void Select_Sort(int *a, int count) { inti, j; intmin_value, min_index; for(i = 0; i < count-1; i++) // 패스 반복 { min_index = i; // 정렬되지 않은 리스트의 첫 번째 값 기억 min_value = a[i]; for(j = i+1; j < count; j++) // 최소 원소 찾기(과정 ①) { if(min_value > a[j]) { min_index = j; min_value = a[j]; } } a[min_index] = a[i]; // 과정 ②, ③ a[i] = min_value; } }

  7. 1.1 선택 정렬 • 예제 13-1) 선택 정렬 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> void Select_Sort(int* a, int count); int main(void) { int data[ ] = {4, 2, 20, 8, 1, 33, 35, 9, 6, 26}; inti; printf("정렬 전 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); Select_Sort(data, 10); puts("\n"); printf("정렬 후 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); puts("\n"); return 0; }

  8. 1.1 선택 정렬 • 예제 13-1) 선택 정렬 예제 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 void Select_Sort(int *a, int count) { inti, j; intmin_value, min_index; for(i = 0; i < count-1; i++) { min_index = i; min_value = a[i]; for(j = i+1; j < count; j++) { if(min_value > a[j]) { min_index = j; min_value = a[j]; } } a[min_index] = a[i]; a[i] = min_value; } }

  9. 1.2 버블 정렬 • 버블 정렬 과정 • ①정렬되지 않은 리스트의 뒤에서부터 앞으로 값을 하나하나 비교하면서 현재 값보다 작은 값이 나타나면 자리를 바꿈. 현재 값이 더 크거나 같으면 앞의 값이 현재 값이 됨 • ② 과정 ①을 반복하면 제일 작은 값이 정렬되지 않은 리스트 맨 앞으로 옴 • ③ 과정 ②의 값을 벽 앞 정렬된 리스트로 넘김 • ④ 가상의 벽을 하나 뒤로 옮겨 정렬되지 않은 리스트의 범위를 좁힘. 버블 정렬도 정렬된 리스트, 정렬되지 않은 리스트로나뉨

  10. 1.2 버블 정렬 • 버블 정렬 함수 소스 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 void Bubble_Sort(int *a, int count) { inti, j; int temp; for(i = 0; i < count-1; i++) // 패스 반복 { for(j = 1; j < count-i; j++) // 최솟값 찾기 { if(a[j-1] > a[j]) { temp = a[j-1]; a[j-1] = a[j]; a[j] = temp; } } } }

  11. 1.2 버블 정렬 • 예제 13-2) 버블 정렬 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> void Bubble_Sort(int* a, int count); int main(void) { int data[] = {4, 2, 20, 8, 1, 33, 35, 9, 6, 26}; inti; printf("정렬 전 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); Bubble_Sort(data, 10); puts("\n"); printf("정렬 후 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); puts("\n"); return 0; }

  12. 1.2 버블 정렬 • 예제 13-2) 버블 정렬 예제 27 28 29 30 31 32 33 34 35 36 37 38 39 4041 42 43 44 45 void Bubble_Sort(int *a, int count) { inti, j; int temp; for(i = 0; i < count-1; i++) { for(j = 1; j < count-i; j++) { if(a[j-1] > a[j]) { temp = a[j-1]; a[j-1] = a[j]; a[j] = temp; } } } }

  13. 1.3 삽입 정렬 • 삽입 정렬은 가장 일반적인 알고리즘 중 하나로 카드놀이에서 가끔 사용됨. • 삽입 정렬 과정 • ①가상의 벽 바로 뒤의 값을 벽 바로 앞의 값과 비 • 정렬이 안된 리스트의 첫 번째 값과 정렬된 리스트의 마지막 값 비교 • ② 가상의 벽 뒤의 값이 크면 가상의 벽을 1칸 뒤로 옮긴 후 ①을 수행 • ③ 가상의 벽 뒤의 값이 작으면 그 값을 정렬된 리스트의 값과 뒤에서부터 비교 • ④ 이동시켜야 하는 값보다 작은 값을 발견하면, 그 값 뒤로 가상의 벽 바로 뒤의 값을 옮김 • ⑤ 가상의 벽을 뒤로 1칸 옮겨 정렬되지 않은 리스트의 범위를 좁힘

  14. 1.3 삽입 정렬 • 삽입 정렬 함수 소스 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 void Insert_Sort(int *a, int count) { inti, j; int temp; for(i = 1; i < count; i++) // 전체 루프 반복 { temp = a[i]; j = i; while((a[j-1] > temp) && (j > 0)) // 원소 삽입 위치 찾기 { a[j] = a[j-1]; j = j-1; } a[j] = temp; } }

  15. 1.3 삽입 정렬 • 예제 13-3) 삽입 정렬 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> void Insert_Sort(int* a, int count); int main(void) { int data[] = {4, 2, 20, 8, 1, 33, 35, 9, 6, 26}; inti; printf("정렬 전 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); Insert_Sort(data, 10); puts("\n"); printf("정렬 후 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); puts("\n"); return 0; }

  16. 1.3 삽입 정렬 • 예제 13-3) 삽입 정렬 예제 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 void Insert_Sort(int *a, int count) { inti, j; int temp; for(i = 1; i < count; i++) { temp = a[i]; j = i; while((a[j-1] > temp) && (j > 0)) { a[j] = a[j-1]; j = j-1; } a[j] = temp; } }

  17. 1.4 셸 정렬 • 삽입 정렬의단점 • 인접한 요소를 비교해 해당 원소가 들어갈 위치를 찾으므로, n개의 배열을 내림차순으로 정렬할 경우 제일 작은 값이 맨 뒤에 있다면n 번 비교하고 이동해야 함. • 셸 정렬: h 간격만큼 떨어진 요소들을 모아서 삽입 정렬을 수행. • 셸 정렬은 삽입 정렬의 단점을 해결 h만큼의 간격으로 삽입 정렬을 실행. • 셸(D. L. Shell)에 의해 1959년에 만들어진 알고리즘 • 보통 h의 초깃값으로1, 4, 13, 40, 121, 364 등을 많이 사용함 • hn = 3 X hn-1 +1 인 경우에 효율이 높음

  18. 1.4 셸 정렬 • 셸 정렬 과정 • ① h 간격을 설정. • ② h 간격만큼 떨어진 원소를 모은 부분 집합에서 삽입 정렬을 각각 수행. • ③ h 간격을 재설정하고 과정 ②를 반복.

  19. 1.4 셸 정렬 • 셸 정렬 함수 소스 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 void Shell_Sort(int *a, int count) { inti, j, inc, h; int temp; for(h = count/2; h > 0; h /= 2) // 변수 h의 변화 { for(i = 0; i < h; i++) // 각 부분 집합 반복 { for(j = i+ h; j < count; j+= h) // 삽입 정렬 { temp = a[j]; inc = j; while(inc > h-1 && a[inc-h] > temp) { a[inc] = a[inc-h]; inc = inc - h; } a[inc] = temp; } } } }

  20. 1.4 셸 정렬 • 예제 13-4) 셸 정렬 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> void Shell_Sort(int* a, int count); int main(void) { int data[] = {4, 2, 20, 8, 1, 33, 35, 9, 6, 26}; inti; printf("정렬 전 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); Shell_Sort(data, 10); puts("\n"); printf("정렬 후 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); puts("\n"); return 0; }

  21. 1.4 셸 정렬 • 예제 13-4) 셸 정렬 예제 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 void Shell_Sort(int *a, int count) { inti, j, inc, h; int temp; for(h = count/2; h > 0; h /= 2) { for(i = 0; i < h; i++) { for(j = i+ h; j < count; j += h) { temp = a[j]; inc = j; while(inc > h-1 && a[inc-h] > temp) { a[inc] = a[inc-h]; inc = inc - h; } a[inc] = temp; } } } }

  22. 1.5 퀵 정렬 • 퀵 정렬 : 1960년 호어(C. A. R. Hoare)가 제안한 방법 빠른 속도와 간단한 구현 방법을 가지고 있는 정렬 알고리즘 • 퀵 정렬 과정

  23. 1.5 퀵 정렬 • 퀵 정렬 함수 소스 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void Quick_Sort(int *a, int count) { inti, j; int v, temp; if(count > 1) { v = a[count-1]; i = -1; // 앞쪽 j = count - 1; // 뒤쪽 for( ; ; ) { while(a[++i] < v); while(a[--j] > v); if(i > = j) break; temp = a[i]; a[i] = a[j]; a[j] = temp; } temp = a[i]; a[i] = a[count-1]; data[count-1] = temp; Quick_Sort(a, i); Quick_Sort(a+i+1, count-i-1); } }

  24. 1.5 퀵 정렬 • 예제 13-5) 퀵 정렬 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> void Quick_Sort(int* a, int count); int main(void) { int data[] = {4, 2, 20, 8, 1, 33, 35, 9, 6, 26}; inti; printf("정렬 전 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); Quick_Sort(data, 10); puts("\n"); printf("정렬 후 데이터\n"); for(i = 0; i < 10; i++) printf("[%d] ", data[i]); puts("\n"); return 0; }

  25. 1.5 퀵 정렬 • 예제 13-5) 퀵 정렬 예제 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 void Quick_Sort(int *a, int count) { inti, j; int v, temp; if(count > 1) { v = a[count-1]; i = -1; j = count - 1; for( ; ; ) { while(a[++i] < v); while(a[--j] > v); if(i > = j) break; temp = a[i]; a[i] = a[j]; a[j] = temp; } temp = a[i]; a[i] = a[count-1]; a[count-1] = temp; Quick_Sort(a, i); Quick_Sort(a+i+1, count-i-1); } }

  26. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_NUM 10000 // 10,000개의 데이터 발생 // 정렬 함수들 원형 void Select_Sort(int* a, int count); void Bubble_Sort(int* a, int count); void Insert_Sort(int* a, int count); void Shell_Sort(int* a, int count); void Quick_Sort(int* a, int count); // 난수 발생 함수 void Rand_Data(int* a); int Random(int start, int end); // 속도 비교 함수 void Check_Speed(int num, char* str, int* a, int count);

  27. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 int main(void) { int data[MAX_NUM]; inti; char* str[] = {"Select", "Bubble", "Insert", "Shell", "Quick"}; Rand_Data(data); for(i = 0; i< 5; i++) Check_Speed(i, str[i], data, MAX_NUM); return 0; }

  28. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 036 037 038 039 040 041 042 043 044 045 046 void array_swap(int *a, int i, int j) { int temp, k; temp = a[j]; for(k = j-1; k > = i; k--) { a[k+1] = a[k]; a[i] = temp; } } 배열 값 바꾸기

  29. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 047 048 049 050 051 052 053 054 055 056 057 058 059 intmove_index(int *a, inti, int j) { int k = j; while(k > i) { if(a[k-1] <= a[j]) return k; k--; } return i; }

  30. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 void Select_Sort(int *a, int count) { inti, j; intmin_value, min_index; for(i = 0; i < count-1; i++) { min_index = i; min_value = a[i]; for(j = i+1; j < count; j++) { if(min_value > a[j]) { min_index = j; min_value = a[j]; } } a[min_index] = a[i]; a[i] = min_value; } } 선택 정렬

  31. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 void Bubble_Sort(int *a, int count) { inti, j; int temp; for(i = 0; i < count-1; i++) { for(j = 1; j < count-i; j++) { if(a[j-1] > a[j]) { temp = a[j-1]; a[j-1] = a[j]; a[j] = temp; } } } } 버블 정렬

  32. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 void Insert_Sort(int *a, int count) { inti, j; int temp; for(i = 1; i < count; i++) { temp = a[i]; j = i; while((a[j-1] > temp) && (j > 0)) { a[j] = a[j-1]; j = j-1; } a[j] = temp; } } 삽입 정렬

  33. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 void Shell_Sort(int *a, int count) { inti, j, inc, h; int temp; for(h = count/2; h > 0; h /= 2) { for(i = 0; i < h; i++) { for(j = i + h; j < count; j += h) { temp = a[j]; inc = j; while(inc > h-1 && a[inc-h] > temp) { a[inc] = a[inc-h]; inc = inc - h; } a[inc] = temp; } } } } 쉘 정렬

  34. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 void Quick_Sort(int *a, int count) { inti, j; int v, temp; if(count > 1) { v = a[count-1]; i = -1; j = count - 1; for( ; ; ) { while(a[++i] < v); while(a[--j] > v); if(i > = j) break; temp = a[i]; a[i] = a[j]; a[j] = temp; } temp = a[i]; a[i] = a[count-1]; a[count-1] = temp; Quick_Sort(a, i); Quick_Sort(a+i+1, count-i-1); } } 퀵 정렬

  35. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 void Rand_Data(int* a) { inti; srand((unsigned)time(NULL)); // 난수 발생 초기화 for(i = 0; i < MAX_NUM; i++) { a[i] = Random(1, MAX_NUM); // 1~ 9999 사이의 난수 발생 } } int Random(int start, int end) { intrnd = 0; rnd = rand() % (end - start) + start; return rnd; } 난수 발생

  36. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 속도 측정 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 void Check_Speed(int num, char* str, int* a, int count) { clock_t start, end; int temp[MAX_NUM]; inti; for(i = 0; i < MAX_NUM; i++) temp[i] = a[i]; start = clock() ; switch(num) { case 0 : Select_Sort(temp, count); break; case 1 : Bubble_Sort(temp, count); break; case 2 : Insert_Sort(temp, count); break; case 3 : Shell_Sort(temp, count); break; case 4 : Quick_Sort(temp, count); break; }

  37. 1.6 정렬 알고리즘 성능 비교 • 예제 13-6) 정렬 알고리즘 성능 비교 예제 속도 측정 222 223 224 225 end = clock(); // 종료 시간 확인 printf("%10s의 수행 시간은 %5ld입니다.\n", str, end-start); }

  38. 2. 간단한 영상처리 프로그램 • 흑백 영상 파일을 프로그램에서 읽어와서 간단한 처리하는 방법을 알아보자 • 영상처리 프로그램 예제의 흐름 • ① 파일로 저장되어 있는 흑백영상을 프로그램에서 읽어서 메모리에 저장. • ② 메모리에 저장된 흑백영상에 몇가지 영상처리(반전영상, 이진화영상, 윤곽선영상)를 한 후, 그 결과를 파일로 저장. • ③ 영상처리한 결과 영상을 포토샵과 같은 응용프로그램에서 읽어서 결과를 확인.

  39. 2.1 영상파일 입출력 • . raw 파일 • .raw 파일은 영상의 화소(픽셀, pixel)값만 데이터로 저장 • 그림판으로는 확인할 수 없고 포토샵같은 프로그램을 이용해야 영상 확인 가능 • 영상 파일에는 .raw뿐만 아니라 .jpg, .bmp, .gif 등이 있음. • lena256.raw • 영상의 크기, 즉 화소 수가 256×256개임. • 각 화소는 0~255까지의 값을 가질 수 있고 한 화소당 크기는 1바이트 • 화소 값이 0이면 검은색, 255이면 흰색, 그 사이의 값은 회색으로 값이 클수록 밝은 색 • 화소 값이 0에서 255까지의 0을 포함한 양수이므로 unsigned char 자료형을 사용 예제 소스파일Chapter_13 폴더에 있음

  40. 2.1 영상파일 입출력 • lena256.raw 영상을 프로그램에 읽어오는 소스 01 02 03 04 05 06 #define SIZE 256*256 // 사이즈 정의 typedef unsigned char BYTE; FILE* fpIn; fpIn = fopen("lena256.raw", "rb"); // 영상 파일 열기 BYTE* pBufIn = (BYTE*)malloc(SIZE); // 동적 메모리 할당 fread(pBufIn, 1, SIZE, fpIn);

  41. 2.1 영상파일 입출력 • 동적 메모리 할당 – malloc( ) 함수 • <stdlib.h>에 정의됨 • 함수의 인자: 동적으로 저장할 크기 • 반환값: 저장되는 주소값

  42. 2.1 영상파일 입출력 • lena256.raw 영상을 처리한 파일을 만드는 소스 • 파일 닫기와 메모리 해제 소스 • 모든 작업이 끝났으면 fclose( )로 열어둔 파일을 닫아야 함 • malloc( ) 함수를 이용하여 동적으로 메모리가 할당된 경우 free( ) 함수를 이용해 할당된 메모리를 해제 • free( )의 인자로는 메모리를 가리키고 있는 포인터가 들어감.

  43. 2.2 반전영상 만들기 • 반전영상 • 검은색 흰색, 흰색 검은색으로 바꿔준 영상 • 회색값: 밝은색 어둡게, 어두운 색 밝게 • 처리 방법: 색을 표현하는 최댓값인 255 - 해당 화소값 • 반전영상 주요 소스 • pBufIn과 pBufOut:1차원 포인터로 1차원 배열의 시작주소를 가리킴. • pBufIn: 영상처리를 하기 전의 메모리를 가리키는 포인터 • pBufOut: 영상처리 후의 메모리를 가리키는 포인터 inti, j; BYTE* pBufOut = (BYTE*)malloc(SIZE); // 동적 메모리 할당 for(i = 0; i < 256; i++) { for(j = 0; j < 256; j++) { pBufOut[i*256 + j] = 255 - pBufIn[i*256 + j]; } } 01 02 03 04 05 06 07 08 09

  44. 2.2 반전영상 만들기 • 예제 13-7) 반전영상 만드는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <stdio.h> #include <stdlib.h> #define SIZE 256*256 typedef unsigned char BYTE; void main( ) { inti, j; FILE* fpIn, *fpOut; BYTE* pBufIn = (BYTE*)malloc(SIZE); BYTE* pBufOut = (BYTE*)malloc(SIZE); fpIn = fopen("lena256.raw", "rb"); fpOut = fopen("lenainvert256.raw", "wb"); fread(pBufIn, 1, SIZE, fpIn); for(i = 0; i < 256; i++) { for(j = 0; j < 256; j++) { pBufOut[i*256 + j] = 255 - pBufIn[i*256 + j]; } } fwrite(pBufOut, 1, SIZE, fpOut); fclose(fpIn); fclose(fpOut); free(pBufIn); free(pBufOut); }

  45. 2.3 이진영상 만들기 • 이진영상 • 검은색 또는 흰색으로만 구성된 영상. • 즉, 화소값으로0 또는 255만 가짐 • 검은색과 흰색을 구분하는 기준 값(문턱값)을 결정해야 함. • 처리 방법: 기준 값 미만 0, 기준 값 이상 255로 처리 • 이진영상 주요 소스 • 위의 소스에서 기준 값(문턱값) : 128 • 문턱값을 어느 값으로 할 지는 사용자가 필요에 맞게 결정 for(i = 0; i < 256; i++ ) { for(j = 0; j < 256; j++) { if(pBufIn[i*256 + j] >= 128) // 기준값과화소값 비교 pBufOut[i*256 + j] = 255; else pBufOut[i*256 + j] = 0; } } 01 02 03 04 05 06 07 08 09 10

  46. 2.3 이진영상 만들기 • 예제 13-8) 이진영상 만드는 예제 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <stdio.h> #include <stdlib.h> #define SIZE 256*256 typedef unsigned char BYTE; void main( ) { inti, j; FILE* fpIn, *fpOut; BYTE* pBufIn = (BYTE*)malloc(SIZE); BYTE* pBufOut = (BYTE*)malloc(SIZE); fpIn = fopen("lena256.raw", "rb"); fpOut = fopen("lenabynary256.raw", "wb"); fread(pBufIn, 1, SIZE, fpIn); for(i = 0; i < 256; i++) { for(j = 0; j < 256; j++) { if(pBufIn[i*256 + j] >= 128) pBufOut[i*256 + j] = 255; else pBufOut[i*256 + j] = 0; } } fwrite(pBufOut, 1, SIZE, fpOut); fclose(fpIn); fclose(fpOut); free(pBufIn); free(pBufOut); } 이진영상 문턱값이 68인 영상 문턱값이 192인 영상

  47. 2.4 윤곽선 영상 만들기 • 윤곽선 영상 • 영상의 윤곽선을 추출한 영상 • 영상에서 화소값의 변화가 큰 지점들을 추출해서 만듬 • 처리 방법: 필터를 이용해 화소값의 변화를 살펴봄 화소값의 변화가 큰 부분: 필터로 처리한 값으로 밝게 남겨둠 화소값의 변화가 작은 부분: 검은색으로 처리

  48. 2.4 윤곽선 영상 만들기 • 소벨 필터 • 윤곽선 영상을 처리할 때 사용하는 필터 • 마스크, 윈도우라고도 함 • 3×3 또는 5×5 크기인 정사각형 블록. 들어가는 값에 따라서 필터의 종류가 결정됨

  49. 2.4 윤곽선 영상 만들기 • 윤곽선 영상 주요 소스 intnEdgeSum; intnSobelMask[3][3] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; for(i = 1; i < 255; i++) { for(j = 1; j < 255; j++) { nEdgeSum = 0; for(int y = -1; y <= 1; y++) { for(int x = -1; x <= 1; x++) { nEdgeSum += pBufIn[(i+y)*256 + j+x]* nSobelMask[y+1][x+1]; } } if(nEdgeSum > 128 ㅣㅣnEdgeSum < -128) pBufOut[i*256+j] = (BYTE)(nEdgeSum); else pBufOut[i*256+j] = 0; } } 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22

More Related