영상처리

영상처리 (특정색 검출 + 이진화 + 엣지 검출)

빛나는 미래 2010. 1. 5. 18:49

#include<windows.h>
#include "vfw.h"
#pragma comment(lib,"vfw32.lib")

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK FramInfo(HWND,LPVIDEOHDR);

HINSTANCE g_hInst;
HWND hwndMain;
HWND hVFW;
HWND HwndMain;
HBITMAP hBit;
BITMAPINFO bm;

LPCTSTR lpszClass=TEXT("VFW");
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)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,
  lpszClass,
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,//x좌표
  CW_USEDEFAULT,//y
  1300,// 윈도우창의  가로폭
  1000,// 윈도 창의 세로폭
  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;
 static RECT rt={200,500,100,100};

 switch(IMessage)
 {
 case WM_CREATE:
  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;
  }

  GetClientRect(hWnd,&rt);

  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;
 int i=60;//엣지 감도조절 변수
 int flag=0;

 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)
  { 
   SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(VideoHdr->lpData[Jump+2],VideoHdr->lpData[Jump+1],VideoHdr->lpData[Jump]));

   // 점찍기 (핸들 , x좌표,y좌표                                      red               , green                  ,blue)  
   Jump += 3;// 색상 배열 3개의 요소 건넘뜀
  }
 }

 BitBlt(Hdc,0,0
  ,bm.bmiHeader.biWidth
  ,bm.bmiHeader.biHeight
  ,hMemDC
  ,0,0
  ,SRCCOPY);
 Jump=0;

 //--------------------------------------------------------- 특정색 검출------------------------------------------------------------------------------
 for(iCntY =0; iCntY<bm.bmiHeader.biHeight; ++iCntY)
 { 
 for(iCntX=0;iCntX<bm.bmiHeader.biWidth;++iCntX)
 { if(VideoHdr->lpData[Jump]>230&&VideoHdr->lpData[Jump+2]>230&&VideoHdr->lpData[Jump+1]>230)

 SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(30,100,230));
 else
 SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(VideoHdr->lpData[Jump+2],VideoHdr->lpData[Jump+1],VideoHdr->lpData[Jump]));

 // 점찍기 (핸들 , x좌표,y좌표                                      red               , green                  ,blue)  
 Jump += 3;// 색상 배열 3개의 요소 건넘뜀
 }

 } 
 BitBlt(Hdc,650,0
 ,bm.bmiHeader.biWidth
 ,bm.bmiHeader.biHeight
 ,hMemDC
 ,0,0
 ,SRCCOPY);

 Jump=0;
 

 //---------------------------------------------------------------이진화--------------------------------------------
 for(iCntY =0; iCntY<bm.bmiHeader.biHeight; ++iCntY)
 { 
  for(iCntX=0;iCntX<bm.bmiHeader.biWidth;++iCntX)
  { if(VideoHdr->lpData[Jump]>i&&VideoHdr->lpData[Jump+2]>i&&VideoHdr->lpData[Jump+1]>i)

  SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(255,255,255));//흰점
  else
   SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(0,0,0));// 검은점

  // 점찍기 (핸들 , x좌표,y좌표                                      red               , green                  ,blue)  
  Jump += 3;// 색상 배열 3개의 요소 건넘뜀
  }

 } 
 BitBlt(Hdc,0,500
  ,bm.bmiHeader.biWidth
  ,bm.bmiHeader.biHeight
  ,hMemDC
  ,0,0
  ,SRCCOPY);

 Jump=0;

 //---------------------------------------------------------------에지검출 --------------------------------------------
 for(iCntY =0; iCntY<bm.bmiHeader.biHeight; ++iCntY)
 { 
  for(iCntX=0;iCntX<bm.bmiHeader.biWidth;++iCntX)
  { 
   if(VideoHdr->lpData[Jump]>i && VideoHdr->lpData[Jump+2]>i && VideoHdr->lpData[Jump+1]>i)// 감도이상 밝아지면
   { 
    if(flag==0)
     SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(255,255,255));// 흰 점 찍음

   }
   else // 감도 이상 어두워지면
   {
    SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(0,0,0));// 검은 점 한번 찍고
    flag=1;
    if(flag=1&&VideoHdr->lpData[Jump]<i && VideoHdr->lpData[Jump+2]<i && VideoHdr->lpData[Jump+1]<i)// 어두운 부분 흰점 찍고
    { 
     SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(255,255,255));// 흰 점 찍다가
    }       

    else // 다시 밝아지면
     SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(0,0,0));// 검은 점 한번 찍고
    /*if(flag=1&&VideoHdr->lpData[Jump]>i && VideoHdr->lpData[Jump+2]>i && VideoHdr->lpData[Jump+1]>i)// 어두운 부분 흰점 찍고
    { 
    SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(255,255,255));// 흰 점 찍다가
    }  */ 
    flag=0;

   }
   Jump += 3;// 색상 배열 3개의 요소 건넘뜀
  }


 } 
 BitBlt(Hdc,650,500
  ,bm.bmiHeader.biWidth
  ,bm.bmiHeader.biHeight
  ,hMemDC
  ,0,0
  ,SRCCOPY);
 Jump=0;


 SelectObject(hMemDC,OldBitmap);

 

 ReleaseDC(HwndMain,Hdc);


 return 0;
}