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

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
    - 주사방식
     → NTSC, PAL 등이 방식이 있다.


    - 테스트 1, 2
     → 첫번째로 복제된 영상에 BMP를 고정 위치로 출력시킨다.
     → 다음으로 원본 영상에 BMP를 고정 위치로 출력시킨다.
    #include<windows.h>
    #include<vfw.h>


    HBITMAP hBm; 
    BITMAPINFO BInfo;
    HWND hWnd;
    HWND hVfw;
    HDC hdc;
    HANDLE hFile;
    static TCHAR buf[640*480*3];

    // 라이브러리를 추가하는 것을 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, 100760740, 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_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;
      int iCnt2=54;
      DWORD dwRead;

      hFile = CreateFile("1117.bmp", GENERIC_READ, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL);
      // 원본 영상에 bmp파일 고정 출력
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {
          // 예외 처리
          if((60<yPos && 120>=yPos) && (80<=xPos && 160>xPos))
          {
            // BMP
            lp->lpData[iCnt+2= buf[(iCnt2)+2];
            lp->lpData[iCnt+1= buf[(iCnt2)+1];
            lp->lpData[iCnt] = buf[iCnt2];
            iCnt2 = iCnt2 +3;
          }  
          iCnt = iCnt+3;
        }
      }  
      iCnt = 0;
      iCnt2 = 54;
      
      // 복제 영상에 bmp파일 고정 출력
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {
          // 예외 처리
          if((60<yPos && 120>=yPos) && (80<=xPos && 160>xPos))
          {
            // BMP
            SetPixel(hdc, xPos+420, yPos+10, RGB(buf[(iCnt2)+2], buf[(iCnt2)+1], buf[(iCnt2)]));
            iCnt2 = iCnt2 +3;
          }
          else
          {
            // 영상      
            SetPixel(hdc, xPos+420, yPos+10, RGB(lp->lpData[iCnt+2], lp->lpData[iCnt+1], lp->lpData[iCnt]));
          }
          iCnt = iCnt +3;
        }
      }    
      return 0;
    }
     → 원본 영상과 복제 영상 양쪽에 각각 출력시킨다.
     → 실행 결과

     → 사실 원본 영상을 바꾸었으면 복제영상은 예외처리를 할 필요가 없다. 복제 영상은 원본 영상을 그대로 복제하기 때문에 BMP로 대체된 부분가지 그대로 복제하여 출력한다.



    - 테스트 3
     → 출력되는 영상에 떠있는 BMP 출력 화면을 키보드의 방향키를 이용하여 이동시킨다.

    #include<windows.h>
    #include<vfw.h>


    HBITMAP hBm; 
    BITMAPINFO BInfo;
    HWND hWnd;
    HWND hVfw;
    HDC hdc;
    HANDLE hFile;
    static TCHAR buf[640*480*3];

    unsigned int xStart = 0;
    unsigned int xEnd = 80;
    unsigned int yStart = 0;
    unsigned int yEnd = 60;


    // 라이브러리를 추가하는 것을 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, 100760740, 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;
        // 키를 움직여 bmp 파일의 출력 위치를 조절한다.
        case WM_KEYDOWN:
          switch(wParam)
          {
          case VK_LEFT:
            if(0 == xStart)
            {
              xStart = 0;
              xEnd = 80;
            }
            else
            {
              xStart = xStart - 10;
              xEnd = xEnd - 10;
            }
            break;
          case VK_RIGHT:
            if(240 == xStart)
            {
              xStart = 240;
              xEnd = 320;
            }
            else
            {
              xStart = xStart + 10;
              xEnd = xEnd + 10;
            }
            break;
          case VK_UP:
            if(yStart == 0)
            {
              yStart = 0;
              yEnd = 60;
            }
            else
            {
              yStart = yStart - 10;
              yEnd = yEnd - 10;
            }
            break;
          case VK_DOWN:
            if(yStart == 180)
            {
              yStart = 180;
              yEnd = 240;
            }
            else
            {
              yStart = yStart + 10;
              yEnd = yEnd + 10;
            }
            break;
          }
          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)
    {
      unsigned int xPos;
      unsigned int yPos;  
      unsigned int iCnt=0;
      unsigned int iCnt2=54;
      DWORD dwRead;

      hFile = CreateFile("1117.bmp", GENERIC_READ, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL);
      // 원본 영상에 bmp파일 고정 출력
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {
          // 예외 처리
          if(((yStart<yPos) && (yEnd>=yPos)) && ((xStart<=xPos) && (xEnd>xPos)))
          {
            // BMP
            lp->lpData[iCnt+2= buf[(iCnt2)+2];
            lp->lpData[iCnt+1= buf[(iCnt2)+1];
            lp->lpData[iCnt] = buf[iCnt2];
            iCnt2 = iCnt2 +3;
          }  
          iCnt = iCnt+3;
        }
      }  
      iCnt = 0;
      iCnt2 = 54;
      return 0;
    }


     → 실행 결과

     → 키보드의 방향키를 입력하므로써 출력된 이미지를 영상 범위 내에서 이동시킬 수 있다.
     → 출력 영상의 범위를 벗어나지 않도록 예외 처리를 실시한다.
     

    - 영상에서 RGB값에 따른 분리
     → 우선 화면의 정중앙(x축 160, y축 120)을 지정해 해당 픽셀의 RGB값을 추출하여 윈도우 상단 바에 뿌린다.
     → 카메라를 칠판에 맞추고 RGB 값을 추출한다.(오차범위 ±5 정도)
     → 값을 추출하면 소스를 수정하여 해당 값을 가지는 픽셀은 RED로 출력한다.
     → RED로의 변환에 성공하면 해당 범위에 이미지가 출력되도록 소스를 수정한다.
     → 소스 작성
    #include<windows.h>
    #include<vfw.h>


    HBITMAP hBm; 
    BITMAPINFO BInfo;
    HWND hWndMain;
    HWND hVfw;
    HDC hdc;
    HANDLE hFile;
    static TCHAR buf[640*480*3];

    unsigned int xStart = 0;
    unsigned int xEnd = 80;
    unsigned int yStart = 0;
    unsigned int yEnd = 60;

    unsigned char Red;
    unsigned char Green;
    unsigned char Blue;

    // 라이브러리를 추가하는 것을 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 구조체의 번지를 전달

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


      /* 화면에 윈도우 표시 */
      ShowWindow(hWndMain, 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)
    {  
      static int X;
      static int Y;
      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_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)
    {
      unsigned int xPos;
      unsigned int yPos;  
      unsigned int iCnt=0;
      unsigned int iCnt2=54;  

      DWORD dwRead;

      hFile = CreateFile("11.bmp", GENERIC_READ, 0, NULL,
            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      ReadFile(hFile, buf, sizeof(buf), &dwRead, NULL);

      // 원본 영상에 bmp파일 고정 출력
      for(yPos=240;0<yPos;--yPos)
      {
        for(xPos=0;320>xPos;++xPos)
        {
          
    /* 화면 중앙(x축160, y축120)에서 RGB값을 읽어들인다.
          if(160==xPos && 120==yPos)
          {
            Blue = lp->lpData[iCnt+2];
            Green = lp->lpData[iCnt+1];
            Red = lp->lpData[iCnt];        
          }*/
          
          Blue = lp->lpData[iCnt+2];
          Green = lp->lpData[iCnt+1];
          Red = lp->lpData[iCnt];        
          if((185>Red&&160<Red)&&(185>Green&&160<Green)&&(185>Blue&&160<Blue))
          {
            // BMP 파일을 해당 픽셀에 출력한다.
            lp->lpData[iCnt+2= buf[(iCnt2)+2];
            lp->lpData[iCnt+1= buf[(iCnt2)+1];
            lp->lpData[iCnt] = buf[iCnt2];
          }  
          iCnt2 = iCnt2+3;
          iCnt = iCnt+3;
        }
      }
      // BMP 파일을 해당 픽셀에 출력한다.
      wsprintf(buf, TEXT("R: %d, G: %d, B: %d"), Red , Green, Blue);
      SetWindowText(hWndMain,buf);

      return 0;
    }

     → 우선 화면의 중앙 픽셀에서 읽어들인 값을 확인한 결과 RED, GREEN, BLUE가 각각 165에서 175 사이의 값 에서 변화하는 것을 확인할 수 있었다.
     → 따라서 해당 범위를 RED로만 출력되도록 소스를 변경하였다.


     → 다음으로 RED로 바뀐 부분에 이미지가 출력되도록 소스를 수정하였다.

     


     → 문제점으로 해당 칠판에 대한 RGB 값의 변동이 심하고 생각한 만큼의 정확도로 칠판에 표시되지가 않았다.
     → RGB값의 범위를 조절하여 테스트를 반복하였으나 원하는 정도의 결과가 나오지 않았다.
    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함