영상처리

영상처리 특정색 검출 후 표현

빛나는 미래 2010. 1. 12. 15:37

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

#define ID_R_SCROLL  202
#define ID_G_SCROLL  203
#define ID_B_SCROLL  204
#define ID_SCRRED  100
#define ID_SCRGREEN     101
#define ID_SCRBLUE  102
#define ID_Brightness 103
#define ID_FIND   104


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


HINSTANCE g_hInst;
HWND hVFW;
HWND HwndMain;
HWND hwndMain;
HWND hRed,hGreen,hBlue,h_CFIND,hBrightness;// 스크롤바 핸들
HBITMAP hBit;
BITMAPINFO bm;
PAINTSTRUCT ps;

int flag_menu=0;
unsigned int j=65;//명암 밝기 조절  변수
int flag_plus=0;
int flag=0;
int Red,Green,Blue,FIND,Brightness;
int TempPos;
int GAP;// GAP특정색 검출 오차 범위
int i=0;//엣지 감도조절 변수

RECT rect1 = {0,0,1300,400};
RECT rect2 = {500,500,600,600};
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)(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
  ,1280// 윈도우창의  가로폭
  ,1200// 윈도 창의 세로폭
  ,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;
 HDC hdc;
 HBRUSH MyBrush,OldBrush;
 hwndMain = hWnd;

 switch (iMessage)
 {
 case WM_CREATE:
  CreateWindow(TEXT("button"),TEXT("특정색 검출"),WS_CHILD | WS_VISIBLE |
   BS_PUSHBUTTON ,640,500,200,35,hWnd,(HMENU)0,g_hInst,NULL);//푸쉬 버튼

  CreateWindow(TEXT("button"),TEXT("특정색 검출 후 2진화"),WS_CHILD | WS_VISIBLE |
   BS_PUSHBUTTON ,640,600,200,35,hWnd,(HMENU)1,g_hInst,NULL);//푸쉬 버튼

  CreateWindow(TEXT("button"),TEXT("이진화 감도 조절"),WS_CHILD | WS_VISIBLE |
   BS_PUSHBUTTON ,640,700,200,35,hWnd,(HMENU)2,g_hInst,NULL);//푸쉬 버튼

  CreateWindow(TEXT("button"),TEXT("엣지검출"),WS_CHILD | WS_VISIBLE |
   BS_PUSHBUTTON ,640,800,200,35,hWnd,(HMENU)3,g_hInst,NULL);//푸쉬 버튼

 

  //--------------------------------------------------스크롤 생성-----------------------
  hRed=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_HORZ,
   870,500,400,20,hWnd,(HMENU)ID_SCRRED,g_hInst,NULL);// 레드
  hGreen=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_HORZ,
   870,530,400,20,hWnd,(HMENU)ID_SCRGREEN,g_hInst,NULL);// 그린
  hBlue=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_HORZ,
   870,560,400,20,hWnd,(HMENU)ID_SCRBLUE,g_hInst,NULL);// 블루

  hBrightness=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_HORZ,
   870,700,400,20,hWnd,(HMENU)ID_Brightness,g_hInst,NULL);// 특정색 검출 밝기 콘트롤 스크롤 바 특성

  h_CFIND=CreateWindow(TEXT("scrollbar"),NULL,WS_CHILD | WS_VISIBLE | SBS_HORZ,
   640,540,200,20,hWnd,(HMENU)ID_FIND,g_hInst,NULL);// 특정색 오차범위 스크롤


  SetScrollRange(hRed,SB_CTL,0,255,TRUE);
  SetScrollPos(hRed,SB_CTL,0,TRUE);

  SetScrollRange(hGreen,SB_CTL,0,255,TRUE);
  SetScrollPos(hGreen,SB_CTL,0,TRUE);

  SetScrollRange(hBlue,SB_CTL,0,255,TRUE);
  SetScrollPos(hBlue,SB_CTL,0,TRUE);

  SetScrollRange(hBrightness,SB_CTL,0,255,TRUE);
  SetScrollPos(hBrightness,SB_CTL,65,TRUE);// 명암 밝기 조절 초기값

  SetScrollRange(h_CFIND,SB_CTL,0,255,TRUE);//특정색 오차범위 스크롤 범위
  SetScrollPos(h_CFIND,SB_CTL,40,TRUE);//특정색 오차범위 스크롤 초기값

 

  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_COMMAND:
  switch (LOWORD(wParam))
  {
  case 0:
   {
    flag_menu=0;
    break;
   }
  case 1:
   {
    flag_menu=1;  
    break;
   }
  case 2:
   {  
    flag_menu=2;
    break;
   }
  case 3:
   {
    flag_menu=3;
    break;
   }
  }

 case WM_HSCROLL:
  if ((HWND)lParam == hRed) TempPos = Red;
  if ((HWND)lParam == hGreen) TempPos = Green;
  if ((HWND)lParam == hBlue) TempPos = Blue;
  if ((HWND)lParam == h_CFIND) TempPos = FIND;
  if ((HWND)lParam == hBrightness) TempPos = Brightness;

  switch (LOWORD(wParam)) {
 case SB_LINELEFT:
  TempPos=max(0,TempPos-1);
  break;
 case SB_LINERIGHT:
  TempPos=min(255,TempPos+1);
  break;
 case SB_PAGELEFT:
  TempPos=max(0,TempPos-10);
  break;
 case SB_PAGERIGHT:
  TempPos=min(255,TempPos+10);
  break;
 case SB_THUMBTRACK:
  TempPos=HIWORD(wParam);
  break;
  }
  if ((HWND)lParam == hRed) Red=TempPos;
  if ((HWND)lParam == hGreen) Green=TempPos;
  if ((HWND)lParam == hBlue) Blue=TempPos;
  if ((HWND)lParam == h_CFIND) FIND=TempPos;
  if ((HWND)lParam == hBrightness) Brightness=TempPos;

  SetScrollPos((HWND)lParam,SB_CTL,TempPos,TRUE);
  InvalidateRect(hWnd,&rect2,TRUE);

 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  MyBrush=CreateSolidBrush(RGB(Red,Green,Blue));
  GAP=FIND;
  i=Brightness;
  TextOut(hdc,650,570,TEXT("특정색 감도 허용오차 범위"),14);
  TextOut(hdc,855,500,TEXT("R"),2);
  TextOut(hdc,855,530,TEXT("G"),2);
  TextOut(hdc,855,560,TEXT("B"),2);
  TextOut(hdc,500,610,TEXT("찾고자 하는색"),7);
  OldBrush=(HBRUSH)SelectObject(hdc,MyBrush);
  Rectangle(hdc,500,500,600,600);
  SelectObject(hdc,OldBrush);
  DeleteObject(MyBrush);
  EndPaint(hWnd,&ps);
  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;

 

 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]));


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

 }

 Jump=0;

 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(flag_menu==0)//특정색 검출------------------------------------------------------------------------------------
   { 
    if((VideoHdr->lpData[Jump+2])>Red-GAP && (VideoHdr->lpData[Jump+2])<Red+GAP  // GAP특정색 검출 오차 범위
     && (VideoHdr->lpData[Jump+1])>Green-GAP && (VideoHdr->lpData[Jump+1])<Green+GAP
     && (VideoHdr->lpData[Jump])>Blue-GAP && (VideoHdr->lpData[Jump])<Blue+GAP) //특정 밝기 이상이면==> 흰색검출
     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]));

   }

   else if(flag_menu==1)// 이진화-------------------------------------------------------------------------------
   {
    if((VideoHdr->lpData[Jump+2])>Red-GAP && (VideoHdr->lpData[Jump+2])<Red+GAP  // GAP특정색 검출 오차 범위
     && (VideoHdr->lpData[Jump+1])>Green-GAP && (VideoHdr->lpData[Jump+1])<Green+GAP
     && (VideoHdr->lpData[Jump])>Blue-GAP && (VideoHdr->lpData[Jump])<Blue+GAP) //특정 밝기 이상이면==> 흰색검출
     SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1
     ,RGB(VideoHdr->lpData[Jump+2], VideoHdr->lpData[Jump+1], VideoHdr->lpData[Jump]));


    else
     SetPixel(hMemDC,iCntX,(bm.bmiHeader.biHeight - iCntY)-1
     ,RGB(255,255,255));

   }
   else if(flag_menu==2)// 이진화2 감도 조절 가능--------------------------------------------------------------------
   {
    if(VideoHdr->lpData[Jump]>i && VideoHdr->lpData[Jump]>i && VideoHdr->lpData[Jump]>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));// 검은점
   }
   //---------------------------------------------------------------에지검출 3--------------------------------------------
   else if(flag_menu==3)
   {
    for(iCntY =0; iCntY<bm.bmiHeader.biHeight; ++iCntY)
    {
     for(iCntX=0;iCntX<bm.bmiHeader.biWidth;++iCntX)
     {

      if(VideoHdr->lpData[Jump+j]>i && VideoHdr->lpData[Jump+j]>i && VideoHdr->lpData[Jump+j]>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));// 검은 점 한번 찍고
       SetPixel(hMemDC,iCntX+1,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(0,0,0));// 검은 점 한번 찍고
       flag=1;
       if(flag=1&&VideoHdr->lpData[Jump]<i && VideoHdr->lpData[Jump]<i && VideoHdr->lpData[Jump]<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));// 검은 점 한번 찍고
       SetPixel(hMemDC,iCntX+1,(bm.bmiHeader.biHeight - iCntY)-1 ,RGB(0,0,0));// 검은 점 한번 찍고
       flag=0;

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

     }
    }
   }
   //---------------------------------------------------------------------------------------------------------------------------------------------

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

 

 if((flag_menu==0) || (flag_menu==1) || (flag_menu==2) || (flag_menu==3))
 {
  BitBlt(Hdc,640,0
   ,bm.bmiHeader.biWidth
   ,bm.bmiHeader.biHeight
   ,hMemDC
   ,0,0
   ,SRCCOPY);
 } Jump=0;

 

 SelectObject(hMemDC,OldBitmap);

 DeleteDC(hMemDC);

 ReleaseDC(HwndMain,Hdc);

 return 0;
}