1. 목표설정 - 주목적 : Noise 가 추가된 영상을 C언어와 Matlab을 통하여 Time 또는 Frequency 영역의 다 양한 Filter를 적용해 원본 이미지와 가장 흡사하게 복원. - Time 영역과 Frequency 영역의 특징을 이해하고 각 영역의 Filter 들이 가지는 장, 단점을 분석 - 다양한 Noise의 이미지 복원에 있어 최적의 Filter를 예상 할 수 있는 능력을 배양 할 수 있도 록 한다.2. 설계규격 - Time domain Filter, Frequency domain Filter 를 이용하여 영상을 복원한다. - Noise가 들어간 이미지를 Time domain과 Frequency domain 에서 각각 분석한다. - 각 domain Filter의 특성을 이해하여 어떤 것을 선택 하여 어떠한 예상 출력물을 생성 할 것 인지 분석해 본다. - 이미지의 복원은 우선 육안으로 Noise 제거를 확인 할 수 있어야 한다. 그 다음 PSNR등을 이 용하여 객관적인 수치로 복원의 정도를 측정 한다.
제목 : C언어를 이용한Arithmetic Coding과 목 명 :담당교수 :제 출 일 :학 과 :학 번 :이 름 :1. 이론(1) Entrophy 부호화이번 실습은 Entrophy 부호화 방식 중에 하나인 Arithmetic coding 방식에 대하여 알아보았다. 저번 시간에 실습한 허프만 코딩 방식 또한 Entrophy 부호화 방식이다. 이 개념의 특징은 일단은 무손실 압축 기법 알고리즘 이며, 모든 데이터를 가변길이나 혹은 고정길이의 부호들로 부호화 한다. 이 부호화 방식의 특징은 데이터 고유의 특징과 형태를 무시하고 모두 비트 열이나 바이트 열로 간주하여 처리한다.어떠한 데이터들의 빈도수 값이 있을 때 Entrophy는 이들 데이터들이 나타내는 빈도수에 따라 자신들이 표현 하는 정보량을 평균적으로 산출한 값이다. 이 값은 최적의 값이며 이 값을 기준으로 압축 알고리즘의 효율성을 판단하게 된다. 예를 들어 어떠한 데이터들을 표현하는데 필요한 Entrophy 값이 3bit 라면 3bit 는 최적 값이기 때문에 동일 데이터를 표현하는데 있어 3bit보다 낮은 bit수로는 절대 표현이 불가능 하다. 따라서 우리는 이 최적의 Entrophy 값에 최대한 근접하는 결과를 가져오는 알고리즘을 설계하는 것이 주된 목적이다. 이론상으로 이 Entrophy 와 동일한 알고리즘을 설계 하는 것이 가능하지만 좀처럼 간단한 방법으론 이를 구현하기가 쉽지 않고 여러가지 물리적, 구조적 제약 조건들 때문에 달성해야 하는 기준 값으로 놓고 설계하는 경우가 많다.(2) Arithmetic codingArithmetic coding은 Entrophy 부호화 방식 중 에서도 원래의 데이터를 손상시키지 않는 무손실 데이터 압축 방법이다. 그래서 이번 실험에서는 그 특징을 알아 볼 수 있게 TEXT를 가지고 부호화를 해보았다. Arithmetic coding 기법은 이름에서도 알 수 있듯이 많은 연산량을 기초로 하기 때문에 허프만 코딩 방식 보다는 조금 복잡하다. 그리고 허프만 코딩 방식이 최적의 코딩길이를 기반으로 문자 하나당 코드워드를 생성하는 알고리즘 이었던 반면에 Arithmetic coding 방식은 연속적인 전체의 데이터를 가지고 이 전체에 대한 실수로 표현하여 부호화 하는 방식이다.압축률은 허프만 코딩 방식보다 뛰어나며 역시 통계적인 확률 값을 이용하여 구현한다. 만약에 예를 들어 알파벳 A, B, C에 대한 통계 값이 있고 이들 3문자가 ABC라는 단어를 만든다고 할 때 Arithmetic coding 알고리즘이 고려하는 사항은 다음과 같다.첫 째, 하나의 단어를 정확히 인코딩하여 디코딩 시에도 그 단어가 복원되어야 하므로 A가 부호화 된 다음에는 반드시 B를 부호화 해주어야 한다. 이 이유는 디코딩 시 단어가 복원되어야 하기 때문에 문자들의 순서가 어긋나 버리면 ABC라는 단어가 복원되지 않고 임의의 순서에 따라 부호화한 CAB나 BCA 등으로 복원 될 수 있기 때문이다.둘 째, 현재의 구간을 결정해 주는 것이 중요하다. 처음 문자가 부호화 되면 확률 범위 비율이 1이라고 했을 때, 다음 문자의 확률 범위의 비율 역시 1로 정해주고 구간을 세분화 하여야 한다. 구간을 세분화 하는 각각 문자에 대한 확률 값은 처음과 동일한 비율로 세분화 되게 된다. 쉽게 말해 다음 문자의 확률 값의 분포는 최소값~최대값 까지의 범위의 비율이 1로 유지되어야 한다는 것이다.셋 째, 인코딩의 끝을 표시해 주어야 한다. 이는 허프만 코딩처럼 문자 하나에 대한 코드워드를 생성하는 것이 아니고 전체적인 데이터를 부호화 하는 것이기 때문에 중요하다. 인코딩의 끝을 표시해 주지 않으면 부호화가 계속 진행되기 때문에 오류가 발생 할 수 있다. 역시 복호화 과정에서도 데이터의 끝 부분을 인코딩시에 포함 시켰기 때문에 그 부분을 복호화 하고 종료 하게 된다.2. 내용소스 코드의 내용이 너무 많기 때문에 수업시간에 채워 넣은 구간이 있는 소스부분과 Encoding과 Decoding이 실제 일어나는 부분만을 추출하였다. 자세한 소스 분석을 해보려고 했지만 소스가 너무 최적화 된 소스이기 때문에 현재 나의 프로그래밍 지식수준으로는 세밀한 분석이 불가능 하였다.(1) Encoding/* ARITHMETIC ENCODING ALGORITHM. *//* THE BIT BUFFER. */static int S_buffer;/* Bits buffered for output */static int S_bits_to_go;/* Number of bits free in buffer *//* INITIALIZE FOR BIT OUTPUT. */void start_outputing_bits(){S_buffer = 0;//출력 버퍼의 비트수는 0; 으로 초기화S_bits_to_go= 8;// 버퍼안의 여유 비트수는 8로 초기화.}/* OUTPUT A BIT. */#define output_bit(bit) do{buffer >>= 1;if (bit) buffer |= 0x80;bits_to_go -= 1;if (bits_to_go ==0 ) {putc(buffer, stdout);bits_to_go = 8;}} while(0)/* FLUSH OUT THE LAST BITS. */void done_outputing_bits(){putc(S_buffer>>S_bits_to_go,stdout);}/* OUTPUT BITS PLUS FOLLOWING OPPOSITE BITS. */#define bit_plus_follow(bit) do{output_bit(bit); while (bits_to_follow>0) {output_bit(!bit);bits_to_follow -= 1;}} while(0)/* CURRENT STATE OF THE ENCODING. */static code_value S_low, S_high;static long S_bits_to_follow;/* START ENCODING A STREAM OF SYMBOLS. */void start_encoding(){S_low = 0;//전역 변수 low 값을 0으로 초기화S_high = Top_value;//1보다 작지만 1에 가장 가까운 수로 초기화.S_bits_to_follow = 0;//비트의 흐름을 체크하는 변수는 0으로 초기화}/* ENCODE A SYMBOL. */void encode_symbol(symbol,P_cum_freq)int symbol;/* Symbol to encode */int P_cum_freq[];/* Cumulative symbol frequencies */{register code_value low, high;{register long range;register int *cum_freq;cum_freq = P_cum_freq;range = (long)(S_high-S_low)+1;high = S_low + (range*cum_freq[symbol-1])/cum_freq[0]-1;low = S_low + (range*cum_freq[symbol])/cum_freq[0];}{register int H;register long bits_to_follow;register int buffer, bits_to_go;H = Half;bits_to_follow = S_bits_to_follow;buffer = S_buffer;bits_to_go = S_bits_to_go;for (;;) {/* Loop to output bits. */if (high=H) {/* Output 1 if in high half.*/bit_plus_follow(1);low -= H;high -= H;/* Subtract offset to top. */}else if (low>=First_qtr && high=First_qtr && high
제목 : Huffman Coding을 이용한 압축과 목 명 :담당교수 :제 출 일 :학 과 :학 번 :이 름 :1. 이론데이터를 압축하는 기법은 크게 두 가지 방법으로 나눌 수 있는데, 압축 과정에서 데이터에 손실이(혹은 변화가) 발생하면 손실압축(Lossy Compression), 데이터에 손실이(혹은 변화가) 발생하지 않으면 무손실 압축(Lossless Compression)이라고 한다. 손실 압축은 말 그대로 손실이 생기는 기법을 사용하여 압축 전과 후의 데이터에 차이가 생기는 것을 말하고, 무손실 압축은 손실이 생기지 않는 방법을 사용하여 압축 전의 데이터가 온전히 보존되어 압축 후의 데이터와 일치하는 것을 말한다. 그리고 본 실습에서 사용한 Huffman Coding 법은 무손실 압축법의 가장 대표적인, Coding Redundancy(코딩 잉여물 - 코딩 시 불필요한 낭비, 혹은 꼭 필요하지 않고 줄일 수 있는 부분)를 줄여주는 압축기법이다.Coding Redundancy를 줄이는 방법 중 Huffman Coding법에서 사용하며 가장 대표적인 방법은 Variable Bits Coding, 즉 Bit 수를 유동적(혹은 가변적)으로 변화시키는 방법이다. 가장 간단한 예로, 텍스트의 경우 공백 문자(Space)부터 대문자, 소문자, 숫자에 이르기까지 모든 문자에 대하여 각각의 고유 값인 ASCII Code 값이 부여되어 있다. 그리고 그 문자들은 사용자가 입력할 때 자연히 ASCII Code 값, 즉 8 Bits의 숫자로 저장된다.그러나 문자들에는 사용 빈도라는 것이 있어서, 한글을 예로 들면 보통 평균적으로 사용 되는 빈도수가 ㅁㄴㅇㄹ, 그리고 ㅓㅏl 등과 ㅋㅌㅊㅍ, 혹은 ㅕㅑㅒㅖ 가 분명히 다름을 알고 있을 것이다. 이것을 쉽게 알아보려면 국어사전을 한번 펴보면 된다. 자음별로 만들어 내는 단어수가 차이가 나는 것을 알 수 있다. 그런데 모든 문자에 8Bits를 할당한다는 것은 비효율적인 방법이 아닌가, 라는 의문에서 출발한 것이 Variable B트의 발생 확률보다 크다면 해당 이벤트는 아래로 내리고 그 위로 들어가는 과정을 거친다. 최종적으로 두 개를 남겨 더 이상 분할의 필요성이 없을 때, 해당 이벤트의 경로를 따라 이동한다. 상기의 예시를 예로 들자면, E 는 가장 오른쪽의 0 으로 출발하고, 다음은 E+F+D가 된 1 을 지나서, E+F가 된 1 을 지나 마지막 자기 자신이 위치한 0 에 도착한다. 이를 상위 비트부터 채워 넣으면 0110 이라는 Codeword를 가지는 것이다.이런 과정을 거치만 확률이 낮은 이벤트들을 우선 처리하기 때문에 자연히 거치는 경로가 적은 확률이 높은 이벤트는 Bits 수가 적고 거치는 경로가 많은 확률이 낮은 이벤트는 Bits 수가 늘어나게 된다.또한 여기서 중요한 것은, Coding Redundancy 법을 사용할 때 중요한 점은 Prefix 원칙을 위배해서는 안 된다는 것인데, Prefix 원칙이라는 것은 한 이벤트의 Codeword가 다른 이벤트 Codeword의 앞부분과 같아서는 안 된다는 것이다. 만약 위의 예시에 G라는 값을 넣는데 임의로 011011 이라는 값을 넣으면, 분명 새로운 값이고 중복되지 않으나 E의 Codeword인 0110 이 G의 앞부분과 같기 때문에 이렇게는 사용할 수가 없다. Prefix 원칙이 중요한 이유는 기계는 사람과 같이 언어의 형태로 구분할 수 있는 것이 아니라 공백까지도 Binary Code로 들어가게 된다. 0과 1이 끊이지 않고 반복된다는 것인데, 아까 예로 들었던 G의 경우, 우리는 G라는 의도로 011011이라는 값을 넣었으나 컴퓨터는 이를 G로 인식할 수 없을 수도 있다. 데이터를 받아들이는 과정에서 0110이라는 값을 인지하는 순간 컴퓨터는 이를 E로 받아들이게 될 것이다. 그리고 뒤의 11은 C의 Codeword이므로, 우리의 의도인 G 와는 전혀 다르게 컴퓨터는 EC 라는 값을 저장하게 되는 것이다. 때문에 원하는 데이터를 온전히 얻어내기 위해서는 Prefix 원칙을 꼭 지켜야 한다.Huffman Codingd);int Huffman_Decoding(void);int Compressed_Bit = 0;double cord_word[256];int cordword_cnt = 0;struct node{int active, count;char asciicode;struct node *childhigh;struct node *childlow;};struct codeword{char code;unsigned int word;};int main(void){printf("=====================================================nn");printf("Source Filett= dream.txtn");printf("Compressed Header Filet= Huffman.headern");printf("Compressed Filett= Huffman.compn");printf("Reconstructed Filet= reHuffman.txtnn");printf("=====================================================nn");Huffman_Encoding();//Huffman_Decoding();}int Huffman_Encoding(void){FILE *Input_File;int* cot[256];int i, j;char cc;for (i = 0; i count = *cot[i]; // cot[i]안에 있는 카운트 값 저장npc[nddd]->asciicode = (char)i; // 0-255 사이인 아스키 코드 값을// 차례로 집어넣음. int형인 i를 char로 형변환npc[nddd]->childhigh = NULL;npc[nddd]->childlow = NULL; // childhigh, childlow NULL로 초기화//printf("%d ", npc[nddd]->count);prob[i] = (double)npc[nddd]->count/sumnum;// prob d를 증가시켜 값이 없는 새로운 배열위치를 만듬npc[ndnd] = (struct node *)malloc(sizeof(struct node)); //할당npc[ndnd]->active = 1; // active시킴npc[ndnd]->count = min[1]->count + min[0]->count;// min 구조체의 0, 1 카운트를 더해서 저장npc[ndnd]->asciicode = (char)NULL; // asciicode값 비움npc[ndnd]->childhigh = min[1]; // min[1]을 childhigh에 저장npc[ndnd]->childlow = min[0]; // min[0]을 childlow에 저장} // 위 while문이 break;가 될 때까지 반복됨. ndnd++의 값이 증가되나 active를 0으로 하면// 실제적인 data의 이동은 이뤄지지 않는다.// tree 구조로 부터 codeword 만들기 (모든 node를 다 거쳐보기)// (만들어진 codeword의 첫 비트는 무조건 1// 나중에 첫번째 1을 제외하고 코딩됨// 이유 -> codeword를 int로 저장하므로// 왼쪽부터 0을 제외해 나가서 코딩할때 쓰는데,// codeword 의 첫번째가 0이면 그것마저 제외되버린다.// 처음 등장하는 1의 의미는// "이 다음 비트부터가 코드워드" 라는 뜻.)// 예 > 0111 의 경우 컴퓨터상에 저장되는 codeword는 10111이 된다.// 파일에는 0111이다.struct node *currentnode = NULL; // 현재 위치하는 노드 data를 보기 위한 currentnode 구조체 선언unsigned int xcodeword = 0;struct codeword *cdwd[256]; // 각 아스키값마다 비트를 char형으로 저장하기 위한 구조체 codeword 선언for (i = 0; i asciicode == (char)NULL){// 현재 노드에 asciicode값이 NULL일동안 반복if (curn.comp", "wb");while ((cc = fgetc(Input_File)) != EOF){ // 문자 수를 읽어서printf("%c :t ", cc);for (i = 0;i code){ // cdwd의 아스키 값이 cc와 같으면hcoding(Compress_File,cdwd[i]->word); // 저장된 bit 값 출력cord_word[i] = cordword_cnt;cordword_cnt = 0;break;}}}hcoding(Compress_File,0);/*******************************************************************/// Compute the Compression Ratio/*******************************************************************/for(i = 0; i = 0 ; j=j-8){//Character형은 8bit 이므로 8단위씩 줄어듬ii = fgetc(HeadIn);sumn = sumn + (ii * twosmulti(j));}//한문자 씩 읽어 들여 ii에 저장하고, twosmulti(j)로 2의 제곱승 계산후//문자의 아스키 코드와 곱하고 그 값을 sumn에 누적(원본 파일 바이트수)while (!(feof(HeadIn))){ //HeadIn의 문자열이 끝나기 전까지tbl[i] = (struct codeword*)malloc(sizeof(struct codeword));tbl[i]->code = fgetc(HeadIn); //tbl[i]->code에 한 문자씩 삽입tbl[i]->word = 0; //codeword 넣기.for(j = 24; j >= 0 ; j=j-8){//Character형은 8bit 이므로 8단위씩 줄어듬ii = fgetc(HeadIn);tbl[i]->word = tbl[i]->word+(ii*twosmulti(j));}//한문자 씩 읽어 들여 ii에 저장하고, twosmulti(j)로 2의 제곱승 계t
제목 : C언어를 이용한Image Rotation & Interpolation과 목 명 :담당교수 :제 출 일 :학 과 :학 번 :이 름 :1. 이론(1) Image RotationImage Rotation은 cos와 sin을 통하여 배열에 저장된 pixel들을 회전 시키는 것을 말한다. 우리가 흔히 이미지 툴로 사용 하는 포토샵에 보면 Rotate 라는 곳에 이미지를 회전시키는 기능들이 있다. 포토샵에서는 클릭 하나로 끝나지만 이번 실습을 통하여 어떠한 알고리즘을 가지고 이미지가 회전 되는지 알아보았다.Image Rotation 의 원리는 우리가 고등학교 시절에 배운 행렬의 연산 응용에 등장 한다. 그 수식은 아래와 같다.위의 식은 θ의 값에 따라 pixel의 좌표 값을 변화 시켜 준다. 여기서 Image Rotation의 특징이 나타나는데, 우리가 지금 까지 배워왔던 것과 다른 점은 pixel에 저장된 값을 처리하는 것이 아니라 pixel의 좌표 값을 처리하는 것이다. 즉 pixel의 명암 값은 보존하고 위치 값만 변환 시킨다. 그런데 Image Rotation은 회전 할 경우 이미지의 두 가지 유형의 손상이 생긴다. 하나는 삼각함수를 계산함에 있어 계산 결과로 나오는 위치 값을 정수화 시켜주다 보니 손실되는 위치 정보가 생겨 계단현상이 발생 하는 것이고, 또 하나는 사이즈를 보존하며 회전 시킬 경우 이미지의 꼭지점 부분이 잘려나가는 것이다.(2) Interpolation앞에 설명한 Image Rotation과 Interpolation은 이미지의 기하학적 처리 영역에 속하는 분야이다. 우리가 어떠한 이미지를 편집할 때 회전만큼 많이 사용하게 되는 것이 확대가 아닐까 한다. 그런데 포토샵이나 전문적인 이미지 툴에서 확대를 하면 이미지 확대 후 발생하는 계단 현상을 smoothing을 통하여 보정해 주거나 anti-aliasing 기능을 통하여 자연스럽게 처리해 주지만 그림판이나 아니면 아주 고배율로 확대하게 되면 pixel들이 커지면서 계단 현상이 나타나게 된다. 이러한 이유는 모두 Interpolation의 알고리즘에 그 원인이 있다.1?2?????3?4?????Interpolation은 보간법이라고 하는데 기본적인 개념은 아래 보이는 것처럼 이미지를 확대 할 경우 값을 갖지 못하는 pixel에 주변 pixel들을 이용하여 값을 할당해 주는 것이다.1234×2 →물음표로 처리된 곳에 주변 pixel을 이용하는 방법에 따라 4가지의 보간법이 존재 하는데, Nearest Neighbor interpolation, Bilinear interpolation, Cubic Convolution interpolation, B-Spline interpolation 이 있다. 이번 실습에서는 Bilinear interpolation, B-Spline interpolation 을 사용하여 이미지를 2배 확대해 보기로 한다.실습에 들어가기 전에 두 보간법의 차이를 잠깐 살펴보자면, Bilinear interpolation은 주변 pixel값을 더한 후 참조한 pixel수만큼 나누어 평균값으로 채워 넣는 방법이다. 마치 영역기반 처리에서 LPF와 그 연산 방법이 비슷하다고 보면 된다.반면 B-Spline interpolation 은 B-Spline 이라는 함수를 이용하여 채워 넣을 pixel의 거리에 반비례 하여 가중치를 주어 값을 채워 넣는 방법으로, 참조하는 pixel들에 B-Spline 계수를 곱하여 값을 누적시킨다. 그런데 여기서 주목해야 할 점은 그 계수들의 합이 1이어야 한다는 것이다. 이유는 누적 합이기 때문에 저장되는 pixel의 명암 값이 지나치게 높아져 버리기 때문이다. 영역기반 처리에서 HPF의 마스크 내의 계수의 합을 1로 맞추는 것과 비슷한 개념이라고 생각하면 쉽다.2. 내용이번 실습에서 rotation은 matlab으로 구현하고 interpolation은 C언어를 통하여 구현해 보았다. 먼저 matlab에서 512×512의 lena 이미지를 30° 회전하여 원래 이미지와 회전 후 이미지의 차이점을 분석해 보았다.그리고 두 번째로 256×256 lena 이미지를 Bilinear interpolation과 B-Spline interpolation 을 통하여 각각 확대해 본 후 소스 분석과 결과 이미지 분석을 통하여 차이점을 비교해 보았다.(1) Image Rotationclear all;clc;close all;fid2 = fopen('lena512.raw'); %원본 파일을 로드col=512;row=512;Original_img=fread(fid2,[col,row],'uchar'); %이미지를 읽어들여 저장. 이미지가 옆으로 누워있는 상태Original_img=transpose(Original_img); %원본 이미지의 행과 열을 서로 바꿈. 이미지를 원래대로 세움.figure;imshow(Original_img, [0 255]); %이미지 출력. 밝기 범위 값은 0~255new = zeros(512);smallone =zeros(256);%이미지 축소 부분 512->256for i = 1 : 256for j = 1 : 256smallone(i,j)=Original_img(i*2,j*2); % 원본 이미지의 짝수 행, 열 값만 저장.endendfigure;imshow(smallone, [0 255]);% 회전 기준 픽셀 설정.xCenter=127;yCenter=127;radian = (30*pi/180); % 우측으로 30도 회전, -30을 입력하면 좌측으로 30도 회전하게 됨.d(4)=0;height=256;width=256;for y=1:256for x=1:256cosAngle=cos(radian);sinAngle=sin(radian);f_xorg=cosAngle*(x-xCenter)+sinAngle*(y-yCenter)+xCenter; %행을 120,120 을 기준으로 회전 연산 부분f_yorg=-sinAngle*(x-xCenter)+cosAngle*(y-yCenter)+yCenter; %열을 120,120 을 기준으로 회전 연산 부분i_xorg=fix(f_xorg); %소수점 이하 값을 버림 하여 정수화.i_yorg=fix(f_yorg);dx=f_xorg-double(i_xorg); %버림한 소수점 이하 값만 추출. 이부분에서 위치 정보값들이 손실 됨.dy=f_yorg-double(i_yorg);if(i_yorg(height-1) | i_xorg(width-1))elsed(1) = sqrt(dx^2+dy^2);d(2) = sqrt( (1-dx)^2+dy^2);d(3) = sqrt(dx^2 + (1-dy)^2);d(4)= sqrt( (1-dx)^2+ (1-dy)^2);min=d(1);num=1;for p=1:4 %1~4 까지 루프if(d(p)
제목 : MATLAB을 이용한noise 모델 구성 및 복원과 목 명 :담당교수 :제 출 일 :학 과 :학 번 :이 름 :1. 이 론(1) 주기성 잡음주기성 잡음이란 잡음의 패턴이 일정하여 주기적인 함수로 나타낼 수 있는 규칙성을 가진 잡음을 말한다. 시간 영역에서 주기성 잡음은 일정한 패턴을 가지고 연속되는 잡음으로 우리 눈에 보이게 된다. 이러한 잡음을 주파수 영역으로 변환 하여 분석 하게 되면 시간영역에서 보다 더 단순한 패턴을 가지고 표현 되는 것을 볼 수가 있다.그림 1그림 1에서 보는 바와 같이 연속성을 갖는 본래의 잡음 이미지를 주파수 영역으로 변환 하였을 때 8개의 점이 일정한 간격으로 원 모양을 이루고 있는 것을 볼 수 있다. 이처럼 주기성을 갖는 특수한 경우의 잡음은 주파수 영역에서 분석하게 되면 기하학적인 형태로 단순화되기 때문에 잡음의 특성을 쉽게 파악 할 수 있으며 잡음을 처리 하는 것에 있어 시간영역에서 보다 작업이 단순화 되고 복잡성이 줄어들어 효율 적인 처리를 할 수 있다.(2) 주기성 잡음의 제거그림 1의 Original 잡음은 시간영역에서 공간 필터를 이용하여 제거하기에는 상당히 어려움이 있다. 우선 이미지 전체에 대한 연산을 해준 후 결과 값을 출력해야 한다. 앞서 우리가 배운 median filter나 LPF 필터, 영역 전체에 효과가 적용 되는 필터들을 구현할 경우 이미지 전체에 흐려짐과 같은 부작용이 나타 날 수 있다. 하지만 주파수 영역에서는 원모양을 갖는 차단 필터를 사용하면 시간영역에서 처리보다 이미지의 변화를 줄이면서 8개의 점으로 이루어진 잡음만 지워버릴 수 있다. 이러한 필터를 Band Stop Filter(대역 정지 필터) 라고 한다.그림 2그림 2의 모양의 필터를 주파수 영역에서 사용하게 되면 그림 1의 잡음을 제거 할 수 있다. 더 나아가 주파수 영역에서의 잡음의 모양이 원과 같지 않고 다양한 모양을 가질 경우 주기성만 가지고 있으면 기하학적인 모양의 필터를 구현하여 제거 할 수 있다.이러한 주파수 영역에서의 잡음의 처리는 잡음이 주기성을 갖지 않고 불규칙 하게 생성될 경우에도 시간영역에서의 분석보다 훨씬 단순화 된 분석을 할 수 있는 가능성이 크기 때문에 여러 모로 유용하지만수학적인 접근이 필요하기 때문에 수학적 지식과 전문성을 요구 하는 고난이도 작업이다.주파수의 특정 부분만 차단하는 것을 응용하여 특정 부분을 강조하거나 추출하기 위해 대역 통과 필터를 사용하기도 한다.2. 내 용clc; clear all close allD0=127; % 필터의 최초 위치를 정하는 D0를 선언W=100; % 필터의 영역과 (함수의) 형태를 결정하는 W 선언%Read Image fileInput=imread('./Fig4_11.jpg');N=size(Input);%Create NoiseT=floor(sqrt(64*64*2));C=[0 128; 128 0; T T;T -T];[r, R, S]=imnoise3(500,500,C); % 노이즈 함수 호출imshow(S,[]); % 노이스함수 참조 : S는 이미지의 절대값 형태title('1. Frequency image of Noise');figure, imshow(r,[]); % 노이즈함수 참조 :% r은 이미지를 주파수 영역으로 구성(DFT)하고 중앙으로 시프트 작업한 형태.title('2. Noise Image');%Fourier TransformF1=fft2(Input); % 노이즈가 들어간 이미지를 주파수 영역으로 구성.%Centering of DFTF2=fftshift(F1); % 주파수 영역으로 구성된 이미지를 중앙으로 시프트(Centering)%Add Noise;F22 = F2 +10000000*R; % 상기 제공된 노이즈를 원본 이미지에 더한다.F23=log(1+abs(F22)); % log를 씌워 숫자를 축소하여 이미지와 시킨다.%Inverse Fourier TransformF3=ifftshift(F22); % 노이즈가 추가된 주파수 영역 이미지를 역CenteringF4=ifft2(F3); % 주파수 영역 이미지를 공간 영역으로 재구성 해준다.(역DFT)figure;imshow(F4, [0 255]); % 노이즈가 추가된 이미지가 출력된다.title('3. original image: noisy');figure;imshow(abs(F23), [ ]); % 역DFT 하기전 주파수 영역의 이미지를 출력한다.title('4, Frequency image of noisy input');% transfer function of ideal bandstop filterH=ones(N, N);% %Design your filter here !!!!!!!!!!!!!!!!% H = ones(N,N);% for u=1:N% for v=1:N% D = sqrt((u-N/(2)).^2+(v-N/(2)).^2); % 필터의 영역을 원형으로 설정% if D >= D0-W% if D = D0-Wif D = D0-100% if D