블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
     → 영상 처리 예제 소스
    #include<windows.h>
    #include<vfw.h>


    HBITMAP hBm; 
    BITMAPINFO BInfo;
    HWND hWnd;
    HWND hVfw;
    HDC hdc;

    // 라이브러리를 추가하는 것을 comment - 수동식
    // project setting을 변화시키면 project를 통채로 복사해야 하지만
    // #pragama comment를 사용하면 소스만 복사해도 동작한다.
    #pragma comment (lib, "vfw32.lib")

    LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp);
    /* 고정 형식 */
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // 메세지 처리 함수
    HINSTANCE g_hInst; // instance 전역 변수 선언
    LPCTSTR lpszClass = TEXT("VFW32"); // 윈도 클래스 이름 정의

    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
    {
      MSG Message; // MSG 구조체 사용
      WNDCLASS WndClass; // WndClass 구조체 사용
      g_hInst = hInstance; // 윈도우 클래스를 등록하는 프로그램의 번호이며 WinMain의 인수로 전달된 hInstance값을 그대로 대입

      /* 윈도우 클래스 정의 */
      WndClass.cbClsExtra = 0// 예약 영역, 사용하지 않을 경우는 0
      WndClass.cbWndExtra = 0;
      WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // HBRUSH 타입으로 형변환
      WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 윈도우가 사용할 마우스 커서지정
      WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 윈도우가 사용할 아이콘 지정
      WndClass.hInstance = hInstance;
      WndClass.lpfnWndProc = WndProc; // 윈도우의 메시지 처리 함수를 지정
      WndClass.lpszClassName = lpszClass; // 윈도우 클래스의 이름을 문자열로 정의 - 여기서는 First라는 문자열을 보내준다.
      WndClass.lpszMenuName = NULL; // 프로그램이 사용할 메뉴를 지정
      WndClass.style = CS_HREDRAW|CS_VREDRAW; // 윈도우가 어떤 형태를 가질 것인가-윈도우의크기가 변할 경우 윈도우를 다시 그린다.
      
      /* 윈도우 클래스 등록 */
      RegisterClass(&WndClass);  // WndClass 구조체의 번지를 전달

      // 메모리 상에 윈도우 생성
      hWnd=CreateWindow(lpszClass, TEXT("Video for Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
      
    /* 인자의 의미 -> (윈도우 클래스 이름, 타이틀바에 나타날 문자열-윈도우 네임(클래스 이름과 같게 하려면 lpszClass), 
                윈도우의 형태 지정, 윈도우의 크기와 위치(픽셀단위)-x, y, nWidth, nHeight, 
                부모 윈도우가 있을 경우 부모윈도우의 핸들-hWndParent, 윈도우에서 사용할 메뉴의 핸들-hmenu, 
                프로그램의 핸들 지정-hinst(프로그램이 종료될 때 파괴되지 않은 윈도우를 자동으로 파괴),
                여러개의 윈도우를 만들때 각 윈도우에 고유의 파라미터를 전달하는 특수 목적에 사용-lpvParam)
                */


      /* 화면에 윈도우 표시 */
      ShowWindow(hWnd, nCmdShow); //  CreateWindow 함수가 리턴한 핸들을 이용하여 출력

      /* 사용자로부터의 메시지 처리*/
      while(GetMessage(&Message, NULL, 00)) // 메시지 큐에서 메시지 읽어옴, 
                          // WN_QUIT이면 False 리턴 후 while문을 빠져나간다.
      {
        TranslateMessage(&Message); // 키보드 입력 처리 
                      // 만약 A키를 누르면 A문자가 입력되었다는 메시지를 만들어 낸다.
        DispatchMessage(&Message); // 큐에서 꺼낸 메시지를 WndProc 함수의 iMAssage로 전달
      }
      return (int)Message.wParam; // 메시지 루프 종료 후 이 프로그램을 실행시킨 OS로 리턴
    }


    // 사용자와 시스템이 보내오는 메시지를 처리
    // 운영체제가 호출하는 함수는 CALLBACK 표시, LRESULT = 4byte long
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
    {  
      switch(iMessage) // 운영체제로부터 들어온 메시지에 대한 처리
      {
        /* 고정 형식 */
        case WM_CREATE:
          hdc = GetDC(hWnd);
          // 320x240으로 캡쳐, 부모 윈도우(hWnd), 
          // 창이 만들어 진다. - 실제 생성되지는 않는다.
          hVfw = capCreateCaptureWindow(TEXT("Video for Window"), WS_CHILD|WS_VISIBLE, 1010320240, hWnd, 0);
          // usb를 통해 연결된 카메라 장치를 찾아 연결해 준다.
          capDriverConnect(hVfw, 0);
          // hVfw, 1ms - 화면에 보이는 속도(Rate)
          capPreviewRate(hVfw, 1);
          // Video 포멧을 확인하고 정보를 넣는다.
          capGetVideoFormat(hVfw, &BInfo, sizeof(BITMAPINFO));
          BInfo.bmiHeader.biWidth = 320;
          BInfo.bmiHeader.biHeight = 240;
          capSetVideoFormat(hVfw, &BInfo, sizeof(BITMAPINFO));
          // 자동으로 라이브러리에서 Emb_Draw()를 호출해 준다.
          capSetCallbackOnFrame(hVfw, Emb_Draw);
          // 화면에 띄운다.(TRUE)
          capPreview(hVfw, TRUE);
          
          return 0;      
        case WM_LBUTTONDOWN:
          return 0;
        case WM_DESTROY: // 운영체제로부터 들어온 메시지에 대한 처리 - 여기서는 윈도우가 파괴되었음을 알린다.
          ReleaseDC(hWnd, hdc);
          PostQuitMessage(0); // WM_QUIT 메시지를 보냄
          return 0;
      }
      // switch 문에서 처리하지 않은 메시지를 처리
      return(DefWindowProc(hWnd, iMessage, wParam, lParam));
    }
    // HWND, long *
    LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
    {
      int xPos;
      int yPos;  
      int iCnt=0;
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {      
          //lp->lpData[iCnt+0]=255;
          SetPixel(hdc, xPos+420, yPos+10, RGB(00, lp->lpData[iCnt])); // 블루
          SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
          SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 00)); // 레드
          iCnt = iCnt +3;
        }
      }  
      return 0;
    }

     → 실행 결과


     → 아래 함수를 이용하여 캠에서 들어오는 영상을 복제해서 뿌린다.
    // HWND, long *
    LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
    {
      int xPos;
      int yPos;  
      int iCnt=0;
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {      
          //lp->lpData[iCnt+0]=255;
          SetPixel(hdc, xPos+420, yPos+10, RGB(00, lp->lpData[iCnt])); // 블루
          SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
          SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 00)); // 레드
          iCnt = iCnt +3;
        }
      }  

     → COLORREF SetPixel(hdc, nXPos, nYPos, clrref)
     → 위 함수는 화면에 점을 출력하는 함수로 for문을 돌려 영상을 출력(원본 영상의 복사)한다.
     → 출력은 원본을 제외한 3가지로 BLUE, GREEN, RED 의 색상만을 각각 출력해 본다.

    // HWND, long *
    LRESULT CALLBACK Emb_Draw(HWND hWnd, LPVIDEOHDR lp)
    {
      int xPos;
      int yPos;  
      int iCnt=0;
      DWORD dwRead;

      hFile = CreateFile("116.bmp", GENERIC_READ, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL);
      
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {      
          //lp->lpData[iCnt+0]=255;
          // 영상
          SetPixel(hdc, xPos+420, yPos+10, RGB(lp->lpData[iCnt+2], lp->lpData[iCnt+1], lp->lpData[iCnt]));
          // BMP
          SetPixel(hdc, xPos+10, yPos+250, RGB(buf[(iCnt+54)+2], buf[(iCnt+54)+1], buf[(iCnt+54)]));
          // BMP + 영상
          SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2]+buf[(iCnt+54)+2], lp->lpData[iCnt+1]+buf[(iCnt+54)+1], lp->lpData[iCnt]+buf[(iCnt+54)]));
          // BMP - 영상
          SetPixel(hdc, xPos+10, yPos+490, RGB(lp->lpData[iCnt+2]-buf[(iCnt+54)+2], lp->lpData[iCnt+1]-buf[(iCnt+54)+1], lp->lpData[iCnt]-buf[(iCnt+54)]));
          // BMP * 영상
          SetPixel(hdc, xPos+420, yPos+490, RGB(lp->lpData[iCnt+2]*buf[(iCnt+54)+2], lp->lpData[iCnt+1]*buf[(iCnt+54)+1], lp->lpData[iCnt]*buf[(iCnt+54)])); 
          
          //SetPixel(hdc, xPos+10, yPos+250, RGB(0, lp->lpData[iCnt+1], 0)); // 그린
          //SetPixel(hdc, xPos+420, yPos+250, RGB(lp->lpData[iCnt+2], 0, 0)); // 레드
          iCnt = iCnt +3;
        }
      }  
      return 0;
    }

     → 실행파일

     → 위의 실행 결과는 왼쪽 처음부터 오른쪽으로 각각
     → 원본영상, 복사 영상
     → BMP출력, 영상+BMP
     → 영상-BMP, 영상*BMP
     → 6가지의 출력을 나타낸 것이다.
     
    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함