?? childview.cpp
字號:
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "Tracker.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "ChildView.h"
#include "TrackDlg.h"
#include <math.h>
#include <list>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
typedef struct QSEG_ {
POINT head;
UINT length;
} QSEG, *LPQSEG;
// CChildView
BYTE CChildView::bThreshold = 250;
DWORD CChildView::dwRectangle = 0;
DWORD CChildView::dwSegment = 0;
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_COMMAND(ID_DEVICE_REFRESH, OnDeviceRefresh)
ON_COMMAND_RANGE(ID_DEVICE_NAME, ID_DEVICE_NAME+CVideoCapWnd::m_dwDeviceMax, OnDeviceName)
ON_COMMAND(ID_CAPTURE_SOURCE, OnCaptureSource)
ON_COMMAND(ID_CAPTURE_FORMAT, OnCaptureFormat)
ON_COMMAND(ID_CAPTURE_DISPLAY, OnCaptureDisplay)
ON_WM_SIZE()
ON_COMMAND_RANGE(ID_CAPTURE_100, ID_CAPTURE_200, OnCaptureZoom)
ON_COMMAND(ID_TRACK_BRIGHTNESS, OnTrackBrightness)
ON_COMMAND(ID_TRACK_STOP, OnTrackStop)
ON_COMMAND(ID_CAPTURE_STOP, OnCaptureStop)
END_MESSAGE_MAP()
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
}
void CChildView::OnDeviceRefresh()
{
/* -- Get device menu. --*/
CMenu *mDev = AfxGetMainWnd()->GetMenu()->GetSubMenu(3);
MENUITEMINFO miInfo;
do
{
/* -- Find position of separator. -- */
miInfo.cbSize = sizeof(MENUITEMINFO);
miInfo.fMask = MIIM_TYPE;
mDev->GetMenuItemInfo(0, &miInfo, TRUE);
/* -- Delete all entries before separator. -- */
if (miInfo.fType != MFT_SEPARATOR) {
mDev->DeleteMenu(0, MF_BYPOSITION);
}
} while (miInfo.fType != MFT_SEPARATOR);
/* -- Put device names before separator. -- */
CString strDevName, strDevVer;
for (DWORD i=0; i<m_theVideoCapWnd.m_dwDeviceMax; ++i) {
m_theVideoCapWnd.GetDriverDescription(i, strDevName, strDevVer);
if (strDevName.GetLength()) {
mDev->InsertMenu(0, MF_BYPOSITION, ID_DEVICE_NAME+i, strDevName);
}
}
}
void CChildView::OnDeviceName(UINT nID)
{
/* -- Get device index by subtracting the offset. -- */
nID = nID - ID_DEVICE_NAME;
CString strErr;
/* -- Create the capture window if we haven't done do. -- */
if (m_theVideoCapWnd.m_hWnd == NULL) {
m_theVideoCapWnd.CreateCaptureWindow(CString(""), WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, 0);
if (m_theVideoCapWnd.m_hWnd == NULL) {
strErr.LoadString(IDS_ERR_CAPWND);
MessageBox(strErr);
return;
}
}
/* -- Attempt to connect to driver. -- */
if (m_theVideoCapWnd.DriverConnect(nID) == FALSE) {
strErr.LoadString(IDS_ERR_CONNECT);
MessageBox(strErr);
return;
}
/* -- Retrieve device parameters. -- */
CAPTUREPARMS capParms;
if (m_theVideoCapWnd.CaptureGetSetup(&capParms, sizeof(CAPTUREPARMS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETSETUP);
MessageBox(strErr);
return;
}
/* -- Want separate thread. -- */
capParms.fYield = TRUE;
/* -- Do not abort when left mouse button is clicked. -- */
capParms.fAbortLeftMouse = FALSE;
/* -- Do not abort when right mouse button is clicked. -- */
capParms.fAbortRightMouse = FALSE;
/* -- Update device parameters. -- */
if (m_theVideoCapWnd.CaptureSetSetup(&capParms, sizeof(CAPTUREPARMS)) == FALSE) {
strErr.LoadString(IDS_ERR_SETSETUP);
MessageBox(strErr);
return;
}
/* -- Get current state of capture window. -- */
CAPSTATUS capStat;
if (m_theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETSTAT);
MessageBox(strErr);
return;
}
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, capStat.uiImageWidth, capStat.uiImageHeight, SWP_NOMOVE | SWP_NOZORDER);
GetParentFrame()->SetWindowPos(NULL, 0, 0, capStat.uiImageWidth, capStat.uiImageHeight, SWP_NOMOVE);
/* -- Set preview rate. -- */
if (m_theVideoCapWnd.PreviewRate(33) == FALSE) {
strErr.LoadString(IDS_ERR_PREVRATE);
MessageBox(strErr);
return;
}
/* -- Turn on scaling. -- */
if (m_theVideoCapWnd.PreviewScale(TRUE) == FALSE) {
strErr.LoadString(IDS_ERR_PREVSCALE);
MessageBox(strErr);
return;
}
/* -- Start preview. -- */
if (m_theVideoCapWnd.Preview(TRUE) == FALSE) {
strErr.LoadString(IDS_ERR_PREV);
MessageBox(strErr);
return;
}
}
void CChildView::OnCaptureSource()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video source dialog. -- */
if (capCap.fHasDlgVideoSource) {
if (m_theVideoCapWnd.DlgVideoSource() == FALSE) {
strErr.LoadString(IDS_ERR_SOURCE);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video source dialog.";
MessageBox(strErr);
}
}
void CChildView::OnCaptureFormat()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video format dialog. -- */
if (capCap.fHasDlgVideoFormat) {
if (m_theVideoCapWnd.DlgVideoFormat() == FALSE) {
strErr.LoadString(IDS_ERR_FORMAT);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video format dialog.";
MessageBox(strErr);
}
}
void CChildView::OnCaptureDisplay()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video display dialog. -- */
if (capCap.fHasDlgVideoDisplay) {
if (m_theVideoCapWnd.DlgVideoDisplay() == FALSE) {
strErr.LoadString(IDS_ERR_DISPLAY);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video display dialog.";
MessageBox(strErr);
}
}
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
/* -- Centralize the video capture window. -- */
if (m_theVideoCapWnd.m_hWnd != NULL) {
CRect paRect, cpRect;
GetClientRect(&paRect);
m_theVideoCapWnd.GetClientRect(&cpRect);
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, paRect.Width(), paRect.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
else {
/* -- Resize the child window. -- */
GetParentFrame()->SetWindowPos(NULL, 0, 0, 200, 200, SWP_NOMOVE);
}
}
void CChildView::OnCaptureZoom(UINT nID)
{
if (m_theVideoCapWnd.m_hWnd != NULL) {
/* -- Get current state of capture window. -- */
CAPSTATUS capStat;
if (m_theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS))) {
UINT nZoom = nID - ID_CAPTURE_100 + 1;
UINT nWidth = capStat.uiImageWidth * nZoom;
UINT nHeight = capStat.uiImageHeight * nZoom;
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, nWidth, nHeight, SWP_NOMOVE | SWP_NOZORDER);
CMDIChildWnd *pChild = DYNAMIC_DOWNCAST(CMDIChildWnd, GetParentFrame());
pChild->MDIRestore();
GetParentFrame()->SetWindowPos(NULL, 0, 0, nWidth, nHeight, SWP_NOMOVE);
}
else {
CString strErr;
strErr.LoadString(IDS_ERR_GETSTAT);
MessageBox(strErr);
}
}
}
LRESULT CChildView::FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVideoHdr)
{
CVideoCapWnd theVideoCapWnd;
CAPSTATUS capStat;
theVideoCapWnd.Attach(hWnd);
if (theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS))) {
UINT nWidth = capStat.uiImageWidth;
UINT nHeight = capStat.uiImageHeight;
LPBYTE lpData = lpVideoHdr->lpData;
ASSERT(lpVideoHdr->dwBytesUsed == nWidth * nHeight * 3);
if (dwRectangle)
{
BYTE Y; int index; bool init = false;
/* -- Variables used by simple tracking algorithm. -- */
POINT pTop, pBottom, pLeft, pRight;
for (int i=0; i<nHeight; ++i) {
for (int j=0; j<nWidth; ++j) {
index = 3*(i*nWidth+j);
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] + 0.114*lpData[index] + 0.5);
if (Y > bThreshold) {
if (init) {
if (pLeft.x > j) {
pLeft.x = j;
pLeft.y = i;
}
if (pRight.x < j) {
pRight.x = j;
pRight.y = i;
}
pBottom.x = j;
pBottom.y = i;
}
else {
pTop.x = pBottom.x = pLeft.x = pRight.x = j;
pTop.y = pBottom.y = pLeft.y = pRight.y = i;
init = true;
}
}
}
}
/* -- Data regarding object being tracked stored, do something simple about it. -- */
if (init) {
for (int i=pLeft.x; i<=pRight.x; ++i) {
// -- For pTop.y and pBottom.y --
index = 3*((pTop.y)*nWidth + i);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((pBottom.y)*nWidth + i);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
for (int i=pTop.y; i<=pBottom.y; ++i) {
// -- For pLeft.x and pRight.x --
index = 3*((i)*nWidth + pLeft.x);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((i)*nWidth + pRight.x);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
}
}
else if (dwSegment)
{
BYTE Y; int index;
/* -- Variables used by the new tracking algorithm. -- */
QSEG segment;
std::list<QSEG> object;
for (int i=0; i<nHeight; ++i) {
segment.length = 0;
for (int j=0; j<nWidth; ++j) {
index = 3*(i*nWidth+j);
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] + 0.114*lpData[index] + 0.5);
if (Y > bThreshold) {
if (segment.length == 0) {
segment.head.x = j;
segment.head.y = i;
}
++segment.length;
}
}
if (segment.length) {
object.push_back(segment);
}
}
/* -- Data regarding object being tracked stored, do something simple about it. -- */
for (std::list<QSEG>::iterator i=object.begin(); i!=object.end(); ++i) {
index = 3*((*i).head.y*nWidth + (*i).head.x);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((*i).head.y*nWidth + (*i).head.x + (*i).length);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
}
}
theVideoCapWnd.Detach();
return 0;
}
void CChildView::OnTrackBrightness()
{
// TODO: Add your command handler code here
CTrackDlg dlg;
if (dlg.DoModal()) {
bThreshold = atoi(dlg.m_strBrightness);
if (dlg.m_blRectangle == BST_CHECKED) {
dwRectangle = 1;
dwSegment = 0;
}
else if (dlg.m_blSegment == BST_CHECKED) {
dwRectangle = 0;
dwSegment = 1;
}
else {
dwRectangle = 0;
dwSegment = 0;
}
m_theVideoCapWnd.SetCallbackOnFrame(FrameCallbackProc);
}
}
void CChildView::OnTrackStop()
{
// TODO: Add your command handler code here
m_theVideoCapWnd.SetCallbackOnFrame((FrameCallback)(NULL));
}
void CChildView::OnCaptureStop()
{
// TODO: Add your command handler code here
m_theVideoCapWnd.DriverDisconnect();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -