PowerPoint 프레젠테이션

Similar documents
PowerPoint 프레젠테이션

<B9CCB5F0BEEE20C1A4BAB8C3B3B8AE2E687770>

K&R2 Reference Manual 번역본

歯Lecture2.PDF

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

Dialog Box 실행파일을 Web에 포함시키는 방법

슬라이드 1

윈도우시스템프로그래밍

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

슬라이드 1

Microsoft PowerPoint - chap06-2pointer.ppt

PowerPoint 프레젠테이션

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

쉽게 풀어쓴 C 프로그래밍

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

chap 5: Trees

Lab 3. 실습문제 (Single linked list)_해답.hwp

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

PowerPoint 프레젠테이션

목차 포인터의개요 배열과포인터 포인터의구조 실무응용예제 C 2

chap10.PDF

C++-¿Ïº®Çؼ³10Àå

BMP 파일 처리

PowerPoint 프레젠테이션

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

히스토그램구하기 사전준비 : 히스토그램을저장할메모리가필요함 필요한메모리개수 à 전체영상의픽셀은그값이 0 ~ 255이므로 256 개의메모리필요함 영상을구성하는픽셀의개수는매우크므로메모리형식은 unsigned long으로해야함 ( unsigned 란 +/- 를고려하지않는다는

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

Microsoft PowerPoint - chap06-1Array.ppt

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

PowerPoint Presentation

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

금오공대 컴퓨터공학전공 강의자료

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

PowerPoint Presentation

윈도우시스템프로그래밍

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

Microsoft PowerPoint - chap11-포인터의활용.pptx

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

untitled

윤성우의 열혈 TCP/IP 소켓 프로그래밍

그래픽 프로그래밍

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

Comtrol ID 레이블 Hotkey Callback 함수 ⑴ Button, IDC_BTN_DEPT, &Department, OnBtnDepartment ⑵ Button, IDC_BTN_EMP, &Employee, OnBtnEmployee ⑶ Button, IDC_B

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

PowerPoint 프레젠테이션

슬라이드 1

슬라이드 1

Microsoft PowerPoint - ch10 - 이진트리, AVL 트리, 트리 응용 pm0600

Microsoft PowerPoint - additional01.ppt [호환 모드]

슬라이드 1

untitled

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Data Sync Manager(DSM) Example Guide Data Sync Manager (DSM) Example Guide DSM Copyright 2003 Ari System, Inc. All Rights reserved. Data Sync Manager

<4D F736F F F696E74202D203039C0E520B4EBC8ADBBF3C0DA205BC8A3C8AF20B8F0B5E55D>

C프로-3장c03逞풚

슬라이드 1

Microsoft PowerPoint - Java7.pptx

PowerPoint 프레젠테이션

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

Microsoft PowerPoint - ch07 - 포인터 pm0415

untitled

소프트웨어공학 Tutorial #2: StarUML Eun Man Choi

11장 포인터

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )

(Microsoft PowerPoint - 07\300\345.ppt [\310\243\310\257 \270\360\265\345])

PowerPoint 프레젠테이션

UI TASK & KEY EVENT

설계란 무엇인가?

03장.스택.key

Microsoft PowerPoint 세션.ppt

PowerPoint Presentation

PowerPoint Presentation

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C4C656D70656C2D5A69762E637070>

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - chap06-5 [호환 모드]

Microsoft PowerPoint - C++ 5 .pptx

Microsoft PowerPoint - hci2-lecture9.ppt

Microsoft PowerPoint _대화상자.ppt

02 C h a p t e r Java

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

Design Issues

adfasdfasfdasfasfadf

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

untitled

Microsoft PowerPoint - IP11.pptx

13주-14주proc.PDF

Microsoft PowerPoint - 09-Object Oriented Programming-3.pptx

API 매뉴얼

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

PowerPoint 프레젠테이션

쉽게 풀어쓴 C 프로그래밍

Transcription:

15 장프로젝트 _ 웨이브렛변환 웨이브렛변환의개념 웨이브렛변환을위한 MFC 설정하기 파일입. 출력설정하기 웨이브렛변환을위한대화상자설정하기 순방향웨이브렛변환구현하기 역방향웨이브렛변환구현하기 한빛미디어 ( 주 )

15 장. 프로젝트 _ 웨이브렛변환 학습목표 웨이브렛변환의개념을소개한다. 순방향웨이브렛변환프로그램을실습한다. 역방향웨이브렛변환프로그램을실습함다. 2

Section 01 웨이브렛변환의개념 웨이브렛은기본함수로 sine, cosine 함수외에웨이브렛모함수를사용하는데, 각주파수영역에따라변화하는다양한기저함수를생성하여사용함 시간 - 주파수에국부적인성질이있음. 푸리에변환은시간과주파수정보를동시에파악할수없지만웨이브렛에서는이둘을동시에파악가능 3

필터뱅크를이용한이산웨이브렛변환수행 이산웨이브렛변환은저주파통과필터와고주파통과필터로구성된필터뱅크로수행됨. 이때, 사용되는필터는특수하게설계된것으로, 직교특성, 선형특성, 고주파와저주파부분을정확하게분할하는특성이있음. 4

필터뱅크를이용한이산웨이브렛변환수행 ( 계속 ) 필터뱅크의동작을이용한웨이브렛변환과역변환의수행과정을나타낸것. 필터링은컨벌루션으로수행됨. 웨이브렛변환과정에서는각각필터링한뒤데이터의크기를절반으로줄이는다운샘플링이수행되고, 웨이브렛역변환과정에서는각필터링한뒤데이터의크기를원상태로보상해주려고두배로증가시키는업샘플링이수행됨. 5

필터뱅크를이용한 2 차원이산웨이브렛변환 웨이브렛을영상에적용하려면 2 차원처리를수행해야함. 분리성을만족함. 먼저세로방향으로웨이브렛을수행한뒤가로방향으로웨이브렛을수행하면 2 차원웨이브렛변환이가능 6

Section 02 웨이브렛변환을위한 MFC 설정하기 ➊ Visual C++ 프로그램을실행 [File]-[New] 메뉴클릭 7

Section 02 웨이브렛변환을위한 MFC 설정하기 ( 계속 ) ➋ [New] 대화상자의 [Projects] 탭에서 MFC AppWizard [exe] 항목을선택 Project name 란에다음과같이입력 8

Section 02 웨이브렛변환을위한 MFC 설정하기 ( 계속 ) ➌ [MFC AppWizard] 대화상자에서 MDI 기반에서작성하기위해 MDI(multiple documents) 항목을선택 [Finish] 버튼클릭해기본환경설정완료 9

Section 03 파일입 출력설정하기 ➊ Visual C++ 프로그램에서 [View]-[ClassWizard] 메뉴클릭 ➋ [MFC ClassWizard] 대화상자의 Class name 항목에서 CWaveletTransformDoc를선택 Message 항목에서 OnOpenDocument 더블클릭 CWaveletTransformDoc에 OnOpenDocument 함수추가 10

Section 03 파일입 출력설정하기 ( 계속 ) ➌ 함수에서사용할입력영상버퍼변수, 출력영상버퍼변수, 영상의크기와관련된변수추가 11

Section 03 파일입 출력설정하기 ( 계속 ) ➍ BOOL CWaveletTransformDoc::OnOpenDocument(LPCTSTR lpszpathname) 에다음프로그램추가 (1) BOOL CWaveletTransformDoc::OnOpenDocument(LPCTSTR lpszpathname) { if(!cdocument::onopendocument(lpszpathname)) return FALSE; CFile File; File.Open(lpszPathName, CFile::modeRead CFile::typeBinary); if(file.getlength() == 256*256){ // RAW 파일의크기결정 m_height = 256; m_width = 256; else if(file.getlength() == 512*512){ // RAW 파일의크기결정 m_height = 512; m_width = 512; else{ AfxMessageBox("Not Support Image Size"); return 0; 12

Section 03 파일입 출력설정하기 ( 계속 ) ➍ BOOL CWaveletTransformDoc::OnOpenDocument(LPCTSTR lpszpathname) 에다음프로그램추가 (2) m_size = m_height * m_width; m_inputimage = new unsigned char [m_height * m_width]; // 입력영상저장공간 m_outputimage = new unsigned char [m_height * m_width]; // 출력영상저장공간 for(int i = 0 ; i<m_height * m_width ; i++){ m_inputimage[i] = 255; // 초기화 m_outputimage[i] = 255; // 초기화 File.Read(m_InputImage, m_height * m_width); // 파일읽기 File.Close(); return TRUE; 13

Section 03 파일입 출력설정하기 ( 계속 ) ➎ 입력된영상을확인하기위해 CWaveletTransformView::OnDraw(CDC* pdc) 에다음프로그램추가 void CWaveletTransformView::OnDraw(CDC* pdc) { CWaveletTransformDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here int i, j; int R, G, B; for(i=0 ; i<pdoc->m_height ; i++){ for(j=0 ; j<pdoc->m_width ; j++){ R = pdoc-> m_inputimage[i*pdoc->m_width + j]; B = G = R; pdc->setpixel(j+5, i+5, RGB(R, G, B)); // 입력영상을화면에출력 for(i=0 ; i<pdoc->m_height ; i++){ for(j=0 ; j<pdoc->m_width ; j++){ R = pdoc->m_outputimage[i*pdoc->m_width + j]; B = G = R; pdc->setpixel(j+pdoc->m_width+10, i+5, RGB(R, G, B)); // 복원된영상을화면에출력 14

Section 04 웨이브렛변환을위한대화상자설정하기 ➊ ResourceView 창에서 [WaveletTransform resources]-[dialog] 폴더에서마우스오른쪽버튼을클릭 바로가기메뉴 [Insert Dialog] 클릭 ➋ 추가된대화상자를오른쪽과같이편집 15

Section 04 웨이브렛변환을위한대화상자설정하기 ( 계속 ) ➌ 대화상자속성을다음과같이정의 16

Section 04 웨이브렛변환을위한대화상자설정하기 ( 계속 ) ➍ 대화상자위에서마우스오른쪽버튼을눌러 [ClassWizard] 메뉴를클릭 [ClassWizard] 대화상자에서 [Add Class] 버튼클릭 [Adding a Class] 대화상자에서 Create a new class 항목선택 17

Section 04 웨이브렛변환을위한대화상자설정하기 ( 계속 ) ➎ 다음과같이대화상자를클래스에등록 18

Section 04 웨이브렛변환을위한대화상자설정하기 ( 계속 ) ➏ [Class Wizard] 대화상자에서 [Add Variable] 버튼클릭 [Add Member Variable] 대화상자에서 CWaveletTransforDlg 대화상자를선택 변수추가 19

Section 05 순방향웨이브렛변환구현하기 ➊ ResourceView 창에서 [Menu]-[IDR_IMAGETYPE] 더블클릭해메뉴추가 ➋ 메뉴를추가할부분을더블클릭 [Menu Item Properties] 대화상자에서다음과같이캡션추가 20

➌ 프로그램을실행하는실제메뉴를추가하려고 ➋ 처럼메뉴가들어갈위치를더블클릭 [Menu Item Properties] 대화상자에서다음과같이속성지정 ➍ 해당메뉴위에서마우스오른쪽버튼을눌러 바로가기메뉴 [ClassWizard] 클릭 21

➎ [MFC Class Wizard] 대화상자의 [Message Maps] 탭에서 Object IDs 항목과 Messages 항목을다음과같이지정하고 [Add Function] 버튼클릭 [Add Member Function] 대화상자에서 [OK] 버튼을눌러함수를추가 [Edit Code] 버튼을눌러함수로이동 22

➏ CWaveletTransformView::OnWaveletTransform에다음과같이프로그램을작성. CWaveletTransformView는 CWaveletTransformDoc를호출하는역할을하고, 웨이브렛변환은 CWaveletTransformDoc에서일어나게됨 void CWaveletTransformView::OnWaveletTransform() { CWaveletTransformDoc* pdoc = GetDocument(); ASSERT_VALID(pDoc); pdoc->onwavelettransform(); // Doc 클래스에서생성해야할함수이름 Invalidate(TRUE); 23

➐ ResoureViess 창의 CWaveletTransformDoc 폴더위에서마우스오른쪽버튼클릭후바로가기메뉴 [Add Member Function] 클릭 [Add Member Function] 대화상자에서 OnWaveletTransform 함수추가 24

➑ CWaveletTransformDoc::OnWaveletTransform 에서는입력된영상과미리만든대화상자를이용하여웨이브렛변환실행. Wavelet Transform 대화상자를호출할수있도록 [File View]-[Header File]-[WaveletTransformDoc.h] 파일을클릭하여다음부분추가 // avelettransformdoc.h : interface of the CWaveletTransformDoc class ////////////////////////////////////////////////////////////// #if!defined(afx_wavelettransformdoc_h 4A38BAEB_ E3CB_44C9_B2CB_057CD4D9FF0A INCLUDED_) #define AFX_WAVELETTRANSFORMDOC_H 4A38BAEB_E3CB_44C9_ B2CB_057CD4D9FF0A INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "WaveletTransformDlg.h" // 대화상자헤더선언 class CWaveletTransformDoc : public CDocument { protected: // create from serialization only CWaveletTransformDoc(); DECLARE_DYNCREATE(CWaveletTransformDoc) // Attributes public: // Operations public: CWaveletTransformDlg *pdlg; 25

➒ CWaveletTransformDoc 클래스의생성자와소멸자를다음과같이작성 CWaveletTransformDoc::CWaveletTransformDoc() { // TODO: add one-time construction code here pdlg = new CWaveletTransformDlg(this); CWaveletTransformDoc::~CWaveletTransformDoc() { delete pdlg; 26

➓ 생성된함수 CWaveletTransformDoc::OnWaveletTransform 을다음과같이작성여기서 WaveletTransform 대화상자를호출하게됨. void CWaveletTransformDoc::OnWaveletTransform() { if(pdlg->getsafehwnd() == NULL) pdlg->create(idd_dialog1); // 모달리스대화상자이용 pdlg->showwindow(sw_show); 27

11 CWaveletTransformDlg 클래스로이동. 대화상자를이용하여변환에사용되는변수를입력받게됨. [File View]-[Header Files]-[WaveletTransformDlg.h] 파일로이동하여다음프로그램추가 ////////////////////////////////////////////////////////// // CWaveletTransformDlg dialog class CWaveletTransformDoc; class CWaveletTransformDlg : public CDialog { // Construction public: CWaveletTransformDlg(CWnd* pparent = NULL); // standard constructor CWaveletTransformDlg(CWaveletTransformDoc *pdoc, CWnd* pparent = NULL); : // Implementation protected: CWaveletTransformDoc *m_pdoc; 28

12 [File View]-[Source Files]-[WaveletTransformDlg.cpp] 파일로이동하여다음과같이프로그램수정 #include "WaveletTransformDoc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////// // CWaveletTransformDlg dialog CWaveletTransformDlg::CWaveletTransformDlg(CWnd* pparent /*=NULL*/) : CDialog(CWaveletTransformDlg::IDD, pparent) { m_pdoc = NULL; CWaveletTransformDlg::CWaveletTransformDlg(CWaveletTransform Doc *pdoc, CWnd* pparent /*=NULL*/) : CDialog(CWaveletTransformDlg::IDD, pparent) { m_pdoc = pdoc; // Doc 클래스참조 m_level = 1; // Wavelet 분해레벨초기화 m_error = 0.0f; // MSE 초기화 m_snr = 0.0f; // SNR 초기화 m_filtercheck = 0; // Filter Check 초기화 29

13 Section 05 순방향웨이브렛변환구현하기 ( 계속 ) [MFC Class Wizard] 대화상자의 Wavelet Transform 대화상자에서 [ 변환 ] 버튼클릭 웨이브렛변환이일어나도록다음과같이함수추가 30

void CWaveletTransformDlg::OnButtonUpdate() { // TODO: Add your control notification handler code here UpdateData(TRUE); m_pdoc->m_level = m_level; // 대화상자에서입력받은레벨값을 Doc 클래스에전달 m_pdoc->onwaveletencode(); // 웨이브렛변환 UpdateData(FALSE); // 결과업데이트 31

14 Section 05 순방향웨이브렛변환구현하기 대화상자의변환버튼이클릭되면변환이실행되고실행코드는 CWaveletTransformDoc 클래스에서있게됨. CWaveletTransformDoc 클래스로이동하여 OnWaveletEncode 함수추가 32

15 수학함수를사용하기위해 CWaveletTransforDoc.cpp 의위쪽에다음과같이선언 // WaveletTransformDoc.cpp:implementation of the CWaveletTransformDoc class // #include "stdafx.h" #include "WaveletTransform.h" #include "WaveletTransformDoc.h" #include "math.h" // 수학함수를위한헤더선언 33

16 Section 05 순방향웨이브렛변환구현하기 ( 계속 ) OnWaveletEncode 함수에서사용되는전역변수를선언하기위해 [WaveletTransform Classes]-[CWaveletTransformDoc] 폴더위에서마우스오른쪽버튼클릭 [Add Member Variable] 클릭 [Add Member Variable] 대화상자를이용해변수추가 34

17 Section 05 순방향웨이브렛변환구현하기 ( 계속 ) CWaveletTransformDoc 폴더위에서마우스오른쪽버튼클릭 [Add Member Function] 클릭 [Add Member Function] 대화상자에서 OnWaveletEncode 함수에서사용되는함수를선언하고작성 35

1 OnDownSampling 함수추가하기 double* CWaveletTransformDoc::OnDownSampling(double *m_target, int size) { int i; double* m_temp; m_temp = new double [size / 2]; for(i=0 ; i<size/2 ; i++) m_temp[i] = m_target[2*i]; // 다운샘플링처리 return m_temp; 36

2 OnConvolution 함수추가하기 (1) double* CWaveletTransformDoc::OnConvolution(double *m_target, double *m_filter, int size, int mode) { // Circular Convolution 을위한함수 int i, j; double *m_temp, *m_tempconv; double m_sum = 0.0; m_temp = new double [size + m_filtertap - 1]; m_tempconv = new double [size]; // Convolution 결과출력배열 switch(mode){ case 1 : // Circular Convolution 을위한초기화 for(i=0 ; i<size ; i++) m_temp[i] = m_target[i]; for(i=0 ; i<m_filtertap-1 ; i++) m_temp[size + i] = m_target[i]; break; 37

2 OnConvolution 함수추가하기 (2) case 2 : for(i=0 ; i<m_filtertap-1 ; i++) m_temp[i] = m_target[size - m_filtertap + i + 1]; for(i=m_filtertap-1 ; i<size + m_filtertap-1 ; i++) m_temp[i] = m_target[i - m_filtertap + 1]; break; for(i=0 ; i<size ; i++){ for(j=0 ; j<m_filtertap ; j++){ m_sum += (m_temp[j+i] * m_filter[m_filtertap-j-1]); // Convolution 연산 m_tempconv[i] = m_sum; m_sum = 0.0; return m_tempconv; // 연산결과를반환 38

3 OnFilterTapGen 함수추가하기 void CWaveletTransformDoc::OnFilterTapGen() { // Filter Tap 선택 switch(pdlg->m_filtercheck) { case 0 : m_filtertap = 2; break; case 1 : m_filtertap = 4; break; case 2 : m_filtertap = 6; break; case 3 : m_filtertap = 8; break; default : AfxMessageBox("Wrong Filter Tap"); return; 39

4 OnFilterGen 함수추가하기 (1) void CWaveletTransformDoc::OnFilterGen(double *m_h0, Double *m_h1, double *m_g0, double *m_g1) { // 필터계수값 int i; switch(m_filtertap) { case 2 : m_h0[0] = 0.70710678118655; m_h0[1] = 0.70710678118655; break; case 4 : m_h0[0] = -0.12940952255092; m_h0[1] = 0.22414386804186; m_h0[2] = 0.83651630373747; m_h0[3] = 0.48296291314469; break; case 6 : m_h0[0] = 0.03522629188210; m_h0[1] = -0.08544127388224; m_h0[2] = -0.13501102001039; m_h0[3] = 0.45987750211933; m_h0[4] = 0.80689150931334; m_h0[5] = 0.33267055295096; break; 40

4 OnFilterGen 함수추가하기 (2) case 8 : m_h0[0] = -0.01059740178500; m_h0[1] = 0.03288301166698; m_h0[2] = 0.03084138183599; m_h0[3] = -0.18703481171888; m_h0[4] = -0.02798376941698; m_h0[5] = 0.63088076792959; m_h0[6] = 0.71484657055254; m_h0[7] = 0.23037781330886; break; default : AfxMessageBox("Wrong Filter"); return; // H0 필터계수를이용해, H1, G0, G1 필터계수생성 for(i=0 ; i<m_filtertap ; i++) m_h1[i] = pow(-1,i+1) * m_h0[m_filtertap - i - 1]; for(i=0 ; i<m_filtertap ; i++) m_g0[i] = m_h0[m_filtertap - i - 1]; for(i=0 ; i<m_filtertap ; i++) m_g1[i] = pow(-1, i) * m_h0[i]; 41

5 OnMem2DAllocUnsigned 함수추가하기 unsigned char** CWaveletTransformDoc::OnMem2DAllocUnsigned (int height, int width) { // unsigned char 형태의 2차원배열할당 int i, j; unsigned char** temp; temp = new unsigned char *[height]; for(i=0 ; i<height ; i++) // 2 차원배열할당 temp[i] = new unsigned char [width]; for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ temp[i][j] = 0; // 2차원배열초기화 return temp; 42

6 OnMem2DAlloc double 함수추가하기 double** CWaveletTransformDoc::OnMem2DAlloc double(int height, int width) { // double 형태의 2차원배열할당 int i, j; double** temp; temp = new double *[height]; for(i=0 ; i<height ; i++) temp[i] = new double [width]; for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ temp[i][j] = 0; return temp; 43

7 OnScale 함수추가하기 (1) double** CWaveletTransformDoc::OnScale(double **m_target, int height, int width) { // 정규화함수 : 필터링된값을 0~255 사이의값으로정규화 int i, j; double min, max; double **temp; temp = OnMem2DAlloc double(height, width); min = max = m_target[0][0]; for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ if(m_target[i][j] <= min){ min = m_target[i][j]; // 최소값 if(m_target[i][j] >= max){ max = m_target[i][j]; // 최대값 44

7 OnScale 함수추가하기 (2) max = max - min; for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ temp[i][j] = (m_target[i][j] - min) * (255. / max); // 정규화처리 return temp; 45

18 OnWaveletEncode 함수작성 (1) void CWaveletTransformDoc::OnWaveletEncode() { // Wavelet encode 함수 if(m_level <= 0 (pow(2, m_level+3) > (double) m_width) (pow(2, m_level+3) > (double) m_height)){ AfxMessageBox("Not support decomposition level"); return; // 최대분해레벨이 512*512이면 6레벨로제한 int i, j, k, width, height; double *m_conv1, *m_conv2, *m_conv3, *m_conv4; // Convolution을위한버퍼 double *m_down1, *m_down2, *m_down3, *m_down4; // 다운샘플링을위한버퍼 double *m_hor, *m_ver1, *m_ver2; double **m_l, **m_h, **m_ll, **m_lh, **m_hl, **m_hh, **m_sll, **m_slh, **m_shl, **m_shh; m_tempinput = OnMem2DAlloc double(m_height, m_width); m_tempoutput = OnMem2DAlloc double(m_height, m_width); m_arrangeimage = OnMem2DAllocUnsigned(m_Height, m_width); for(i=0 ; i< m_height ; i++){ for(j=0 ; j< m_width ; j++){ m_tempinput[i][j] = (double) m_inputimage[i* m_width + j]; // 1차원입력을 2차원배열로변환 46

18 OnWaveletEncode 함수작성 (2) OnFilterTapGen(); // 필터 tap 생성 m_filterh0 = new double [m_filtertap]; // 필터계수를위한배열 m_filterh1 = new double [m_filtertap]; // 필터계수를위한배열 m_filterg0 = new double [m_filtertap]; // 필터계수를위한배열 m_filterg1 = new double [m_filtertap]; // 필터계수를위한배열 OnFilterGen(m_FilterH0, m_filterh1, m_filterg0, m_filterg1); // 필터계수생성 width= m_width; height= m_height; for(k=0 ; k<m_level ; k++){ m_l = OnMem2DAlloc double(height, width/2); // m_h = OnMem2DAlloc double(height, width/2); // m_ll = OnMem2DAlloc double(height/2, width/2); // LL 저장을위한배열 m_lh = OnMem2DAlloc double(height/2, width/2); // LH 저장을위한배열 m_hl = OnMem2DAlloc double(height/2, width/2); // HL 저장을위한배열 m_hh = OnMem2DAlloc double(height/2, width/2); // HH 저장을위한배열 m_hor = new double [width]; // 횡입력을위한배열 47

18 OnWaveletEncode 함수작성 (3) for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ m_hor[j] = m_tempinput[i][j]; // 입력배열을 1차원배열에할당 m_conv1 = OnConvolution(m_Hor, m_filterh0, width, 1); // Convolution 처리 m_conv2 = OnConvolution(m_Hor, m_filterh1, width, 1); // Convolution 처리 m_down1 = OnDownSampling(m_Conv1, width); // 다운샘플링 m_down2 = OnDownSampling(m_Conv2, width); // 다운샘플링 for(j=0 ; j<width/2 ; j++){// 다운샘플링결과를저장 m_l[i][j] = m_down1[j]; m_h[i][j] = m_down2[j]; m_ver1 = new double[height]; m_ver2 = new double[height]; 48

18 OnWaveletEncode 함수작성 (4) for(i=0 ; i<width/2 ; i++){ for(j=0 ; j<height ; j++){ m_ver1[j] = m_l[j][i]; // 열방향으로 1차원배열에할당 m_ver2[j] = m_h[j][i]; m_conv1 = OnConvolution(m_Ver1, m_filterh0, height, 1); // Convolution 처리 m_conv2 = OnConvolution(m_Ver1, m_filterh1, height, 1); m_conv3 = OnConvolution(m_Ver2, m_filterh0, height, 1); m_conv4 = OnConvolution(m_Ver2, m_filterh1, height, 1); m_down1 = OnDownSampling(m_Conv1, height); // 다운샘플링 m_down2 = OnDownSampling(m_Conv2, height); m_down3 = OnDownSampling(m_Conv3, height); m_down4 = OnDownSampling(m_Conv4, height); for(j=0 ; j<height/2 ; j++){ m_ll[j][i] = m_down1[j]; // 결과저장 m_lh[j][i] = m_down2[j]; m_hl[j][i] = m_down3[j]; m_hh[j][i] = m_down4[j]; 49

18 OnWaveletEncode 함수작성 (6) m_sll = OnScale(m_LL, height/2, width/2); // 처리결과를정규화 m_slh = OnScale(m_LH, height/2, width/2); m_shl = OnScale(m_HL, height/2, width/2); m_shh = OnScale(m_HH, height/2, width/2); for(i=0 ; i<height/2 ; i++){ for(j=0 ; j<width/2 ; j++){ m_tempoutput[i][j] = m_ll[i][j]; m_tempoutput[i][j+(width/2)] = m_hl[i][j]; m_tempoutput[i+(height/2)][j] = m_lh[i][j]; m_tempoutput[i+(height/2)][j+(width/2)] = m_hh[i][j]; // 처리결과를정렬 m_arrangeimage[i][j] = (unsigned char)m_sll[i][j]; m_arrangeimage[i][j+(width/2)] = (unsigned char)m_shl[i][j]; m_arrangeimage[i+(height/2)][j] = (unsigned char)m_slh[i][j]; m_arrangeimage[i+(height/2)][j+(width/2)] = (unsigned char)m_shh[i][j]; // 정규화과정을거친정렬영상 width = width / 2; // 분해를계속하기위해영상의가로축크기를반으로줄임 height = height / 2; // 분해를계속하기위해영상의세로축크기를반으로줄임 50

18 OnWaveletEncode 함수작성 (7) m_tempinput = OnMem2DAlloc double(height, width); for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ m_tempinput[i][j] = m_ll[i][j]; // LL 값을새로운입력으로할당 delete [] m_conv1, m_conv2, m_conv3, m_conv4; delete [] m_down1, m_down2, m_down3, m_down4; delete [] m_hor, m_ver1, m_ver2; for(i=0 ; i<height ; i++){ // 메모리해제 delete[] m_ll[i]; delete[] m_lh[i]; delete[] m_hl[i]; delete[] m_hh[i]; delete[] m_sll[i]; delete[] m_slh[i]; delete[] m_shl[i]; delete[] m_shh[i]; delete[] m_l[i]; delete[] m_h[i]; delete m_l, m_h, m_ll, m_lh, m_hl, m_hh, m_sll, m_slh, m_shl, m_shh; UpdateAllViews(NULL); 51

정렬영상출력 ➊ [Resource View] 창의 [WaveletTransform resources-dialog] 폴더에서마우스오른쪽버튼클릭 [Insert Dialog] 클릭해대화상자하나삽입 ( [OK], [Cancel] 버튼은삭제 ) [Dialog Properties] 대화상자에서캡션 Arrange Image 로설정 52

➋ 대화상자를클래스에추가 ➌ [MFC ClassWizard] 대화상자의 [Message Maps] 탭에서 Messages 항목의 WM_INITDIALOG 를클릭하여 OnInitDialog 함수추가. 대화상자를초기화하는역할을함. 53

➍ Messages 항목의 WM_PAINT 지를클릭하여 OnPain 함수추가. 이곳은대화상자에그림을그리는역할수행 54

➎ CWaveletTransformDoc 에서 CArrangeDlg 클래스에출력할영상과크기를저장하는변수선언 55

➏ 생성된함수에다음프로그램추가 1 OnInitDialog 함수추가하기 BOOL CArrangeDlg::OnInitDialog() { CDialog::OnInitDialog(); CRect rect, rectc; GetWindowRect(&rect); GetClientRect(&rectC); int cx, cy; CSize sizeimg; sizeimg.cx = Width; sizeimg.cy = Height; cx = sizeimg.cx + rect.width() - rectc.width() + 4; // 정렬영상출력을위한대화상자크기조절 cy = sizeimg.cy + rect.height() - rectc.height() + 4; SetWindowPos(this, 0, 0, cx, cy, SWP_NOZORDER); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE 56

2 OnPaint 함수추가하기 void CArrangeDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CDialog::OnPaint() for painting messages int i, j; unsigned char R, G, B; for(i=0 ; i<height ; i++){ for(j=0 ; j<width ; j++){ R = m_tempimage[i][j]; G = B = R; dc.setpixel(j, i, RGB(R, G, B)); // 정규화된정렬영상을화면에출력 57

➐ 정렬된영상은 Wavelet Transform(IDD_DIALOG1) 대화상자에서 [Arrange Image] 버튼을클릭하면영상이출력되게함. [MFC ClassWizard] 대화상자에서 [Arrange Image] 버튼에함수추가 58

➑ ArrangeDlg 를사용하기위해 CWaveletTransformDlg.cpp 파일위쪽에 ArrangeDlg.h 선언 #include "stdafx.h" #include "WaveletTransform.h" #include "WaveletTransformDlg.h" #include "WaveletTransformDoc.h" #include "ArrangeDlg.h" 59

➒ OnButtonArrange 함수추가 void CWaveletTransformDlg::OnButtonArrange() { // 버튼을누르면정렬영상출력 CArrangeDlg dlg; dlg.width = m_pdoc->m_width; dlg.height = m_pdoc->m_height; dlg.m_tempimage = m_pdoc->m_arrangeimage; UpdateData(TRUE); dlg.domodal(); // 정렬영상을위한대화상자출력 60

➓ Wavelet Transform(IDD_DIALOG1) 대화상자의 [ 종료 ] 버튼에변환을종료하는프로그램추가 61

11 OnButtonEnd 함수추가 void CWaveletTransformDlg::OnButtonEnd() { CDialog::OnOK(); 62

Section 06 역방향웨이브렛변환구현하기 ➊ 역방향웨이브렛변환은순방향변환이일어난뒤변환된값을사용하여역방향변환을하게됨. 따라서순방향에서사용되었던함수와대화상자가재사용됨. ➋ CWaveletTransformDlg::OnButtonArrange 함수에다음프로그램추가 void CWaveletTransformDlg::OnButtonUpdate() { // TODO: Add your control notification handler code here UpdateData(TRUE); m_pdoc->m_level = m_level; m_pdoc->onwaveletencode(); m_pdoc->onwaveletdecode(); // 웨이브렛역변환 m_pdoc->onsnr(); // 신호대잡음비 UpdateData(FALSE); 63

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) ➌ 순방향웨이브렛변환처럼 CWaveletTransformDoc 클래스에 OnWaveletDecode 함수를추가하여역방향웨이브렛변환을수행할수있도록한. 역방향웨이브렛변환하는데필요한함수는 CWaveletTransformDoc 클래스에추가 64

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) 1 OnUpSampling 함수추가하기 double* CWaveletTransformDoc::OnUpSampling(double *m_target, int size) { // 업샘플링을위한함수 int i; double* m_temp; m_temp = new double[size * 2]; for(i=0 ; i<size*2 ; i++) m_temp[i] = 0.0; // 초기화 for(i=0 ; i<size ; i++) m_temp[2*i] = m_target[i]; // 업샘플링처리 return m_temp; 65

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) 2 OnSNR 함수추가하기 void CWaveletTransformDoc::OnSNR() { // 신호대잡음비를위한함수 double OrgSum, ErrSum, MeanErr, MeanOrg; int i; OrgSum = 0.0; ErrSum = 0.0; // calculate mean squared error for(i=0 ; i<m_size ; i++){ // 오류의에너지계산 ErrSum += ((double) m_inputimage[i] - m_recon[i]) * ((double) m_inputimage[i] - m_recon[i]); MeanErr = ErrSum / m_size; // 오류에너지평균 for(i=0 ; i<m_size ; i++){ // 신호의에너지계산 OrgSum += ((double) m_inputimage[i]) * ((double) m_inputimage[i]); MeanOrg = OrgSum / m_size; // 신호에너지평균 pdlg->m_error = (float)meanerr; // 오류출력 pdlg->m_snr = (float)(10 * (double)log10(meanorg / MeanErr)); // 신호대잡음비계산 66

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) ➍ OnWaveletDecode 함수작성 (1) void CWaveletTransformDoc::OnWaveletDecode() { int i, j, k; int width, height; double *templl, *templh, *temphl, *temphh, *templ, *temph; double **L, **H; double *Up1, *Up2, *Up3, *Up4; double *Conv1, *Conv2, *Conv3, *Conv4; double **R; width= m_width / (int)(pow(2, m_level)); height= m_height / (int)(pow(2, m_level)); m_recon = new double [m_width * m_height]; for(k=m_level ; k>0 ; k--){ if(width > m_width height >m_height){ // 분해종료 return; templl = new double [height]; templh = new double [height]; temphl = new double [height]; temphh = new double [height]; 67

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) ➍ OnWaveletDecode 함수작성 (2) L = OnMem2DAlloc H = OnMem2DAlloc templ = new double [width]; temph = new double [width]; double(height*2, width); double(height*2, width); R = OnMem2DAlloc double(height*2, width*2); for(i=0 ; i<width ; i++){ for(j=0 ; j<height ; j++){ // 정렬영상에서처리하려는열을분리 templl[j] = m_tempoutput[j][i]; templh[j] = m_tempoutput[j + height][i]; temphl[j] = m_tempoutput[j][i + width]; temphh[j] = m_tempoutput[j + height][i + width]; Up1 = OnUpSampling(tempLL, height); // 업샘플링 Up2 = OnUpSampling(tempLH, height); Up3 = OnUpSampling(tempHL, height); Up4 = OnUpSampling(tempHH, height); Conv1 = OnConvolution(Up1, m_filterg0, height*2, 2); // 컨벌루션연산 Conv2 = OnConvolution(Up2, m_filterg1, height*2, 2); Conv3 = OnConvolution(Up3, m_filterg0, height*2, 2); Conv4 = OnConvolution(Up4, m_filterg1, height*2, 2); 68

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) ➍ OnWaveletDecode 함수작성 (3) for(j=0 ; j<height*2 ; j++){ L[j][i] = Conv1[j] + Conv2[j]; H[j][i] = Conv3[j] + Conv4[j]; for(i=0 ; i<height*2 ; i++){ for(j=0 ; j<width ; j++){ templ[j] = L[i][j]; // 횡데이터분리 temph[j] = H[i][j]; Up1 = OnUpSampling(tempL, width); // 업샘플링 Up2 = OnUpSampling(tempH, width); Conv1 = OnConvolution(Up1, m_filterg0, width*2, 2); // 컨벌루션연산 Conv2 = OnConvolution(Up2, m_filterg1, width*2, 2); for(j=0 ; j<width*2 ; j++){ R[i][j] = Conv1[j] + Conv2[j]; for(i=0 ; i<height*2 ; i++){ for(j=0 ; j<width*2 ; j++){ m_tempoutput[i][j] = R[i][j]; // 복원데이터를다시정렬 69

Section 06 역방향웨이브렛변환구현하기 ( 계속 ) ➍ OnWaveletDecode 함수작성 (4) height = height * 2; // 영상의크기를두배확장 width = width * 2; for(i=0 ; i< m_height ; i++){ for(j=0 ; j< m_width ; j++){ m_recon[i* m_width + j] = R[i][j]; m_outputimage[i* m_width + j] = (unsigned char)r[i][j]; // 최종복원된결과를출력 UpdateAllViews(NULL); delete [] templl, templh, temphl, temphh, templ, temph; // 메모리해제 delete [] Up1, Up2, Up3, Up4; delete [] Conv1, Conv2, Conv3, Conv4; for(i=0 ; i< m_height ; i++){ // 메모리해제 delete[] L[i]; delete[] H[i]; delete[] R[i]; delete L, H, R; 70

➎ 결과영상 Section 06 역방향웨이브렛변환구현하기 ( 계속 ) 71

Thank you