실습용 TOOL 다운 디지털영상처리 실습도구세팅 방송영상미디어과 1. Visual Studio 2010 실행 à Hel 클릭 à Samles 클릭 2. Visual Studio 2010 Samles 클릭 실습용 TOOL 준비 실습용 TOOL 은 Microsoft 사의 Visual Studio 2010 에서기본으로제공하는비트맵보기프로그램 (DIBLOOK) 을기초로함 실습용비트맵첨부 : 확장자 bm 파일 실습용 TOOL 다운 3. Visual Studio 2010 코드샘플중에서 [Visual C++] 클릭 4. Visual C++ Saml 에서아랫쪽으로이동 à MFC 클릭 1
실습용 TOOL 다운 5. MFC 페이지는다음과같으며중간쯤으로이동하면 [MFC Samles General] 항이나오며이중에서 DIBLook 을선택하면다운가능 Folder 에확장자가안보일때 Exlorer 에서 [ 구성 ] 클릭 [ 폴더및검색옵션 ] 클릭 폴더옵션에서 : [ 알려진파일형식의파일확장명숨기기 ] 에 표시없앰 (1) (2) (3) 실습용 TOOL 다운 폴더내에있어야할프로그램리스트 시작프로그램 à 구동시반드시더블클릭해야함 Microsoft Visual Studio comile 기초 Microsoft사의 Visual Studio 2010이설치되어있는지확인 설치되어있는경우앞장의리스트중에서 [diblook.sln] 파일을더블클릭하여실행 n *.sln 파일은 Visual C의작업파일 VS2010 은 4개영역으로나뉘어져있는지확인 1 Project 내용을볼수있는영역 2 각파일내용을볼수있는영역 3 outut, result 등상태내용을볼수있는영역 4 Proerty ( 속성 ) 을볼수있는영역 (1) (2) (4) (3) 2
Microsoft Visual Studio comile 기초 영역 : 다음 4 부분으로이루어짐 n Solution Exlorer : Project 를이루고있는파일들을펼쳐볼수있는윈도우 n Class View : Project 를이루고있는 Class 들을펼쳐볼수있는윈도우 n Proerty Manager : Project 를컴파일하여얻게될속성들을펼쳐볼수있는윈도우 n Team Exlorer : Team Project 진행에대한정보 Microsoft Visual Studio comile 기초 4 부분중보이지않는부분이생기면다음과같이추가 n [view] 메뉴를선택 n 메뉴항목이나타나면원하는윈도우를선택하면됨 Microsoft Visual Studio comile 기초 Microsoft Visual Studio comile 기초 (1) Solution Exlorer (2) Class View (3) Proerty Manager (4) Team Exlorer 컴파일 (comile) 이란? n C 언어로된프로그램은 High Level 언어이므로컴퓨터가인식못함 n comile 이라는번역단계를거쳐인간의언어와유사한 C 언어를기계어로번역해주어야함 컴파일하기 Ø[Build]-[Build Solution / 솔루션빌드 ] Ø[Build]-[Comile/ 컴파일 ] 1 succeeded 0 failed 성공했음에러없음 3
Microsoft Visual Studio comile 기초 실행해보기 컴파일된이후 à [Debug/ 디버그 ]-[Start Without Debugging/ 디버깅하지않고시작 ] [File]-[Oen] 파일열기대화창 à 우측하단에서모든파일 (*.*) 선택 à 비트맵파일이실제 *.dib 보다는 *.bm 가일반적이기때문 새메뉴생성 IDR_DIBTYPE 클릭하면오른쪽 Proerties 에속성나타남 속성중 [Language ( 언어 )]-[ 영어 ( 미국 )] 클릭 à 펼쳐지면아래로내려서 [ 한국어 ( 대한민국 )] 선택 n 왼쪽윈도우에서 IDR_DIBTYPE 이변한다 à 한국어가당연한결과이므로아무것도안보임 ( 좀전에열었던실행파일반드시닫은후 ) IDR_DIBTYPE 를더블클릭 à 가운데코드보는부분에메뉴가나타나는데이것은앞에서컴파일한후실행한프로그램과비교하면동일 n 오른쪽끝에 [Tye Here/ 여기에입력 ] 부분에한글로 내메뉴 라입력 [Build Solution/ 솔루션빌드 ]-[Start Without Debugging/ 디버깅하지않고시작 ] 실행 새메뉴생성 새메뉴생성 : Resource View 에서 좌측윈도우하단에여러개탭중에 [ResourceView/ 리소스뷰 ] 탭선택. w 클릭 (DibLook 의앞에더볼수있다는뜻 ) 하면 resource file 인 diblook.rc 가열린다. n Resource 란 : 그프로그램이가지고있는그림, 글자, 모양등을통틀어말함 n diblook.rc 를확장하면 Accelerator, Bitma, Dialog, Icon, Menu, String Table 등이보인다 [Menu] 클릭 n Menu 확장 : IDR_DIBTYPE[ 영어 ( 미국 )], DIR_MAINFRAME[ 영어 ( 미국 )] n 이메뉴는영어만사용할수있도록되어있으므로바꿔야함 (2) Menu : IDR_DIBTYPE (3) Proerties : Language 선택 (1) Resource View 4
새메뉴생성 : Resource 메뉴에서 메뉴의기능 (1) IDR_DIBTYPE 더블클릭 (2) Tye Here 클릭 ( 파란바탕에흰영역 ) (3) 내메뉴 한글로입력 (4) Build Solution/ 솔루션빌드 (5) Start Without Debugging / 디버깅하지않고시작 그래픽사용자인터페이스즉 GUI 형식을통해명령을수행하기위한하나의방법 우리가원하는기능을수행하도록명령을선택하기전에어떤기능이있는지볼수있는항목 Category 별로메뉴바에생성하고그메뉴를선택하면그범위에해당하는명령들이하단에펼쳐짐 n 예를들어 파일 이라는항목을선택하면파일에대한각종기능들이펼쳐지는데 new, oen, save 등이파일관련명령을수행함 새메뉴실행 메뉴의기능 Hel 우측에 [ 내메뉴 ] 가나타남메뉴추가 : diblook.sln 실행 à Resource View에서 Menu 선택 à IDR_DIBTYPE 선택하여한글화 ( 매우중요함 ) à IDR_DIBTYPE 더블클릭 à 빈공간에 내메뉴 추가 à build 후실행강의에서언급하는윈도우가보이지않을때 [View/ 보기 ] 에가서해당항목을클릭하면보이게됨 [ 내메뉴 ] 는클릭해도아무런반응이없음 : 기능을연결하지않았기때문 메뉴에명령을수행하는항목추가 (1) [ 내메뉴 ] 하단의 [Tye Here/ 여기에입력 ] 클릭 (2) 흰색공간에원하는명령어입력 à 테스트 라입력하고 enter (3) 테스트 한번만클릭 (4) Proerties 에메뉴항속성나타남 : ID 를보면 ID_XXXX 처럼숫자로나타남 (5) ID_XXXX 를클릭한후 ID_TEST 로변경 ( 반드시영어대문자 ) 5
메뉴의기능 [Build Solution/ 솔루션빌드 ]-[Start Without Debugging/ 디버깅하지않고시작 ] 실행 n [Build Solution/ 솔루션빌드 ] 후실행할때다음과같은대화창나타날때 yes 선택 : Udate 를할것인가를묻는것임 메뉴에명령기능연결하기 명령을수행해야하므로 Message tye: 에반드시 COMMAND 를선택 우측 Class list: 에서 CDibView 선택해야함 : n 가장쉬운방법은 View class에서명령을구현하는것이므로편의상 하단의 Add and Edit/ 추가및편집 버튼선택 à 명령프로그램을구현한장소로안내됨 (1) (2) 내메뉴에 테스트 라는명령을수행할수있는항목이생성됨 테스트 항이회색으로되어있음 : 명령과연결되지못하고있다는뜻 (3) 메뉴에명령기능연결하기 메뉴에명령기능연결하기 앞에서한작업은메뉴에명령항목만마련한것임 명령기능을연결해주어야명령을수행할수있음메뉴항목중에서 테스트 에가서마우스 오른쪽버튼 클릭 [Add Event Handler/ 이벤트처리기추가 ] 선택 (2) CDibView 클릭 테스트 에가서마우스오른쪽버튼클릭 Add Event Handler.. 선택 (3) OnTest() 더블클릭해도나타남 à 향후코드를편집할때더블클릭으로찾아가면편리함 (1) Class View 탭선택 6
메뉴에명령기능연결하기 MessageBox 대화창출력해보기 n CDibView::OnTest() 에코드입력 MessageBox( 나는테스트명령수행중!!,0,0); n build 하고 start 함 for 文과친해지기 오른쪽영상의크기는 24x18 이영상의모든픽셀을지나가기위한방법은 : i방향으로 (0,0) 맨윗줄부터한줄씩진행 한줄을지나가면다음한줄아래로감 즉 j=0에서 j=1로진행함 이렇게 i 방향으로증가를거듭하면 j 방향으로한줄씩증 j 가함 i cydib for(i=0; i<24; i++){ (i, j) cxdib (23,17) 메뉴에연결된기능실행 점처리를위한사전실습 1. 그림파일을열기 2. 내메뉴 클릭 3. 테스트 클릭 4. 그림과같이대화창나타남 절대!! 대 소문자를구별해야한다. 예컨데 CDib 라고입력해야하는데 Cdib 라고하면반드시에러발생. undeclared identifier: 선언되어있지않은변수거나선언된것과대소문자구별이맞지않은경우나타난다. 반드시 error 만고쳐준다. Warning 은단순히경고이므로신경쓰지않아도된다. (error 부분을더블클릭하면에러가발생한곳으로안내 ) 7
프로그램문제발생유형및해결책 Diblook.sln 을 USB 메모리에서시작할경우 n USB 메모리는용량이한정적이어서빈공간부족 n 해결책 : 반드시용량이충분한 HDD 에 DIBLOOK 전체폴더위치해야함 Diblook.zi 을풀지않고실행한경우 반드시압축을풀고해야함 압축풀때반드시독립폴더에서해야함 ( 바탕화면절대불가 ) 프로그램문제발생유형및해결책 Build 가되지않는경우 -3 : Link error 발생시 n link 가되지않는다는문장과함께에러발생시 n Visual Studio 를종료하고 diblook 하위 Debug 폴더를삭제하고다시시작 n 그래도안되면이전에저장해놓은압축프로그램풀어서처음부터진행 프로그램문제발생유형및해결책 Build 가되지않는경우 -1 n failed 상황이발생할경우스크롤바를위로올려서 error 위치를확인함 n error 발생시 : 반드시 error xxx 라는문장이존재함 n could not oen ****.** 라고파일오픈에러인경우그파일이없어진경우 à 폴더전체를삭제하고이전압축파일을풀어서복구함 Build 가되지않는경우 -2 n error cxxx : xxxxx : identifier not found 인경우대부분잘못타이핑한경우 n 해결책 : error 발생문장을더블클릭 à error 발생한곳으로안내됨 à 그곳에서 xxxxx 로표시된부분이잘못타이핑되었나살펴봄 프로그램관리방법 최초에배포한자동압축풀기프로그램따로보관 매번실습한후그날날짜를덧붙여서 Backu File 관리 : ( 예 ) Diblook_IMG_20140423.zi Error 상황을극복못할경우직전파일열어서다시시작하는방법이가장바람직함 반드시 HDD 에풀어서작업함 à 실습후압축하여날짜덧붙인후 USB 에보관 ( 이동시 ) 또는집에서작업할때는 Backu 폴더를운영해야함 반드시기억할사항 : 프로그램은영문자로해야하며대. 소문자를철저히구분해주며한번사용한변수는그구역내에서는동일하게써줘야에러가안남 8
윈도우핸들가져오기 윈도우시스템에서는멀티윈도우시스템사용 처리할작은윈도우 ( 영상이담긴윈도우 ) 를선택한후영상처리작업을해야한다윈도우가선택된후처리작업을시작하면그윈도우를제어할수있는 Handle 필요 윈도우핸들과영상핸들구하기 (3) 핸들구하기 에서마우스오른쪽버튼클릭 à Add Event Handler 선택 CDibDoc* Doc = GetDocument(); Handle 가져오기명령어 핸들의 Tye 받아온핸들을지니고있게될변수명 ( 그함수가끝날때까지사용함 ) 윈도우의핸들이얻어지면영상메모리의핸들 ( 그윈도우에들어있는영상의핸들 ) 을가져온다 영상 DIB라함 (Device Indeendent Bitma : 비트맵의개선된형식 ). HDIB는 Huge Memory를갖는 DIB라는뜻으로매우큰메모리사이즈를갖는비트맵이라는뜻 HDIB hdib = Doc->GetHDIB(); 영상의 Handle 가져오기명령어 ( 실제로는영상메모리의첫번째주소를가져온다 ) 핸들의 Tye 영상핸들을지니고있게될변수명 ( 그함수가끝날때까지사용함 ) (3) 선택 (4) 클릭 (1) 오른마우스클릭 (2) 선택 Message tye - COMMAND Class list - CDibView 클릭 à Add and Edit 클릭 윈도우핸들과영상핸들구하기 윈도우핸들과영상핸들구하기 (1) [Resource View]-[Menu] 항 -[IDR_DIBTYPE] 선택 à 중앙의 diblook.rc 에서 내메뉴 를선택한후 à 빈공간에 핸들구하기 새로만듬 (2) Proerties 에서 ID 항에서 ID_HANDLE 로수정 Add Event Handler 를선택 CDibView::OnHandle() 클래스가빈상태로만들어짐 빈공간에프로그램삽입 (1) 영상데이터가존재하는곳의윈도우의 Handle 받아옴 (1) (2) (2) 윈도우 Handle 이용하여영상메모리의 Handle 받아옴 (3) 영상이비었으면실패메세지 (4) 영상이있으면성공메세지 9
윈도우핸들과영상핸들구하기실행 실행결과 n 영상이없는윈도우를선택한후 내메뉴 à 핸들구하기 를하면실패메시지나타남 n 영상을읽은후윈도우를선택한후 내메뉴 à 핸들구하기 를하면성공메시지나타남 원하는위치의픽셀값변경하기 : 점 (160, 200) 과 (161, 200) 의위치에해당하는두픽셀값을 0 으로변경 ( 나란히붙어있는픽셀 ) void CDibView::OnPutixel() { CDibDoc* Doc = GetDocument(); HDIB hdib = Doc->GetHDIB(); if (hdib == NULL){ MessageBox( 핸들얻기실패!!, NULL, MB_OK); return; LPSTR ldibhdr = (LPSTR) ::GlobalLock((HGLOBAL) hdib); int cxdib = (DWORD) ::DIBWidth(lDIBHdr); int cydib = (DWORD) ::DIBHeight(lDIBHdr); int rwidth = ((int)cxdib + 3)/4*4; LPSTR ldibbits = ::FindDIBBits(lDIBHdr); int i=160; int j=200; *(ldibbits + i + j*rwidth) = 0; i=161; j=200; *(ldibbits + i + j*rwidth) = 0; (1) 영상의첫번째주소얻어오기 (2) i 선언한후 160 입력 j 선언한후 200 입력 (3) (160, 200) 위치의픽셀값 0 으로변경 (4) i 161 입력, j 200 입력 ( 위에서정수형으로선언했으므로다시선언안함 ) (5) (161, 200) 위치의픽셀값을 0 으로변경 (6) 바뀐메모리를화면에업데이트함 Invalidate(TRUE); 바뀌거나첨가된부분 영상정보구하기 앞에서얻어낸영상핸들을이용하여영상의정보를구해낸다 영상의가로, 세로크기를얻는다 (cxdib, cydib) 메모리 alignment를통해메모리넓이 rwidth 계산 CDibDoc* Doc = GetDocument(); HDIB hdib = Doc->GetHDIB(); if (hdib == NULL) return; ldibhdr = (LPSTR) ::GlobalLock((HGLOBAL) hdib); int cxdib = (DWORD) ::DIBWidth(lDIBHdr); int cydib = (DWORD) ::DIBHeight(lDIBHdr); int rwidth = ((int)cxdib + 3)/4*4; (1) 윈도우의핸들얻어오기 (2) 영상의핸들얻어오기 ( 헤더와영상이모두들어있음 ) (3) 핸들이비어있으면실패!! (4) (5) (6) (7) < 헤더 > 영상의정보가들어있음 - 영상데이터의크기 - 영상가로, 세로등 - 영상의컬러정보등 원하는위치의픽셀값변경하기 : 점 (1) Resource View 선택 (2) [Menu]-[IDR_DIBTYPE] 더블클릭 ldibbits = ::FindDIBBits(lDIBHdr); (8) (3) [ 내메뉴 ]-[Tye Here ] 클릭 à 픽셀변경 _ 점 타이핑 (4) 헤더 + 영상데이터의첫번째주소를얻어온다 à ldibhdr (5) 헤더로부터영상의가로크기를얻어온다 à cxdib (6) 헤더로부터영상의세로크기를얻어온다 à cydib (7) 영상의가로크기로부터메모리의가로크기를계산한다 à Memory Alignment (8) 헤더정보를잘라내고순수영상데이터만얻어온다 à ldibbits ( 향후실험에사용할영상데이터 ) (4) [Proerties]-[ID] 의 [ID_xxxx] 클릭 à ID_PUTPIXEL 타이핑 10
원하는위치의픽셀값변경하기 : 점 원하는위치의픽셀값변경하기실행 (5) 픽셀변경 _ 점 오른마우스클릭 (6) [Add Event Handler] (7) [COMMAND]-[CDibView] 선택 (8) [Add and Edit] 원하는위치의픽셀값변경하기 : 점 프로그램작성 원하는선의픽셀값변경하기 (150,250) 에서 (250,250) 까지 100 개의픽셀을 0 의값 ( 검정 ) 으로바꾸는프로그램작성 즉 I 를 150 에서 250 까지변화 : for 문사용 à for(i=150; i<250; i++) I 를 150 부터 250 미만에이르기까지 I 를하나씩증가시키면서다음을수행하라하는명령. : : LPSTR ldibbits = ::FindDIBBits(lDIBHdr); j=250; for(i=150; i<250; i++){ *(ldibbits + i + j*rwidth) = 0; Invalidate(TRUE); : : (1) 순수영상의첫번째주소얻어오기 (2) j 는 250 으로고정함 (3) for 문을사용한다 à i=150 에대해 i<250 까지 i 를하나씩증가시키면서다음명령을수행하라 (4) (i, 250) 위치의픽셀값을 0 으로변경 (5) 바뀐메모리를화면에업데이트함 11
원하는선의픽셀값변경하기 void CDibView::OnPutline() { CDibDoc* Doc = GetDocument(); HDIB hdib = Doc->GetHDIB(); if (hdib == NULL){ MessageBox( 핸들얻기실패!!, NULL, MB_OK); return; LPSTR ldibhdr = (LPSTR) ::GlobalLock((HGLOBAL) hdib); int cxdib = (DWORD) ::DIBWidth(lDIBHdr); int cydib = (DWORD) ::DIBHeight(lDIBHdr); int rwidth = ((int)cxdib + 3)/4*4; LPSTR ldibbits = ::FindDIBBits(lDIBHdr); int i, j; j=200; for(i=150; i<250; i++){ *(ldibbits + i + j*rwidth) = 0; Invalidate(TRUE); 변수 i, j 선언 바뀌거나첨가된부분 사각영역의픽셀값변경하기 (150,150) 에서 (250,250) 에이르는사각형을원하는밝기로변경. 가로 150~250까지의범위, 세로 150~250까지의범위. (i가0 150~250까지, j 150~250까지변함 ) 사각형범위를다루기위해서는 for문을이중으로사용 for(j=150; j<250; j++){ for(i=150; i<250; i++){ *(ldibbits + i + j*rwidth) = 0; Invalidate(TRUE); - j가하나증가하는동안다음 for문을모두수행함 - for문 i 가 150에서 250까지모두진행되어야상위레벨인 j에대한 for문중 j 하나증가. - 두 for문이다수행되면 100ⅹ100 즉 10000개의일을함. (1) 이중 for 문사용 à j=150 에대해 j <250 까지 j 를하나씩증가시키면서, 동시에 i=150 에대해 i<250 까지 I 를하나씩증가시키면서다음명령수행 (2) (i, j) 위치의픽셀값을 0 으로변경 (3) 바뀐메모리를화면에업데이트함 원하는선의픽셀값변경하기실행 사각영역의픽셀값변경하기 void CDibView::OnPutBox() { CDibDoc* Doc = GetDocument(); HDIB hdib = Doc->GetHDIB(); if (hdib == NULL){ MessageBox( 핸들얻기실패!!, NULL, MB_OK); return; LPSTR ldibhdr = (LPSTR) ::GlobalLock((HGLOBAL) hdib); int cxdib = (DWORD) ::DIBWidth(lDIBHdr); int cydib = (DWORD) ::DIBHeight(lDIBHdr); int rwidth = ((int)cxdib + 3)/4*4; LPSTR ldibbits = ::FindDIBBits(lDIBHdr); int i, j; 변수 i, j 선언 for(j=150; j<250; j++){ for(i=150; i<250; i++){ *(ldibbits + i + j*rwidth) = 0; Invalidate(TRUE); (150, 150) ~ (250, 250) 에이르는 100ⅹ100 의사각형평면의픽셀을모두 0( 검은색 ) 으로변경한영상 2 중 for 문구조 (2 차원평면을다룰때반드시사용함 ) 12
사각영역의픽셀값변경하기 산술연산 밝기변환 : Brightness 원하는영역 ( 사각형 ) 에밝기변화 n (100,100)~(300,300) 사각형영역의명도 70증가사각형영역에대한변환은 for 문두개를사용하여수행픽셀값 : *(ldibbits + i + j*rwidth) 앞으로모든영상처리는이렇게사각영역이주로사용되므로잘익혀두시기바랍니다 for(j=100; j<300; j++){ for(i=100; i<300; i++){ int TMP; TMP = ((int)*(ldibbits + i + j*rwidth)) & 0x00ff; TMP = TMP + 70; if(tmp >= 255) TMP = 255; if(tmp <= 0) TMP = 0; *(ldibbits + i + j*rwidth) = (BYTE)(TMP & 0x00ff); Invalidate(TRUE); (1) (100,100) ~ (300,300) 사각형영역처리하는 for 문작성 (2) 정수변수선언 (3) Byte 형태의픽셀값을 int 형태의정수값으로변환 (4) 명도값에 70 을더함 (5) 픽셀값은 (-) 가될수없고 255 를넘을수없음 (6) 픽셀값을정수에서 Byte 형으로변환하여픽셀메모리에입력함 (7) 바뀐메모리를영상에 Udate 시킴 사각영역의픽셀값변경하기실행 밝기변환실습 1 Resource View 탭선택 à Menu 중 IDR_DIBTYPE 더블클릭 à 새로운메뉴선택 à 점처리 입력 (1) (2) (3) 2 점처리 메뉴하위메뉴선택 à 밝기조절 메뉴만들기 à Proerties 중에서 ID 를 ID_BRIGHT 로바꾸기 (4) (5) 13
밝기변환실습 밝기변환실습 3 밝기조절 메뉴를우클 à Add Event Handler 선택 à Event Handler Wizard 에서 COMMAND 와 CDibView 를선택 à Add and Edit 클릭 (1) 점처리 를선택한후 밝기조절 선택 (6) (8) 4 5 (7) dibview.c 로자동으로안내됨 à 만약자동안내가되지않으면문제가발생했을가능성이높지만수동으로 Solution Exlorer 를선택하고 Source Files 에서 dibview.c 를선택하여더블클릭하면소스코드를볼수있음 void CDibView::OnBright() 에서원하는프로그램생성 (9) (2) 밝기조절 된결과 : (100,100)~(300,300) 사각영역의밝기를 70 만큼올림 밝기변환실습 밝기변환실습 밝기를 70만큼줄이는실습앞서했던 70 증가시키는것과동일프로그램에서 +70을 -70으로바꾸면된다 기존다른클래스의첫부분과동일함 밝기조절 기능의프로그래밍 : (100,100)~(300, 300) 사각영역의밝기를 70 만큼올림 for(j=100; j<300; j++){ for(i=100; i<300; i++){ int TMP; TMP = ((int)*(ldibbits + i + j*rwidth)) & 0x00ff; TMP = TMP - 70; if(tmp >= 255) TMP = 255; if(tmp <= 0) TMP = 0; *(ldibbits + i + j*rwidth) = (BYTE)(TMP & 0x00ff); Invalidate(TRUE); +70 을 -70 으로교체함 14
밝기변환실습 (1) 점처리 를선택한후 밝기조절 선택 (2) 밝기조절 된결과 : (100,100)~(300,300) 사각영역의밝기를 70 만큼어두워짐 15