<원본 이미지>
●주사방식
주사방식이란 화면의 맨 아랫줄 부터 한줄씩 위로 출력을 하여 전체 화면을 출력하는 방식이다. 다음의 이미지는 이를 나타낸 것이다.
주사방식은 NTSC와 PAL로 나뉜다. NTSC는 우리나라와 미국에서 사용하는 방식이다.
●다음은 수업시간에 작성한 영상처리에 관련된 소스 들이다. 소스안의 주석들로 설명을 대체한다.
//복사 영상에 비트맵 이미지 덮어쓰기
#include <windows.h>
#include <vfw.h>
#pragma comment(lib,"vfw32.lib") //수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR); //복사영상을 출력하는 함수
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
HANDLE hThread;
DWORD ThreadID;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch(iMessage)
{
case WM_CREATE:
hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);//3번째 인자 부터(계속)
//순서대로 설명;왼쪽상단 x좌표,왼쪽 상단 y좌표,가로 픽셀크기,세로 픽셀크기
capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
capPreviewRate(hVfw,1);//2번째 인자를 높이면 영상 속도는 느려짐
capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
BInfo.bmiHeader.biWidth=320; //영상 가로크기
BInfo.bmiHeader.biHeight=240; //영상 세로크기
capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 Emb_Draw함수가 계속 호출된다
capPreview(hVfw,TRUE); //FALSE로 바꾸면 최초 영상이 사진으로 나타난다.
g_hdc=GetDC(hWnd);
return 0;
case WM_DESTROY:
ReleaseDC(hWnd,g_hdc);
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData[](RGB 값)
{
unsigned int i;
unsigned int j;
unsigned int index=0;
unsigned char* ucP;
static unsigned char buf[80*60*3]; //이미지 크기가 80X60 픽셀이고, 한점은 3바이트를 차지함
HANDLE hFile;
DWORD dwRead;
HDC hdc;
hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
CloseHandle(hFile);
ucP=&buf[54];
for(i=240;0<i;--i)
{
for(j=0;320>j;++j)
{
if((400<=360+j)&&(480>=360+j)&&(140<=i)&&(200>=i)) //영상 안에 일정영역이라면
{
SetPixel(g_hdc,360+j,i,RGB(*(ucP+2),*(ucP+1),*ucP)); //비트맵 이미지 출력
ucP=ucP+3;
}
else
{
SetPixel(g_hdc,360+j,i,RGB(lp->lpData[index+2],lp->lpData[index+1],lp->lpData[index]));//영상 출력
}
index=index+3;
}
ucP=ucP+(*(LONG*)(&buf[18]))%4;
}
return 0;
}
//원본 영상에 비트맵 이미지 덮어쓰기
//중복되는 코드는 생략
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
unsigned int i;
unsigned int j;
unsigned int index=0;
unsigned char* ucP;
static unsigned char buf[80*60*3];
HANDLE hFile;
DWORD dwRead;
HDC hdc;
hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
CloseHandle(hFile);
ucP=&buf[54];
for(i=240;0<i;--i)
{
for(j=0;320>j;++j)
{
if((40<=j)&&(120>=j)&&(140<=i)&&(200>=i))//원본영상의 특정영역 이라면
{
lp->lpData[index+2]=*(ucP+2); //원본영상의 점을 비트맵 점으로 대치함
lp->lpData[index+1]=*(ucP+1);
lp->lpData[index]=*ucP;
ucP=ucP+3;
}
index=index+3;
}
ucP=ucP+(*(LONG*)(&buf[18]))%4;
}
return 0;
}
Emb_Draw() 함수가 호출되고, 그 다음에 원본영상이 출력이 되므로, Emb_Draw()함수에서 원본영상의 점을 바꿔 버리면 원본영상에는 바뀌어진 점이 출력 되는 것이다. 그러므로, 원본영상에 비트맵 이미지를 덮어쓰는 것이 가능한 것이다.
//원본영상내 비트맵 이미지 키보드로 위치 조작하기
#include <windows.h>
#include <vfw.h>
#pragma comment(lib,"vfw32.lib") //수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD WINAPI Thread_Func(LPVOID);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;
unsigned int uiStartX=40; //비트맵 맨 좌측 X좌표
unsigned int uiEndX=120; //비트맵 맨 우측 X좌표
unsigned int uiStartY=140; //비트맵 맨 위측 Y좌표
unsigned int uiEndY=200; //비트맵 맨 아래측 Y좌표
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
HANDLE hThread;
DWORD ThreadID;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch(iMessage)
{
case WM_CREATE:
hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);//
capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
capPreviewRate(hVfw,1);
capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
BInfo.bmiHeader.biWidth=320;
BInfo.bmiHeader.biHeight=240;
capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 이함수가 계속 호출된다
capPreview(hVfw,TRUE);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(0!=uiStartX) //영상 맨 좌측에 이미지가 닿으면 이동 안함
{
--uiStartX;
--uiEndX;
}
break;
case VK_RIGHT:
if(319-80>uiStartX)//영상 맨 우측에 이미지가 닿으면 이동 안함
{
++uiStartX;
++uiEndX;
}
break;
case VK_UP:
if(1!=uiStartY)//영상 맨 위측에 이미지가 닿으면 이동 안함
{
--uiStartY;
--uiEndY;
}
break;
case VK_DOWN:
if(240!=uiEndY)//영상 맨 아래측에 이미지가 닿으면 이동 안함
{
++uiStartY;
++uiEndY;
}
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
unsigned int i;
unsigned int j;
unsigned int index=0;
unsigned char* ucP;
static unsigned char buf[80*60*3];
HANDLE hFile;
DWORD dwRead;
hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
CloseHandle(hFile);
ucP=&buf[54];
for(i=240;0<i;--i)
{
for(j=0;320>j;++j)
{
if((uiStartX<=j)&&(uiEndX>=j)&&(uiStartY<=i)&&(uiEndY>=i)) //방향키를 누르면 전역변수의 값이(계속)
{ //바뀌므로, 영상내 특정 영역의 위치가 이동함
lp->lpData[index+2]=*(ucP+2);
lp->lpData[index+1]=*(ucP+1);
lp->lpData[index]=*ucP;
ucP=ucP+3;
}
index=index+3;
}
ucP=ucP+(*(LONG*)(&buf[18]))%4;
}
return 0;
}
//원본 영상에 있는 비트맵 이미지 마우스로 위치 조작하기
#include <windows.h>
#include <vfw.h>
#pragma comment(lib,"vfw32.lib") //수동식으로 라이브러리 추가;소스만 들고가면 OK;자동은 디렉토리 통째로 딴데로 가져가야 함;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD WINAPI Thread_Func(LPVOID);
LRESULT CALLBACK Emb_Draw(HWND,LPVIDEOHDR);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("First");
HBITMAP HBm;
BITMAPINFO BInfo;
HWND hVfw;
HDC g_hdc;
unsigned char temp;
unsigned int uiStartX=40;
unsigned int uiEndX=120;
unsigned int uiStartY=140;
unsigned int uiEndY=200;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
HANDLE hThread;
DWORD ThreadID;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,TEXT("Hello"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,NULL,0,0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static BOOL bLbuttonDown=FALSE;
static int x;
static int y;
int current_x;
int current_y;
switch(iMessage)
{
case WM_CREATE:
hVfw=capCreateCaptureWindow(TEXT("영상처리"),WS_CHILD | WS_VISIBLE ,0,0,320,240,hWnd,0);//
capDriverConnect(hVfw,0);//창과 카메라 붙이는 거
capPreviewRate(hVfw,1);
capGetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
BInfo.bmiHeader.biWidth=320;
BInfo.bmiHeader.biHeight=240;
capSetVideoFormat(hVfw,&BInfo,sizeof(BInfo));
capSetCallbackOnFrame(hVfw,Emb_Draw); //$$자동으로 이함수가 계속 호출된다
capPreview(hVfw,TRUE);
return 0;
case WM_LBUTTONDOWN:
x=LOWORD(lParam);
y=HIWORD(lParam);
bLbuttonDown=TRUE;
return 0;
case WM_MOUSEMOVE:
if(TRUE==bLbuttonDown)
{
current_x=LOWORD(lParam);
current_y=HIWORD(lParam);
if(0>x-current_x)//마우스 오른쪽 이동
{
++uiStartX;
++uiEndX;
}
else if(0<x-current_x) //마우스 왼쪽 이동
{
--uiStartX;
--uiEndX;
}
if(0>y-current_y) //마우스 아래 이동
{
++uiStartY;
++uiEndY;
}
else if(0<y-current_y) //마우스 위로 이동
{
--uiStartY;
--uiEndY;
}
x=current_x;
y=current_y;
}
return 0;
case WM_LBUTTONUP:
bLbuttonDown=FALSE;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
LRESULT CALLBACK Emb_Draw(HWND hWnd,LPVIDEOHDR lp) //lp->lpData(RGB 값)
{
unsigned int i;
unsigned int j;
unsigned int index=0;
unsigned char* ucP;
static unsigned char buf[80*60*3];
HANDLE hFile;
DWORD dwRead;
hFile=CreateFile(TEXT("girl.bmp"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
ReadFile(hFile,buf,sizeof(buf),&dwRead,NULL);
CloseHandle(hFile);
ucP=&buf[54];
for(i=240;0<i;--i)
{
for(j=0;320>j;++j)
{
if((uiStartX<=j)&&(uiEndX>=j)&&(uiStartY<=i)&&(uiEndY>=i))
{
lp->lpData[index+2]=*(ucP+2);
lp->lpData[index+1]=*(ucP+1);
lp->lpData[index]=*ucP;
ucP=ucP+3;
}
index=index+3;
}
ucP=ucP+(*(LONG*)(&buf[18]))%4;
}
return 0;
}
'코스웨어 > 11년 내장형하드웨어' 카테고리의 다른 글
BrickOS Memory Management Report (0) | 2011.11.30 |
---|---|
[내장형]황세선_2011.11.29 일일보고서 (4) | 2011.11.30 |
brickos-0.9.0 폴더 (0) | 2011.11.29 |
[내장형]2011.11.28 일일보고서 - 정선주 (7) | 2011.11.28 |
[내장형]김동화 - 11월22일 일일보고서 (10) | 2011.11.22 |
[내장형]윤수영 - 11월21일 일일보고서 (7) | 2011.11.21 |
[내장형]최남식-2011년 11월18일 일일보고서 (8) | 2011.11.18 |
[내장형]김수만 111116 (7) | 2011.11.17 |