Download presentation
Presentation is loading. Please wait.
1
제 7 장 동영상 처리
2
학습목표 AVI 파일에 대해 설명할 수 있다 VFW 라이브러리를 활용할 수 있다
동영상과 PC 카메라 영상에 대한 영상처리 프로그램을 작성할 수 있다 영상처리
3
AVI 파일 디스플레이 AVI(Audio Video Interface) 스트림(stream) 이라는 단위로 구성 AVI파일은
오디오 스트림, 비디오 스트림, MIDI 스트림, 텍스트 스트림 AVI파일은 하나 이상의 스트림을 포함해야 함 동일한 스트림을 여러 개 포함할 수도 있음 비디오 스트림 대부분 압축되어 있음 Cinepak, Indeo 등 여러 가지 형식 영상처리
4
AVI 파일 디스플레이 VFW(Video For Windows) 비디오 처리를 위한 라이브러리
AVI 파일을 읽어서 각 frame을 추출할 수 있는 함수 제공 영상처리
5
AVI 파일 디스플레이 LPBITMAPINFOHEADER pbmih; PAVIFILE pavi; PAVISTREAM pstm;
PGETFRAME pfrm; AVIFILEINFO fi; AVISTREAMINFO si; int stm; int frame; int x, y; unsigned char *image; AVIFileInit(); AVIFileOpen(&pavi, AVIFileName, OF_READ | OF_SHARE_DENY_NONE,NULL); AVIFileInfo(pavi,&fi,sizeof(AVIFILEINFO)); 영상처리
6
AVI 파일 디스플레이 AVIStreamGetFrameClose(pfrm);
for (stm = 0;stm < fi.dwStreams; stm++) { AVIFileGetStream(pavi, &pstm, 0, stm); AVIStreamInfo(pstm, &si, sizeof(si)); if (si.fccType == streamtypeVIDEO) { pfrm = AVIStreamGetFrameOpen(pstm,NULL); for (frame = 0; frame < si.dwLength; frame++) { pbmih = (LPBITMAPINFOHEADER) AVIStreamGetFrame(pfrm,frame); if (!pbmih) contunue; image = (unsigned char *) ((LPSTR)pbmih + (WORD)pbmih->biSize); // 프레임의 비트맵 데이터 사용 (일차원 배열 형태로 저장비트맵 // 데이터를 image가 가리킴) } AVIStreamGetFrameClose(pfrm); AVIStreamRelease(pstm); AVIFileRelease(pavi); AVIFileExit(); 영상처리
7
실습
8
AVI 파일 출력 프로그램 메뉴막대에 동영상 처리 메뉴 추가 [동영상 처리] 메뉴에 부메뉴 추가 이름 : 동영상 처리
ID : ID_AVI_VIEW 영상처리
9
AVI 파일 출력 프로그램 CImageProView 클래스에 OnAviView() 함수를 추가
void CImageProView::OnAviView() { CFile file; CFileDialog dlg(TRUE); if(dlg.DoModal()==IDOK) { strcpy(AVIFileName, dlg.GetPathName()); viewMode = AVI_FILE; } Invalidate(FALSE); 영상처리
10
AVI 파일 출력 프로그램 ImageProView.cpp 파일의 앞부분에 AVI_FILE 상수에 대한 정의를 추가
// 추가한 후 #define TWO_IMAGES #define THREE_IMAGES #define TWO_IMAGES_SCALED 4 #define MORPHING #define AVI_FILE 영상처리
11
AVI 파일 출력 프로그램 CImageProView 클래스에 AVIFileName 변수를 추가
class CImageProView : public CScrollView { protected: // create from serialization only CImageProView(); DECLARE_DYNCREATE(CImageProView) // Attributes public: CImageProDoc* GetDocument(); int viewMode; char AVIFileName[256]; // 추가된 부분 ... } 영상처리
12
AVI 파일 출력 프로그램 OnDraw() 함수를 수정 void CImageProView::OnDraw(CDC* pDC) {
CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (viewMode == AVI_FILE) { loadAVIFile(pDC); return; } if (pDoc->inputImg == NULL) return; ... 영상처리
13
AVI 파일 출력 프로그램 loadAVIFile() 함수를 CImageProView 클래스에 추가한다. 반환 형식 : void
매개변수 형식 : CDC * 매개변수 이름 : pDC 영상처리
14
AVI 파일 출력 프로그램 loadAVIFile() 함수 편집
void CImageProView::loadAVIFile(CDC * pDC) { LPBITMAPINFOHEADER pbmih; PAVIFILE pavi; PAVISTREAM pstm; PGETFRAME pfrm; AVIFILEINFO fi; AVISTREAMINFO si; int stm; int frame; int x, y; unsigned char *image; 영상처리
15
AVI 파일 출력 프로그램 AVIFileInit();
AVIFileOpen(&pavi, AVIFileName, OF_READ | OF_SHARE_DENY_NONE, NULL); AVIFileInfo(pavi,&fi,sizeof(AVIFILEINFO)); for (stm=0;stm < fi.dwStreams;stm++) { AVIFileGetStream(pavi,&pstm,0,stm); AVIStreamInfo(pstm, &si, sizeof(si)); if (si.fccType == streamtypeVIDEO) { pfrm = AVIStreamGetFrameOpen(pstm,NULL); for (frame = 0; frame < si.dwLength; frame++) { pbmih = (LPBITMAPINFOHEADER) AVIStreamGetFrame(pfrm,frame); if (!pbmih) contunue; image = (unsigned char *) ((LPSTR)pbmih + (WORD)pbmih->biSize); 영상처리
16
AVI 파일 출력 프로그램 for (y = 0; y < fi.dwHeight; y++)
for (x = 0; x < fi.dwWidth; x++) pDC->SetPixel(x, fi.dwHeight-y-1, RGB(image[(y*fi.dwWidth+x)*3+2], image[(y*fi.dwWidth+x)*3+1], image[(y*fi.dwWidth+x)*3])); } AVIStreamGetFrameClose(pfrm); AVIStreamRelease(pstm); AVIFileRelease(pavi); AVIFileExit(); 영상처리
17
AVI 파일 출력 프로그램 CImageProView.h 파일 앞부분에 VFW 라이브러리에 대한 헤더 파일에 대한 include 문을 추가 // ImageProView.cpp : implementation of the CImageProView class // #include "stdafx.h" #include "ImagePro.h" #include "ImageProDoc.h" #include "ImageProView.h" #include <vfw.h> // 추가된 부분 영상처리
18
AVI 파일 출력 프로그램 VFW 라이브러리를 링크하도록 설정 솔루션 탐색기 뷰를 선택
ImagePro를 선택하고 마우스 오른쪽 버튼을 클릭 팝업메뉴에서 [속성] 메뉴 항목을 선택 영상처리
19
AVI 파일 출력 프로그램 속성 창에서 [구성속성]=>[링커]=>[입력] 항목을 선택
[추가 종속성] 입력 상자를 선택하고 vfw32.lib를 입력 영상처리
20
AVI 파일 출력 프로그램 프로그램을 컴파일하고 실행 [동영상처리] 메뉴에서 [AVI 파일 출력] 항목선택
영상처리
21
비디오 캡쳐 함수 VFW 라이브러리의 비디오 캡쳐 함수 capGetDriverDescription()
capCreateCaptureWindow() capDriverConnect() capPreviewRate() capPreview() capSetVideoFormat() capDriverDisconnect() capSetCallbackOnFrame() 영상처리
22
비디오 캡쳐 함수 capGetDriverDescription() 함수
BOOL capGetDriverDescription(index, name, name_size, version, version_size); 입력 index : 드라이버 번호 (0 – 9) 출력 name : 캡쳐드라이버의 이름 version : 캡쳐드라이버의 버전 영상처리
23
비디오 캡쳐 함수 capCreateCaptureWindow() 함수
HWND capCreateCaptureWindow(name, style, x, y, width, height, hWnd, id); 입력 name : 윈도우의 이름 style : 윈도우의 스타일 (예 : WS_CHILD, WS_VISIBLE) x,y : 캡쳐 윈도우의 좌측 상단의 좌표를 지정 width와 height : 캡쳐 윈도우의 크기 hWnd : 부모 윈도우의 핸들(handle) 값 id : 윈도우의 식별 번호 결과 윈도우가 정상적으로 생성되면 캡쳐 윈도우의 핸들 그렇지 않으면 NULL 값이 반환 영상처리
24
비디오 캡쳐 함수 capDriverConnect() capDriverConnect(hWnd, index);
캡쳐 윈도우를 캡쳐 드라이버에 연결 입력 hWnd : 캡쳐 윈도우의 핸들 index : 캡쳐 드라이버의 번호 출력 TRUE : 캡쳐 장치가 정상적으로 작동하여 연결이 성공 FALSE : 실패 영상처리
25
비디오 캡쳐 함수 capPreviewRate() capPreviewRate(hWnd, rate);
카메라에서 입력된 비디오를 파일에 저장하는 것이 아니라 화면에 보여줌 입력 hWnd : 캡쳐 윈도우의 핸들 값 rate : 밀리초(ms) 단위의 시간 rate 값을 66으로 설정하면 0.066초마다 새로운 비디오 프레임을 캡쳐해서 디스플레이 1초에 15개의 비디오 프레임이 디스플레이 영상처리
26
비디오 캡쳐 함수 capPreview() capPreviewRate(hWnd, flag); 미리 보기 기능을 켜거나 끔 입력
flag : TRUE 또는 FALSE TRUE : 미리 보기 모드를 켬 FALSE : 미리 보기 모드를 끔 영상처리
27
비디오 캡쳐 함수 capSetVideoFormat()
capSetVideoFormat(hWnd, videoFormat, videoFormat_size); 캡쳐된 비디오 데이터 형식을 설정 입력 hWnd : 캡쳐 윈도우의 핸들 값 videoFormat 설정하고자 하는 비디오 데이터 형식 각 프레임에 대한 비트맵 형식을 BITMAPINFO 구조로 기술 영상처리
28
비디오 캡쳐 함수 typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1]; } BITMAPINFO; typedef struct tagBITMAPINFOHEADER { DWORD biSize; // BITMAPINFOHEADER 구조체의 크기 LONG biWidth; // 영상의 가로 크기 LONG biHeight; // 영상의 세로 크기 (양수: 좌측하단, 음수:좌측상단이 원점) WORD biPlanes; // 목표 장치의 플레인 수(1로 설정해야함) WORD biBitCount; // 각 픽셀의 비트수 DWORD biCompression; // 압축 방법(BI_RGB 또는 0: 무압축 비트맵) DWORD biSizeImage; // 비트맵 영상 크기 (바이트단위) LONG biXPelsPerMeter; // 수평 해상도(미터당 픽셀 수) LONG biYPelsPerMeter; // 수직 해상도(미터당 픽셀 수) DWORD biClrUsed; // 사용된 컬러의 수 DWORD biClrImportant; // 비트맵 디스플레이에 사용되는 컬러 수 } BITMAPINFOHEADER; 영상처리
29
비디오 캡쳐 함수 BITMAPINFOHEADER 구조체에서 biSize, biWidth, biHeight, biPlanes, biBitCount 값을 설정하고 나머지 값들은 0으로 설정하면 된다. BITMAPINFO bmi; memset( &bmi.bmiHeader, 0, sizeof(bmi.bmiHeader)); // 전체 값을 0으로 설정 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = 320; bmi.bmiHeader.biHeight = 240; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; 영상처리
30
비디오 캡쳐 함수 capDriverDisconnect() capDriverDisconnect(hWnd);
capDriverConnect() 함수에 의하여 연결한 캡쳐 윈도우와 캡쳐 장치를 분리 영상처리
31
비디오 캡쳐 함수 capSetCallbackOnFrame()
BOOL capSetCallbackOnFrame(hWnd, func); 캡쳐 장치로부터 비디오 프레임이 캡쳐되었을 때에 이를 화면에 보여주기 위해서 호출되는 callback 함수를 설정 입력 hWnd : 캡쳐 윈도우의 핸들 값 func : 호출될 함수 이름 영상처리
32
실습
33
카메라 영상 출력 프로그램 [동영상 처리] 메뉴 아래에 카메라 영상 출력을 위한 부메뉴를 추가 이름 : 카메라 영상 출력
ID : ID_CAMERA_VIEW 영상처리
34
카메라 영상 출력 프로그램 CImageProView 클래스에 OnCameraView() 함수를 추가
void CImageProView::OnCameraView() { char DeviceName[80]; char DeviceVersion[80]; HWND hWndC = 0; HWND parent = m_hWnd; // 현재의 윈도우의 핸들 for( int wIndex = 0; wIndex < 10; wIndex++ ) { if( capGetDriverDescription( wIndex, DeviceName, sizeof (DeviceName), DeviceVersion, sizeof (DeviceVersion))) hWndC = capCreateCaptureWindow ( "My Own Capture Window", WS_CHILD | WS_VISIBLE , 0, 0, 320, 240, parent, 0); 영상처리
35
카메라 영상 출력 프로그램 if( capDriverConnect (hWndC, wIndex)) { BITMAPINFO bmi;
capPreviewRate(hWndC, 66); // rate, in milliseconds capPreview(hWndC, TRUE); // 미리 보기 기능을 켬 memset( &bmi.bmiHeader, 0, sizeof(bmi.bmiHeader)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biWidth = 320; bmi.bmiHeader.biHeight = 240; bmi.bmiHeader.biPlanes = 1; if (capSetVideoFormat( hWndC, &bmi, sizeof(bmi))) { capSetCallbackOnFrame( hWndC, FrameCallbackProc); viewMode = CAMERA; imageProView_obj = this; return; } else capDriverDisconnect( hWndC ); ::DestroyWindow(hWndC); } } } 영상처리
36
카메라 영상 출력 프로그램 ImageProView.cpp 파일의 앞부분에 카메라 영상 출력에 대한 정의를 추가 // 추가한 후
#define TWO_IMAGES #define THREE_IMAGES #define TWO_IMAGES_SCALED 4 #define MORPHING #define AVI_FILE #define CAMERA 영상처리
37
카메라 영상 출력 프로그램 FrameCallbackProc() 함수를 정의
CImageProView * imageProView_obj; void FrameCallbackProc( HWND hWnd, VIDEOHDR* hdr ) { if(hWnd && hdr && hdr->lpData) if( imageProView_obj ) imageProView_obj->OnFrame((unsigned char *) hdr->lpData); } 영상처리
38
카메라 영상 출력 프로그램 CImageProView 클래스에 OnFrame() 함수를 추가 반환 형식: void
매개변수 형식 : unsigned char * 매개변수 이름 : data 영상처리
39
카메라 영상 출력 프로그램 OnFrame() 함수를 다음과 같이 편집
void CImageProView::OnFrame(unsigned char *data) { Invalidate(FALSE); } 영상처리
40
카메라 영상 출력 프로그램 OnDraw() 함수의 첫 부분을 수정
void CImageProView::OnDraw(CDC* pDC) { CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (viewMode == AVI_FILE) { loadAVIFile(pDC); return; } else if (viewMode == CAMERA) { ... 영상처리
41
카메라 영상 출력 프로그램 프로그램을 컴파일하고 수행 [동영상 처리] 메뉴에서 [카메라 영상 출력] 항목을 선택
영상처리
42
동영상에 대한 선명화 연산 [동영상 처리] 메뉴에 선명화 연산에 대한 부메뉴를 추가 이름 : 선명화(카메라)
ID : ID_VIDEO_SHARPENING 영상처리
43
동영상에 대한 선명화 연산 CImageProView 클래스에 OnVideoSharpening() 함수를 추가
void CImageProView::OnVideoSharpening() { operation = SHARPENING; } 영상처리
44
동영상에 대한 선명화 연산 변수 operation을 CImageProView 클래스 정의에 추가
class CImageProView : public CScrollView { protected: // create from serialization only CImageProView(); DECLARE_DYNCREATE(CImageProView) // Attributes public: CImageProDoc* GetDocument(); int viewMode; char AVIFileName[256]; int operation; // 추가된 부분 … } 영상처리
45
동영상에 대한 선명화 연산 CImageProView() 함수에서 변수 operation의 값을 초기화
CImageProView::CImageProView() { operation = NO_OP; } 영상처리
46
동영상에 대한 선명화 연산 변수 operation에 사용할 상수를 CImageProView.cpp 파일 첫 부분에 정의
#define TWO_IMAGES #define THREE_IMAGES #define TWO_IMAGES_SCALED 4 #define MORPHING #define AVI_FILE #define CAMERA #define NO_OP // 추가된 부분 #define SHARPENING // 추가된 부분 영상처리
47
동영상에 대한 선명화 연산 OnFrame() 함수를 다음과 같이 수정
void CImageProView::OnFrame(unsigned char *data) { if (operation == NO_OP) { Invalidate(FALSE); } else if (operation == SHARPENING) CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); int x, y, i; pDoc->imageHeight = 240; pDoc->imageWidth = 320; pDoc->depth = 3; 영상처리
48
동영상에 대한 선명화 연산 // 기억장소 할당 pDoc->inputImg = (unsigned char **) malloc(pDoc->imageHeight * sizeof(unsigned char *)); pDoc->resultImg = (unsigned char **) malloc(pDoc->imageHeight * for (i = 0; i < pDoc->imageHeight; i++) { pDoc->inputImg[i] = (unsigned char *) malloc(pDoc->imageWidth * pDoc->depth); pDoc->resultImg[i] = (unsigned char *) malloc(pDoc->imageWidth * } 영상처리
49
동영상에 대한 선명화 연산 // 입력 영상 복사 for (y = 0; y < pDoc->imageHeight; y++) for (x = 0; x < pDoc->imageWidth * pDoc->depth; x++) pDoc->inputImg[y][x] = data[y*pDoc->imageWidth*3+x]; // 영상 처리 수행 pDoc->RegionSharpening(); // 결과 영상 복사 data[y*pDoc->imageWidth*3+x] = pDoc->resultImg[y][x]; Invalidate(FALSE); } 영상처리
50
동영상에 대한 선명화 연산 [동영상 처리] 메뉴에서 [카메라 영상 출력] 부메뉴를 선택
그 다음에 [선명화(카메라)] 부메뉴를 선택 영상처리
51
동영상에 대한 차영상 출력 [동영상 처리] 메뉴에 차영상 출력을 위한 부메뉴를 추가 이름 : 차영상 출력(카메라)
ID : ID_VIDEO_SUBTRACT 영상처리
52
동영상에 대한 차영상 출력 CImageProView 클래스에 OnVideoSubtract() 함수를 추가
void CImageProView::OnVideoSubtract() { operation = SUBTRACT; } 영상처리
53
동영상에 대한 차영상 출력 CImageProView.cpp 파일 첫 부분에 SUBTRACT 상수를 정의
#define TWO_IMAGES #define THREE_IMAGES #define TWO_IMAGES_SCALED 4 #define MORPHING #define AVI_FILE #define CAMERA #define NO_OP #define SHARPENING #define SUBTRACT 영상처리
54
동영상에 대한 차영상 출력 OnFrame() 함수를 다음과 같이 수정
void CImageProView::OnFrame(unsigned char *data) { if (operation == NO_OP) { Invalidate(FALSE); } else if (operation == SHARPENING) CImageProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); int x, y, i; pDoc->imageHeight = 240; pDoc->imageWidth = 320; pDoc->depth = 3; 영상처리
55
동영상에 대한 차영상 출력 // 기억장소 할당 pDoc->inputImg = (unsigned char **) malloc(pDoc->imageHeight * sizeof(unsigned char *)); pDoc->resultImg = (unsigned char **) malloc(pDoc->imageHeight * for (i = 0; i < pDoc->imageHeight; i++) { pDoc->inputImg[i] = (unsigned char *) malloc(pDoc->imageWidth * pDoc->depth); pDoc->resultImg[i] = (unsigned char *) malloc(pDoc->imageWidth * } 영상처리
56
동영상에 대한 차영상 출력 // 입력 영상 복사 for (y = 0; y < pDoc->imageHeight; y++) for (x = 0; x < pDoc->imageWidth * pDoc->depth; x++) pDoc->inputImg[y][x] = data[y*pDoc->imageWidth*3+x]; // 영상 처리 수행 pDoc->RegionSharpening(); // 결과 영상 복사 data[y*pDoc->imageWidth*3+x] = pDoc->resultImg[y][x]; Invalidate(FALSE); } 영상처리
57
동영상에 대한 차영상 출력 else if (operation == SUBTRACT) {
static unsigned char *image1=NULL; static unsigned char *image2=NULL; int i, length = 320 * 240 * 3; if (image1 == NULL) { image1 = (unsigned char *) malloc(length); for (i = 0; i < length; i++) image1[i] = data[i]; } else if (image2 == NULL) { image2 = (unsigned char *) malloc(length); for (i = 0; i < length; i++) image2[i] = data[i]; else { for (i = 0; i < length; i++) image1[i] = image2[i]; 영상처리
58
동영상에 대한 차영상 출력 if (image1 && image2) {
for (int i = 0; i < 320 * 240; i++) { if (abs((image1[i*3]+image1[i*3+1]+image1[i*3+2]) / 3 - (image2[i*3]+image2[i*3+1]+image2[i*3+2]) / 3) < 20) { data[i*3] = (char ) 0; data[i*3+1] =(char ) 0; data[i*3+2] = (char )0; } else { data[i*3] = (char )255; data[i*3+1] = (char )255; data[i*3+2] = (char )255; Invalidate(FALSE); }} 영상처리
59
동영상에 대한 차영상 출력 프로그램을 컴파일하고 실행 카메라 앞에서 움직이면 움직인 부분이 하얀색으로 표시됨
영상처리
Similar presentations