⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 图像特征跟踪系统view.cpp

📁 利用web camera对目标进行特征跟踪的程序 对于初学机器视觉的有些帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 图像特征跟踪系统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 + -