VFW 영상처리 함수를 사용하여 캠으로 부터 화면의 변경이 발생했을때 즉시비트맵을 다시 재출력 하는 방식으로 캠동영상을 출력하는 프로그램이다.
여기에 RGB 값을 검사하여 흰색과 가까운 밝은 부분이 검출될시 따로 마련된 비트맵을 대신 출력되는 옵션을 주었다. 캠을 창가 쪽을 향하게 하여 밝은 밖의 모습이 비트맵으로 대체되고 내 팔이나 실내의 사물들은 이미지 그대로 출력 됨을 알 수 있다. 이를 이용하여 TV 일기예보시 배경에 움직이는 구름사진들이 표시된다는 것을 알 수 있다.
마지막 사진은 옷의 가슴에 새겨진 흰색 로고가 배경화면으로 대체됨을 보여준다.
이전에 미흡했던 그래프도 추가 하였는데 점으로 표시되던 그래프를 10단위로 나누어 선으로 연결하여 보기에 알기 쉬운 그래프로 변경 되었다. 화면이 시시각각 바뀌는 동영상이라 보니 그래프 또한 그에 맞추어 시시각각 변경된다.
출력결과
소스
#include#include #include #include #pragma comment(lib,"vfw32.lib") enum {RED=0, GREEN, BLUE, COLOR}; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr); void DrawGraph(HDC hdc, int x, int y); HINSTANCE g_hInst; HWND hWndMain; LPCTSTR lpszClass=TEXT("Vfw32"); HBITMAP hBit; BITMAPINFO Bm; int ColorCnt[COLOR][256]; TCHAR Buf[320*240+54]; // 이미지 저장 배열 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance ,LPSTR lpszCmdParam,int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst=hInstance; WndClass.cbClsExtra=0; WndClass.cbWndExtra=0; WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); 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,lpszClass,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) { HDC hdc; HWND hVFW; int iDes; switch (iMessage) { case WM_CREATE: iDes = open("qwer.bmp", O_RDONLY); read(iDes, Buf, 330000); close(iDes); hWndMain=hWnd; hdc = GetDC(hWnd); hVFW = capCreateCaptureWindow( TEXT("VFW"), WS_CHILD | WS_VISIBLE, 0, 0, 1, 1, hWnd, 0); capDriverConnect(hVFW, 0); capPreviewRate(hVFW, 1); capPreview(hVFW, TRUE); capGetVideoFormat(hVFW, &Bm, sizeof(Bm)); hBit = CreateCompatibleBitmap(hdc, Bm.bmiHeader.biWidth, Bm.bmiHeader.biHeight); if(capSetCallbackOnFrame(hVFW, FramInfo) == FALSE) { return FALSE; } ReleaseDC(hWnd, hdc); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); } LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr) { HDC Hdc; HDC hMemDc; HBITMAP OldBitmap; int iCntX; int iCntY; int Jump; HPEN MyPen, OldPen; Hdc = GetDC(hWndMain); hMemDc = CreateCompatibleDC(Hdc); OldBitmap = (HBITMAP)SelectObject(hMemDc, hBit); Jump = 0; for(iCntY = 0; iCntY < Bm.bmiHeader.biHeight ; ++iCntY) { for(iCntX = 0; iCntX < Bm.bmiHeader.biWidth ; ++iCntX) { /* if(120 < VideoHdr->lpData[Jump+2]) // R { } else if(120 < VideoHdr->lpData[Jump+1]) // G { } else if(120 < VideoHdr->lpData[Jump]) // B { VideoHdr->lpData[Jump+2] = 255; VideoHdr->lpData[Jump+1] = 255; VideoHdr->lpData[Jump] = 255; } */ if(100 < VideoHdr->lpData[Jump+2] && 100 < VideoHdr->lpData[Jump+1] && 100 < VideoHdr->lpData[Jump]) { VideoHdr->lpData[Jump+2] = Buf[Jump+2+54]; VideoHdr->lpData[Jump+1] = Buf[Jump+1+54]; VideoHdr->lpData[Jump] = Buf[Jump+54]; } SetPixel(hMemDc, iCntX, (Bm.bmiHeader.biHeight - iCntY)-1, RGB(VideoHdr->lpData[Jump+2], VideoHdr->lpData[Jump+1], VideoHdr->lpData[Jump]) ); ColorCnt[RED][VideoHdr->lpData[Jump+2]] += 1; ColorCnt[GREEN][VideoHdr->lpData[Jump+1]] += 1; ColorCnt[BLUE][VideoHdr->lpData[Jump]] += 1; Jump += 3; } } MyPen = (HPEN)GetStockObject(NULL_PEN); OldPen = (HPEN)SelectObject(Hdc, MyPen); Rectangle(Hdc, 400, 0, 700, 600); SelectObject(Hdc, OldPen); DrawGraph(Hdc, 400, 600); memset(ColorCnt, 0, sizeof(ColorCnt)); /* for(iCntY = 0; iCntY < 256; ++iCntY){ ColorCnt[RED][iCntY] = 0; ColorCnt[GREEN][iCntY] = 0; ColorCnt[BLUE][iCntY] = 0; } */ BitBlt(Hdc, 0, 0, Bm.bmiHeader.biWidth, Bm.bmiHeader.biHeight, hMemDc, 0, 0, SRCCOPY); SelectObject(hMemDc, OldBitmap); DeleteDC(hMemDc); ReleaseDC(hWndMain, Hdc); return 0; } void DrawGraph(HDC hdc, int x, int y) { int rgb_x; HPEN hPen[3], oldPen; //그래프 축 그리기 MoveToEx(hdc, x, y, NULL); LineTo(hdc, x+300, y); MoveToEx(hdc, x, y, NULL); LineTo(hdc, x, 0); TextOut(hdc, x, y+10, "0", 1); TextOut(hdc, x+240, y+10, "255", 3); hPen[RED] = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); hPen[GREEN] = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); hPen[BLUE] = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); oldPen = (HPEN)SelectObject(hdc, hPen[RED]); MoveToEx(hdc, x, y, NULL); for(rgb_x=0; rgb_x<250; rgb_x += 10) { LineTo(hdc, rgb_x+x, y - ColorCnt[RED][rgb_x]/5); } oldPen = (HPEN)SelectObject(hdc, hPen[GREEN]); MoveToEx(hdc, x, y, NULL); for(rgb_x=0; rgb_x<250; rgb_x += 10) { LineTo(hdc, rgb_x+x, y - ColorCnt[GREEN][rgb_x]/5); } oldPen = (HPEN)SelectObject(hdc, hPen[BLUE]); MoveToEx(hdc, x, y, NULL); for(rgb_x=0; rgb_x<250; rgb_x += 10) { LineTo(hdc, rgb_x+x, y - ColorCnt[BLUE][rgb_x]/5); } DeleteObject(hPen[RED]); DeleteObject(hPen[GREEN]); DeleteObject(hPen[BLUE]); return; }
'WIN_API' 카테고리의 다른 글
| 차분 이미지 와 흑백 이미지 출력 (0) | 2009/08/11 |
|---|---|
| 비트맵 뷰어(CM) 새로운 버전 (0) | 2009/08/11 |
| VFW 영상처리(CAM) 를 이용한 비트맵의 변형 (0) | 2009/07/21 |
| 비트맵 뷰어 - 그래프(픽셀그래프) (0) | 2009/07/21 |
| 비트맵 뷰어 - 수정본 (0) | 2009/07/21 |
| 비트맵 뷰어 - CMVer (0) | 2009/07/21 |


