영상처리 (특정색 검출 + 이진화 + 엣지 검출)
#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;
}