📄 图像特征跟踪系统view.cpp
字号:
// 图像特征跟踪系统View.cpp : implementation of the CMyView class
//
#include "stdafx.h"
#include "图像特征跟踪系统.h"
#include "图像特征跟踪系统Doc.h"
#include "图像特征跟踪系统View.h"
#include "DialogTrackerSetting.h"
#include "vfw.h"
#include "MainFrm.h"
#include "ZXDib.h"
#include <mmsystem.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//全局变量声明:
extern CZXDib dib;
extern bool bBufferNotReady; //缓冲区未准备好
extern bool bDispatchMouseMessage;//将鼠标消息发送出去
extern bool bTrackBegin;
extern CMyView *pCurrentView; //当前视类指针
extern CAPSTATUS gCapStatus; //摄像机状态
extern HWND ghWndCap; //捕获窗口句柄
extern CPoint arrpointTrackWindow[];//在捕获窗口内画四边形框
//全局函数声明:
extern bool OpenCamera(RECT rectCaptureWindow);
extern void CloseCamera();
extern void AdjustCamera();
/////////////////////////////////////////////////////////////////////////////
// CMyView
IMPLEMENT_DYNCREATE(CMyView, CScrollView)
BEGIN_MESSAGE_MAP(CMyView, CScrollView)
//{{AFX_MSG_MAP(CMyView)
ON_COMMAND(ID_TRACK_SETTING, OnTrackSetting)
ON_COMMAND(ID_TRACK_BEGIN, OnTrackBegin)
ON_COMMAND(ID_TRACK_STOP, OnTrackStop)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_SET_USB_CAMERA, OnSetUsbCamera)
ON_UPDATE_COMMAND_UI(ID_SET_USB_CAMERA, OnUpdateSetUsbCamera)
ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew)
ON_COMMAND(ID_TRACK_GET_TEMPLATE, OnTrackGetTemplate)
ON_UPDATE_COMMAND_UI(ID_TRACK_GET_TEMPLATE, OnUpdateTrackGetTemplate)
ON_UPDATE_COMMAND_UI(ID_TRACK_BEGIN, OnUpdateTrackBegin)
ON_UPDATE_COMMAND_UI(ID_TRACK_STOP, OnUpdateTrackStop)
ON_WM_RBUTTONDOWN()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyView construction/destruction
CMyView::CMyView()
{
pBitmapInput = NULL;
pBitmapTarget=
pBitmapTarget_SecondLevel=
pBitmapTemplate =
pEigenSpace =
pEigenSpace_SecondLevel =NULL;
pDisplayBitmapInputBuffer = NULL; //输入图像显示缓冲区
pBMIBitmapInputBuffer = NULL; //输入图像BMP信息结构
pDisplayBitmapTemplateBuffer = NULL; //模板图像显示缓冲区
pBMIBitmapTemplateBuffer = NULL; //模板图像BMP信息结构
pDisplayBitmapTargetBuffer = NULL; //目标图像显示缓冲区
pBMIBitmapTargetBuffer = NULL; //目标图像BMP信息结构
pBitmapBackGround = NULL;
pBitmapInfoBackGround = NULL;
}
CMyView::~CMyView()
{
if(pBitmapInput) delete pBitmapInput;
if(pBitmapTarget) delete pBitmapTarget;
if(pBitmapTarget_SecondLevel) delete pBitmapTarget_SecondLevel;
if(pBitmapTemplate) delete pBitmapTemplate;
if(pEigenSpace) delete pEigenSpace ;
if(pEigenSpace_SecondLevel) delete pEigenSpace_SecondLevel;
if(pDisplayBitmapInputBuffer) delete pDisplayBitmapInputBuffer; //输入图像显示缓冲区
if(pBMIBitmapInputBuffer) delete pBMIBitmapInputBuffer; //输入图像BMP信息结构
if(pDisplayBitmapTemplateBuffer) delete pDisplayBitmapTemplateBuffer; //模板图像显示缓冲区
if(pBMIBitmapTemplateBuffer) delete pBMIBitmapTemplateBuffer; //模板图像BMP信息结构
if(pDisplayBitmapTargetBuffer) delete pDisplayBitmapTargetBuffer; //目标图像显示缓冲区
if(pBMIBitmapTargetBuffer) delete pBMIBitmapTargetBuffer ; //目标图像BMP信息结构
if(pBitmapBackGround) delete pBitmapBackGround;
if(pBitmapInfoBackGround) delete pBitmapInfoBackGround;
}
/////////////////////////////////////////////////////////////////////////////
// CMyView drawing
BOOL CMyView::DestroyWindow()
{
CloseCamera();
pCurrentView = NULL;
return CScrollView::DestroyWindow();
}
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pDC->SetStretchBltMode(COLORONCOLOR);
if(pDisplayBitmapInputBuffer) //输入图像显示
{
StretchDIBits(pDC->GetSafeHdc(),
rectBitmapInputDisplay.left, rectBitmapInputDisplay.top,
rectBitmapInputDisplay.right-rectBitmapInputDisplay.left, rectBitmapInputDisplay.bottom-rectBitmapInputDisplay.top,
0, 0,
pBMIBitmapInputBuffer->bmiHeader.biWidth,
pBMIBitmapInputBuffer->bmiHeader.biHeight,
pDisplayBitmapInputBuffer,
pBMIBitmapInputBuffer,
DIB_RGB_COLORS,
SRCCOPY);
if(SourceType!=TST_USB_CAMERA)
{
CPen pen(PS_SOLID,1,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->SetROP2(R2_COPYPEN);
pDC->MoveTo(arrpointTrackWindow[0].x+rectBitmapInputDisplay.left,arrpointTrackWindow[0].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[1].x+rectBitmapInputDisplay.left,arrpointTrackWindow[1].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[2].x+rectBitmapInputDisplay.left,arrpointTrackWindow[2].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[3].x+rectBitmapInputDisplay.left,arrpointTrackWindow[3].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[0].x+rectBitmapInputDisplay.left,arrpointTrackWindow[0].y+rectBitmapInputDisplay.top);
}
}
if(pDisplayBitmapTemplateBuffer) //模板图像显示缓冲区
{
StretchDIBits(pDC->GetSafeHdc(),
rectBitmapTemplateDisplay.left,
rectBitmapTemplateDisplay.top,
pBMIBitmapTemplateBuffer->bmiHeader.biWidth,
pBMIBitmapTemplateBuffer->bmiHeader.biHeight,
0, 0,
pBMIBitmapTemplateBuffer->bmiHeader.biWidth,
pBMIBitmapTemplateBuffer->bmiHeader.biHeight,
pDisplayBitmapTemplateBuffer,
pBMIBitmapTemplateBuffer,
DIB_RGB_COLORS,
SRCCOPY);
}
if(pDisplayBitmapTargetBuffer ) //目标图像显示缓冲区
{
StretchDIBits(pDC->GetSafeHdc(),
rectBitmapTargetDisplay.left,
rectBitmapTargetDisplay.top,
pBMIBitmapTargetBuffer->bmiHeader.biWidth,
pBMIBitmapTargetBuffer->bmiHeader.biHeight,
0, 0,
pBMIBitmapTargetBuffer->bmiHeader.biWidth,
pBMIBitmapTargetBuffer->bmiHeader.biHeight,
pDisplayBitmapTargetBuffer,
pBMIBitmapTargetBuffer,
DIB_RGB_COLORS,
SRCCOPY);
}
CSize docSize(rectBitmapTemplateDisplay.right+10,rectBitmapInputDisplay.bottom+10);
SetScrollSizes(MM_TEXT,docSize);
}
void CMyView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
::pCurrentView = this; //将本视的指帧送给全局变量
rectBitmapInputDisplay.left = //输入图像显示区域
rectBitmapInputDisplay.top = //
rectBitmapInputDisplay.right = //
rectBitmapInputDisplay.bottom= 100;//
rectBitmapTemplateDisplay= //模板图像显示区域
rectBitmapTargetDisplay=rectBitmapInputDisplay; //目标图像显示区域
arrpointTrackWindow[0].x=arrpointTrackWindow[1].x=arrpointTrackWindow[2].x=arrpointTrackWindow[3].x=0;
arrpointTrackWindow[0].y=arrpointTrackWindow[1].y=arrpointTrackWindow[2].y=arrpointTrackWindow[3].y=0;
bTrackBegin = false;
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics
#ifdef _DEBUG
void CMyView::AssertValid() const
{
CScrollView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CMyDoc* CMyView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMyView message handlers
void CMyView::OnTrackSetting()
{
CDialogTrackerSetting dlg("跟踪系统设置",this,0);
if(dlg.DoModal()!=IDOK)
return;
BeginWaitCursor();
TrackType = dlg.dlgTrackStyle.m_conTrackType; //跟踪类型
TemplateUpdateType = dlg.dlgTemplateUpdate.m_conTemplateUpdateType;//模板更新方式
SourceType = dlg.dlgSourceChoice.m_conTrackSourceType; //数据源类型
dTemplateUpdatePower = dlg.dlgTemplateUpdate.m_nPowerResult; //模板更新权值
nPyramidLevel = dlg.dlgAlgorithmSettingNew.m_nMaxLevel; //算法采用的金字塔层数
nMaxIterateTimes = dlg.dlgAlgorithmSettingNew.m_nUpdateMaxTimes;//算法采用的最大迭代次数
nTargetHeightSet = dlg.dlgAlgorithmSettingNew.m_nHeight;
nTargetWidthSet = dlg.dlgAlgorithmSettingNew.m_nWidth;
bSetTargetScale = dlg.dlgAlgorithmSettingNew.bSetTargetScale;
dDelt = dlg.dlgAlgorithmSettingNew.m_dDelt; //算法采用的一个控制曲线形状的参数
if(TrackType != TT_AFFINE) //如果不是单纯的仿射模型跟踪,则需要设置特征空间
{
strEigenSapceFilePath = dlg.dlgTrackStyle.m_strEigenSapceFilePath; //特征空间文件路径
nEigenSpaceSelectVector = dlg.dlgTrackStyle.m_nEigenSpaceVectorNumber; //选用的特征空间维数
if(pEigenSpace) delete pEigenSpace; //装入底层特征空间:
pEigenSpace = NULL;
if(TrackType==TT_SVD_AFFINE)
{
if(!dib.LoadEigenSpaceFromVCRFile(strEigenSapceFilePath,dwTargetHeight,dwTargetWidth,nEigenSpaceTotalVector,nEigenSpaceSelectVector,pEigenSpace))
return ;
} else
{
if(!dib.LoadEigenSpaceFromVCRFile(strEigenSapceFilePath,dwTargetHeight,dwTargetWidth,nEigenSpaceTotalVector,nEigenSpaceSelectVector+1,pEigenSpace))
return ;
}
//装入第二层特征空间:
if(pEigenSpace_SecondLevel) delete pEigenSpace_SecondLevel;
pEigenSpace_SecondLevel = NULL;
if(nPyramidLevel==2)
{
DWORD dwHeight,dwWidth;
CString strTempFilePath = strEigenSapceFilePath;
int position = strTempFilePath.Find(".voc");
bool bKL = false;
if(position<=0)
{
position = strTempFilePath.Find(".kl");
if(position<=0)
{
AfxMessageBox("没有抽层后的特征空间!");
return;
}
bKL = true;
}
if(bKL) nEigenSpaceSelectVector++;
strTempFilePath.SetAt(position-1,'1');
if(!dib.LoadEigenSpaceFromVCRFile(strTempFilePath,dwHeight,dwWidth,nEigenSpaceTotalVector,nEigenSpaceSelectVector,pEigenSpace_SecondLevel))
return ;
if(bKL) nEigenSpaceSelectVector--;
}
}
if(ghWndCap) CloseCamera();
ghWndCap = 0;
if(pDisplayBitmapInputBuffer) delete pDisplayBitmapInputBuffer; pDisplayBitmapInputBuffer = NULL;
arrpointTrackWindow[0].x = arrpointTrackWindow[1].x = arrpointTrackWindow[2].x = arrpointTrackWindow[3].x = 0;
arrpointTrackWindow[0].y = arrpointTrackWindow[1].y = arrpointTrackWindow[2].y = arrpointTrackWindow[3].y = 0;
if(SourceType!=TST_USB_CAMERA) //如果不是从USB摄像头输入数据
{
strInputBitmapFilePath = dlg.dlgSourceChoice.m_strInputFilePath; //输入磁盘图像文件路径
nInputBitmapFileNumber = dlg.dlgSourceChoice.m_nInputFileNumber; //输入磁盘图像文件总数
WORD flag;
BYTE *pTemp=NULL;
if(!dib.LoadVectorFromBMPFile(strInputBitmapFilePath,pTemp,dwBitmapInputHeight,dwBitmapInputWidth,flag))
return ;
dib.TranslateVectorToBitmap(dwBitmapInputHeight,dwBitmapInputWidth,pTemp,pDisplayBitmapInputBuffer,flag);
dib.CreateBITMAPINFO(pBMIBitmapInputBuffer,dwBitmapInputHeight,dwBitmapInputWidth,flag);
DWORD i,j=dwBitmapInputHeight*dwBitmapInputWidth;
if(pBitmapInput) delete pBitmapInput;
pBitmapInput = new double [j];
for(i=0;i<j;i++)
pBitmapInput[i] = pTemp[i];
delete pTemp;
}
else
{ //如果是由摄像头输入,则初始化摄像头
if(!OpenCamera(rectBitmapInputDisplay))
return;
bBufferNotReady = true;
dwBitmapInputWidth = gCapStatus.uiImageWidth;
dwBitmapInputHeight= gCapStatus.uiImageHeight;
if(pBitmapInput) delete pBitmapInput;
pBitmapInput = new double [dwBitmapInputWidth*dwBitmapInputHeight];
bDispatchMouseMessage=true;
arrpointTrackWindow[0].x=arrpointTrackWindow[0].y=arrpointTrackWindow[1].x=arrpointTrackWindow[1].y=arrpointTrackWindow[2].x=arrpointTrackWindow[2].y=arrpointTrackWindow[3].x=arrpointTrackWindow[3].y=0;
//防止显示缓冲区中的脏数据
if(pDisplayBitmapInputBuffer) delete pDisplayBitmapInputBuffer;
pDisplayBitmapInputBuffer = NULL;
}
//设置输出路径:
if(bSaveResultFile = dlg.dlgOutputSetting.m_bOutputResultImage)
strOutputResultFilePath = dlg.dlgOutputSetting.m_strOutputResultImageFilePath; //结果输出文件路径名
else
strOutputResultFilePath = "";
if(bSaveTargetFile = dlg.dlgOutputSetting.m_nOutputTargetImage)
strOutputTargetFilePath = dlg.dlgOutputSetting.m_strOutputTargetImageFilePath; //目标输出文件路径名
else
strOutputTargetFilePath = "";
//设置目标显示区:
rectBitmapInputDisplay.right = rectBitmapInputDisplay.left + dwBitmapInputWidth; //
rectBitmapInputDisplay.bottom= rectBitmapInputDisplay.top + dwBitmapInputHeight;
rectBitmapTargetDisplay.left = rectBitmapInputDisplay.left+dwBitmapInputWidth+30;
rectBitmapTargetDisplay.top = rectBitmapInputDisplay.top;
EndWaitCursor();
Invalidate(true);
}
///////////////////////////////////////////////////////
// 鼠标响应函数
bool bMouseDown = false;
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
RECT rect;
GetClientRect(&rect);
if(point.x>1 && point.x<rect.right-1 && point.y>1 && point.y<rect.bottom-1)
bDispatchMouseMessage = true;
else
{ bDispatchMouseMessage = false; ReleaseCapture();}
if(!bMouseDown) return;
CPoint point_original = GetScrollPosition();
point+= point_original;
if(point.x>rectBitmapInputDisplay.left+1 && point.y>rectBitmapInputDisplay.top+1 && point.x<dwBitmapInputWidth+rectBitmapInputDisplay.left-1 && point.y<dwBitmapInputHeight+rectBitmapInputDisplay.top-1)
{
if(SourceType!=TST_USB_CAMERA)
{
CDC* pDC = GetDC();
CPen pen(PS_SOLID,1,RGB(255,0,0));
pDC->SelectObject(&pen);
pDC->SetROP2(R2_NOTXORPEN);
pDC->MoveTo(arrpointTrackWindow[0].x+rectBitmapInputDisplay.left,arrpointTrackWindow[0].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[1].x+rectBitmapInputDisplay.left,arrpointTrackWindow[1].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[2].x+rectBitmapInputDisplay.left,arrpointTrackWindow[2].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[3].x+rectBitmapInputDisplay.left,arrpointTrackWindow[3].y+rectBitmapInputDisplay.top);
pDC->LineTo(arrpointTrackWindow[0].x+rectBitmapInputDisplay.left,arrpointTrackWindow[0].y+rectBitmapInputDisplay.top);
pDC->LineTo(point.x,arrpointTrackWindow[1].y+rectBitmapInputDisplay.top);
pDC->LineTo(point.x,point.y);
pDC->LineTo(arrpointTrackWindow[3].x+rectBitmapInputDisplay.left,point.y);
pDC->LineTo(arrpointTrackWindow[0].x+rectBitmapInputDisplay.left,arrpointTrackWindow[0].y+rectBitmapInputDisplay.top);
}
arrpointTrackWindow[1].x=arrpointTrackWindow[2].x=point.x-rectBitmapInputDisplay.left;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -