#include <windows.h>
#include "vfw.h"
#include <alloc.h>
#pragma comment(lib,"vfw32.lib")
/*
#define ID_HISTOGRAM 101
#define ID_CAPTURE 102
#define ID_GRAY 103
#define ID_FIX 104
#define ID_BINARY 105
#define ID_CUT 106
#define ID_EDGE 107
#define ID_SCROLL 201
*/
#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(30,100,230));
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;
}
//=---------------------------------------// 라벨링
else if(flag_menu==4)
{
/*
typedef struct _dnode// 이중 연결리스트 앞뒤 노드생성
{
int key;
struct _dnode *prev;
struct _dnode *next;
} dnode;
// --------------------- 헤더와 테일의 생성
dnode *head, *tail;
void init_dlist(void)
{
head = (dnode*)malloc(sizeof(dnode));
tail = (dnode*)malloc(sizeof(dnode));
head->next = tail;
head->prev = head;
tail->next = tail;
tail->prev = head;
}
dnode *find_dnode(int k)
{
dnode *s;
s = head->next;
while (s->key != k && s != tail)
s = s->next;
return s;
}
//---------------------------- 노드의 삭제----------------------------------------------
int delete_dnode(int k)
{
dnode *s;
s = find_dnode(k);
if (s != tail) // if find
{
s->prev->next = s->next;
s->next->prev = s->prev;
free(s);
return 1;
}
return 0;
}
//--------------노드의 삽입-------------------------------------------------
//인자노드를 가리키는 포인터 t와 정수 k 를 입력받아 t앞의 k를 가지는 노드 삽입
dnode *insert_dnode(int k, int t) // insert k, before t
{
dnode *s;
dnode *i = NULL;
s = find_dnode(t);
if (s != tail) // if find
{
i = (dnode*)malloc(sizeof(dnode));
i->key = k;
s->prev->next = i;
i->prev = s->prev;
s->prev = i;
i->next = s;
}
return i;
}
dnode *ordered_insert(int k)
{
dnode *s;
dnode *i;
s = head->next;
while (s->key <= k && s != tail)
s = s->next;
i = (dnode*)malloc(sizeof(dnode));
i->key = k;
s->prev->next = i;
i->prev = s->prev;
s->prev = i;
i->next = s;
return i;
}
int delete_dnode_ptr(dnode *p)
{
if (p == head || p == tail)
return 0;
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
return 1;
}
dnode *insert_dnode_ptr(int k, dnode *t) // insert k, before t //t 앞에 k를 삽입
{
dnode *i;
if (t == head)
return NULL;
i = (dnode*)malloc(sizeof(dnode));
i->key = k;
t->prev->next = i;
i->prev = t->prev;
t->prev = i;
i->next = t;
return i;
}
void print_dlist(dnode *p)
{
printf("\n");
while (p != tail)
{
printf("%-8d", p->key);
p = p->next;
}
}
void delete_all(void)
{
dnode *p;
dnode *s;
p = head->next;
while (p != tail)
{
s = p;
p = p->next;
free(s);
}
head->next = tail;
tail->prev = head;
}
void main(void)
{
dnode *t;
init_dlist();
ordered_insert(10);
ordered_insert(5);
ordered_insert(8);
ordered_insert(3);
ordered_insert(1);
ordered_insert(7);
ordered_insert(8);
printf("\nInitial Linked list is ");
print_dlist(head->next);
printf("\nFinding 4 is %ssuccessful", find_dnode(4) == tail ? "un" : "");
t = find_dnode(5);
printf("\nFinding 5 is %ssuccessful", t == tail ? "un" : "");
printf("\nInserting 7 before 5");
insert_dnode_ptr(7, t);
print_dlist(head->next);
t = find_dnode(3);
printf("\nDeleting 3 ");
delete_dnode_ptr(t);
print_dlist(head->next);
printf("\nInserting node 2 before 10");
insert_dnode(2, 10);
print_dlist(head->next);
printf("\nDeleting node 2");
if (!delete_dnode(2))
printf("\n deleting 2 is unsuccessful");
print_dlist(head->next);
printf("\nDeleting node 1");
delete_dnode(1);
print_dlist(head->next);
printf("\nInserting 15 at first");
insert_dnode_ptr(15, head->next);
print_dlist(head->next);
printf("\nDeleting all node");
delete_all();
print_dlist(head->next);
}*/
//자료구조 뿌리를 먼저타는 나무구조
typedef struct _node
{
int key;
struct _node *left;
struct _node *right;
} node;
node *head, *tail;
#define MAX 100
node *stack[MAX];
int top;
void init_stack(void)
{
top = -1;
}
node *push(node *t)
{
if (top >= MAX - 1)
{
printf("\n Stack overflow.");
return NULL;
}
stack[++top] = t;
return t;
}
node *pop(void)
{
if (top < 0)
{
printf("\n Stack underflow.");
return NULL;
}
return stack[top--];
}
int is_stack_empty(void)
{
return (top == -1);
}
node *queue[MAX];
int front, rear;
void init_queue(void)
{
front = rear = 0;
}
node *put(node *k)
{
if ((rear + 1) % MAX == front) /* queue is full */
{
printf("\n Queue overflow.");
return NULL;
}
queue[rear] = k;
rear = ++rear % MAX;
return k;
}
node *get(void)
{
node *i;
if (front == rear) /* queue is empty */
{
printf("\n Queue underflow.");
return NULL;
}
i = queue[front];
front = ++front % MAX;
return i;
}
int is_queue_empty(void)
{
return (front == rear);
}
void init_tree(void)
{
head = (node*)malloc(sizeof(node));
tail = (node*)malloc(sizeof(node));
head->left = tail;
head->right = tail;
tail->left = tail;
tail->right = tail;
}
int is_operator(int k)
{
return (k == '+' || k == '-' || k == '*' || k == '/');
}
node *make_parse_tree(char *p)
{
node *t;
while (*p)
{
while (*p == ' ')
p++;
t = (node*)malloc(sizeof(node));
t->key = *p;
t->left = tail;
t->right = tail;
if (is_operator(*p))
{
t->right = pop();
t->left = pop();
}
push(t);
p++;
}
return pop();
}
int is_legal(char *s)
{
int f = 0;
while (*s)
{
while (*s == ' ') /* remove space */
s++;
if (is_operator(*s))
f--;
else
f++;
if (f < 1) break; /* check situation like A + B */
s++;
}
return (f == 1); /* legal if valuable - operator == 1 */
}
void visit(node *t)
{
printf("%c ", t->key);
}
void preorder_traverse(node *t)
{
if (t != tail)
{
visit(t);
preorder_traverse(t->left);
preorder_traverse(t->right);
}
}
void main(void)
{
char post[256];
init_stack();
init_queue();
init_tree();
while (1)
{
printf("\n\nInput Postfix expression -> ");
gets(post);
if (*post == NULL)
{
printf("\n Program ends...");
exit(0);
}
if (!is_legal(post))
{
printf("\nExpression is not legal.");
continue;
}
head->right = make_parse_tree(post);
printf("\nPreorder traverse -> ");
preorder_traverse(head->right);
printf("\nInorder traverse -> ");
inorder_traverse(head->right);
printf("\nPostorder traverse -> ");
postorder_traverse(head->right);
printf("\nLevelorder traverse -> ");
levelorder_traverse(head->right);
}
}
}
}
Jump += 3;// 색상 배열 3개의 요소 건넘뜀
}
}
}*/
// 점찍기 (핸들 , x좌표,y좌표 red , green ,blue)
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;
}