영상에는 알파 값이 존재한다.
일기예보 할 때 기상캐스터에게는 아무것도 보이지 않고 뒤에 하얀색 또는 파란색 칠판만 존재한다.
영상에서 칠판색을 찾아서 비슷한 색들을 다른 영상으로 바꿔서 일기예보 할때 한반도 모양의 지도가 나오는것이다.
우선 우리반 칠판을 찍은 사진을 그림판에 스포이드로 값을 추출해보면
R 161
G 161
B 167 이다 이 3개를 모두 더한뒤 3으로 나누면 칠판의 알파값이 나온다.
159이고 오차값을 정하고 HALPHA, LALPHA 값으로 정한다.
아래의 소스부터 보자. 소스에서 필요 없는 부분은 뺏다
#include <windows.h> #include <Vfw.h> #define XSCALE 320 #define YSCALE 240 #define SPACE 20 #define XGRP 256 #define YGRP 256 // alpha 값 #define MALPHA 160 #define GALPHA 40 ////실제로 사용하는 알파값들 #define HALPHA (MALPHA+GALPHA) #define LALPHA (MALPHA-GALPHA) #define FILENAME TEXT("1.bmp") #define IMGSIZE XSCALE*YSCALE * 3 typedef struct _msgmap { UINT uiMsg; LRESULT(*fp)(HWND, WPARAM, LPARAM); } stMsgMap; LRESULT On_Paint(WPARAM, LPARAM); LRESULT On_Create(WPARAM, LPARAM); LRESULT On_Destroy(WPARAM, LPARAM); LRESULT CALLBACK capture(HWND, LPVIDEOHDR); stMsgMap MsgMap[] = { { WM_PAINT, On_Paint }, { WM_CREATE, On_Create }, { WM_DESTROY, On_Destroy }, { WM_NULL, 0 } }; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BITMAPINFO stBMPInfo; HINSTANCE g_hInst; LPSTR lpszClass = TEXT("VFW ALPHA"); HWND hWnd; HBITMAP HBack; LRESULT On_Create(WPARAM wParam, LPARAM lParam) { HDC hdc; HWND hCamera; BOOL bRet; //절차가있다.윈도우 생성 hCamera = capCreateCaptureWindow(TEXT("samrt") , WS_CHILD | WS_VISIBLE , 0, 0, XSCALE, YSCALE , hWnd, 0); if (NULL == hCamera) //창을 못만들어서 뜨는 에러 { MessageBox(hWnd, TEXT("창을 열수 없음"), TEXT("에러"), MB_OK); } bRet = capDriverConnect(hCamera, 0); //화면을 카메라와 연결한다.(USB장치연결) //0:카메라마다 고유번호 if (FALSE == bRet) //카메라가 없거나 드라이버가 안잡힘. { MessageBox(hWnd, TEXT("카메라가 없음."), TEXT("에러"), MB_OK); } capPreviewRate(hCamera, 1); //화면에 보일 속도 capGetVideoFormat(hCamera, &stBMPInfo, sizeof(stBMPInfo)); //비디오 형식을 bInfo에 저장 stBMPInfo.bmiHeader.biWidth = XSCALE; //가로, 세로 길이 set stBMPInfo.bmiHeader.biHeight = YSCALE; capSetVideoFormat(hCamera, &stBMPInfo, sizeof(stBMPInfo));//bInfo 출력준비 capSetCallbackOnFrame(hCamera, capture);//비디오 라이브러리에서 함수호출 capPreview(hCamera, TRUE); // 영상화면 출력//TRUE:Preview flag hdc = GetDC(hWnd); ReleaseDC(hWnd, hdc); return 0; } LRESULT CALLBACK capture(HWND hWpWnd, LPVIDEOHDR lpVHdr)//구조체 정보가 실려온다. { HDC hdc; HDC MemDC; static BYTE vData[IMGSIZE]; static BYTE BData[IMGSIZE]; UINT iCntX; UINT iCntY; UINT iCal; HANDLE hFile; BITMAPFILEHEADER stBFHead; BITMAPINFOHEADER stBFInfo; BOOL bRet; DWORD dwCnt;
//비트맵 불러오기 hFile = CreateFile(FILENAME, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hFile) { MessageBox(hWnd, L"Open Error", L"ERROR", MB_OK); PostQuitMessage(0); return 0; } bRet = ReadFile(hFile, &stBFHead, sizeof(BITMAPFILEHEADER), &dwCnt, NULL); if (FALSE == bRet) { MessageBox(hWnd, L"File헤더 Read Error", L"ERROR", MB_OK); CloseHandle(hFile); PostQuitMessage(0); return 0; } bRet = ReadFile(hFile, &stBFInfo, sizeof(BITMAPINFOHEADER), &dwCnt, NULL); if (FALSE == bRet) { MessageBox(hWnd, L"Info헤더 Read Error", L"ERROR", MB_OK); CloseHandle(hFile); PostQuitMessage(0); return 0; } bRet = ReadFile(hFile, BData, stBFInfo.biSizeImage, &dwCnt, NULL); if (FALSE == bRet) { MessageBox(hWnd, L"Image Data Read Error", L"ERROR", MB_OK); CloseHandle(hFile); PostQuitMessage(0); return 0; } hdc = GetDC(hWnd); //영상복사 //memcpy(vData, lpVHdr->lpData, lpVHdr->dwBufferLength); for (iCntY = 0; iCntY < YSCALE; ++iCntY) { for (iCntX = 0; iCntX < XSCALE; ++iCntX) { iCal = (3 * (XSCALE * iCntY + iCntX)); vData[iCal + 2] = lpVHdr->lpData[iCal + 2]; vData[iCal + 1] = lpVHdr->lpData[iCal + 1]; vData[iCal + 0] = lpVHdr->lpData[iCal + 0]; if (HALPHA < vData[iCal + 0]) { continue; } if (LALPHA > vData[iCal + 0]) { continue; } if (HALPHA < vData[iCal + 0]) { continue; } if (LALPHA > vData[iCal + 0]) { continue; } if (HALPHA < vData[iCal + 0]) { continue; } if (LALPHA > vData[iCal + 0]) { continue; } vData[iCal + 2] = BData[iCal + 2]; //red vData[iCal + 1] = BData[iCal + 1]; //green vData[iCal + 0] = BData[iCal + 0]; //blue } } StretchDIBits(hdc , XSCALE + SPACE, 0 , XSCALE, YSCALE , 0, 0 , XSCALE, YSCALE , vData, &stBMPInfo, DIB_RGB_COLORS, SRCCOPY); CloseHandle(hFile); ReleaseDC(hWpWnd, hdc); return 0; } |
대체할 화면을 먼저 BData에다가 적재시킨다.
bRet = ReadFile(hFile, BData, stBFInfo.biSizeImage, &dwCnt, NULL);
if (FALSE == bRet)
{
MessageBox(hWnd, L"Image Data Read Error", L"ERROR", MB_OK);
CloseHandle(hFile);
PostQuitMessage(0);
return 0;
}
영상을 복사할때 알파값 사이에 들어가지 않는 부분들은 다걸러낸 다음에 알파값에 해당하는 RGB는 BData로 대체한다
for (iCntY = 0; iCntY < YSCALE; ++iCntY)
{
for (iCntX = 0; iCntX < XSCALE; ++iCntX)
{
iCal = (3 * (XSCALE * iCntY + iCntX));
vData[iCal + 2] = lpVHdr->lpData[iCal + 2];
vData[iCal + 1] = lpVHdr->lpData[iCal + 1];
vData[iCal + 0] = lpVHdr->lpData[iCal + 0];
if (HALPHA < vData[iCal + 0])
{
continue;
}
if (LALPHA > vData[iCal + 0])
{
continue;
} if (HALPHA < vData[iCal + 0])
{
continue;
}
if (LALPHA > vData[iCal + 0])
{
continue;
}
if (HALPHA < vData[iCal + 0])
{
continue;
}
if (LALPHA > vData[iCal + 0])
{
continue;
}
vData[iCal + 2] = BData[iCal + 2]; //red
vData[iCal + 1] = BData[iCal + 1]; //green
vData[iCal + 0] = BData[iCal + 0]; //blue
}
}
아래의 실행화면을 보면 칠판이 원하는 이미지로 대체되어 있는걸 확인할수 있다.
실행화면
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151126 - 강동조 개인업무일지 ARM (6) | 2015.11.26 |
---|---|
20151126 수업 / ARM 어셈블리 - 남수진 (7) | 2015.11.26 |
20151126 - 권오민 - WinAPI 11일차 & ARM ASSEMBLY 1일차 (4) | 2015.11.26 |
20151125_일일업무보고서_박서연_WinAPI(10) (2) | 2015.11.26 |
20151125_주재민_API_10 (6) | 2015.11.26 |
20151125_안향진_API_10 (6) | 2015.11.26 |
20151125 임현수 업무일지 WIN32API #10 영상 밝기 그래프, 알파값 처리 (4) | 2015.11.25 |
2015.11.25_개인업무일지_[Win32API #10]_이량경_알파값 (4) | 2015.11.25 |