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

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

📁 利用web camera对目标进行特征跟踪的程序 对于初学机器视觉的有些帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		arrpointTrackWindow[3].y=arrpointTrackWindow[2].y=point.y-rectBitmapInputDisplay.top;
	}
	CScrollView::OnMouseMove(nFlags, point);
}
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	bMouseDown = true;

	RECT rect;
	GetClientRect(&rect);

	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)
	{
		arrpointTrackWindow[1].x = arrpointTrackWindow[2].x = arrpointTrackWindow[3].x=arrpointTrackWindow[0].x=point.x-rectBitmapInputDisplay.left;
		arrpointTrackWindow[1].y = arrpointTrackWindow[2].y = arrpointTrackWindow[3].y=arrpointTrackWindow[0].y= point.y-rectBitmapInputDisplay.top;
	}
	
	CScrollView::OnLButtonDown(nFlags, point);
}

void CMyView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	bMouseDown = false;

	RECT rect;
	GetClientRect(&rect);

	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)
	{
		arrpointTrackWindow[1].x=arrpointTrackWindow[2].x=point.x-rectBitmapInputDisplay.left;
		arrpointTrackWindow[3].y=arrpointTrackWindow[2].y=point.y-rectBitmapInputDisplay.top;
	}
	::ClipCursor(NULL);

	CScrollView::OnLButtonUp(nFlags, point);
}
void CMyView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	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;
    Invalidate(true);	
	CScrollView::OnRButtonDown(nFlags, point);
}
//////////////////////////////////////////////////////
// 设置摄像头菜单菜单项
void CMyView::OnSetUsbCamera() 
{
	AdjustCamera();
	BeginWaitCursor();
	CloseCamera();
	POINT point;
	point.x = point.y = 0;
	ScrollToPosition(point);
	rectBitmapInputDisplay.right = rectBitmapInputDisplay.left;
	rectBitmapInputDisplay.bottom = rectBitmapInputDisplay.top;
	OpenCamera(rectBitmapInputDisplay);
	
	//初始化
	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;

	rectBitmapInputDisplay.right = rectBitmapInputDisplay.left + dwBitmapInputWidth;
	rectBitmapInputDisplay.bottom =rectBitmapInputDisplay.top +  dwBitmapInputHeight;

	rectBitmapTargetDisplay.left = rectBitmapInputDisplay.left+dwBitmapInputWidth+30;
	rectBitmapTargetDisplay.top = rectBitmapInputDisplay.top;
	rectBitmapTargetDisplay.left = rectBitmapInputDisplay.left+dwBitmapInputWidth+30;
	rectBitmapTargetDisplay.top = rectBitmapInputDisplay.top;

	if(pDisplayBitmapTargetBuffer) delete pDisplayBitmapTargetBuffer; pDisplayBitmapTargetBuffer = NULL;
	if(pBitmapTemplate) delete pBitmapTemplate; pBitmapTemplate = NULL;
	if(pDisplayBitmapTemplateBuffer) delete pDisplayBitmapTemplateBuffer;pDisplayBitmapTemplateBuffer = NULL;
	if(pBitmapTarget) delete pBitmapTarget; pBitmapTarget = NULL;


	bBufferNotReady = true;
	EndWaitCursor();
	Invalidate(true);	
}
void CMyView::OnUpdateSetUsbCamera(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(ghWndCap!=0);
}
/////////////////////////////////////////////////////
//  在摄像头打开时关闭相应“新建”功能
void CMyView::OnUpdateFileNew(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(ghWndCap==0);
}
//////////////////////////////////////////////////////
//  鼠标截取矩形区域有效性检测:
void CMyView::CheckRectData(CPoint* pPoint)
{
	int temp;
	if(pPoint[0].x>pPoint[2].x)
	{
		temp = pPoint[0].x;
		pPoint[0].x = pPoint[2].x;
		pPoint[2].x = temp;
	}
	if(pPoint[0].y>pPoint[2].y)
	{
		temp = pPoint[0].y;
		pPoint[0].y = pPoint[2].y;
		pPoint[2].y = temp;
	}
	if(pPoint[2].x>dwBitmapInputWidth-1)
		pPoint[2].x = dwBitmapInputWidth-1;
	if(pPoint[2].y>dwBitmapInputHeight-1)
		pPoint[2].y = dwBitmapInputHeight-1;
	
	pPoint[1].x = pPoint[2].x;
	pPoint[1].y = pPoint[0].y;
	pPoint[3].x = pPoint[0].x;
	pPoint[3].y = pPoint[2].y;
}

bool bTemplateButton = true;
bool bTemplateButtonOnce = false;
bool bTrackStopButton = false;
bool bReset = true;
/////////////////////////////////////////////////////
//  获取模板
void CMyView::OnTrackGetTemplate() 
{
    if(ghWndCap)
	{
		bBufferNotReady = true;
		::SendMessage(ghWndCap,WM_CAP_GRAB_FRAME_NOSTOP,0,0L);
	}
	while(ghWndCap&&bBufferNotReady);//如果缓冲区没有准备好
    
	//有效性检测:
	CheckRectData(arrpointTrackWindow);
	if(arrpointTrackWindow[2].x==0 || arrpointTrackWindow[2].y==0)
	{
		AfxMessageBox("请先选定一块区域");
		return;
	}

	DWORD dwWidth = abs(arrpointTrackWindow[1].x-arrpointTrackWindow[0].x);
	DWORD dwHeight = abs(arrpointTrackWindow[1].y-arrpointTrackWindow[2].y);
	
	//从选择框中提取信息:
	if(TrackType == TT_AFFINE)
	{
		dwTargetHeight = dwHeight;
		dwTargetWidth = dwWidth;
	}

	rectBitmapTargetDisplay.right = rectBitmapTargetDisplay.left + dwWidth ;
	rectBitmapTargetDisplay.bottom = rectBitmapTargetDisplay.top + dwHeight ;

	rectBitmapTemplateDisplay.left = rectBitmapTargetDisplay.right + 30 ;
	rectBitmapTemplateDisplay.right = rectBitmapTemplateDisplay.left + dwWidth;
	rectBitmapTemplateDisplay.bottom = rectBitmapTargetDisplay.bottom;
    //到输入图像中截取所选择区域:
	dib.CutRegionFromPicture(pBitmapInput,dwBitmapInputHeight,dwBitmapInputWidth,pBitmapTemplate,arrpointTrackWindow[0].x,arrpointTrackWindow[0].y,arrpointTrackWindow[2].x,arrpointTrackWindow[2].y,8);

	for(DWORD  i=0;i<6;i++)
		a[i] = 0;
	a[0] = (arrpointTrackWindow[0].x+arrpointTrackWindow[2].x)/2;
	a[3] = (arrpointTrackWindow[0].y+arrpointTrackWindow[2].y)/2;

	if(bSetTargetScale && TrackType==TT_AFFINE) 
	{
	   double *pTemp1=NULL;
	   track.ChangeImageSize(pBitmapTemplate,dwTargetWidth,dwTargetHeight,pTemp1,nTargetWidthSet,nTargetHeightSet);
	   delete pBitmapTemplate;
	   pBitmapTemplate = pTemp1;

	   a[1] = (double)dwTargetWidth  / (double)nTargetWidthSet;
	   a[5] = (double)dwTargetHeight / (double)nTargetHeightSet;
	   a[1]--;
	   a[5]--;
	 	
	   dwWidth  = dwTargetWidth  = nTargetWidthSet;
	   dwHeight = dwTargetHeight = nTargetHeightSet;
	}

	BYTE* pTemp=NULL;	
	DWORD j=dwHeight*dwWidth;
	pTemp = new BYTE[j];
	for(i=0;i<j;i++)
		pTemp[i] = (BYTE)(pBitmapTemplate[i]);
	
	dib.TranslateVectorToBitmap(dwHeight,dwWidth,pTemp,pDisplayBitmapTemplateBuffer,8);

	delete pTemp;

	//下面数据与显示有关:
	//如果采用了特征空间,则目标的大小在特征空间中已经给出,由此可以设置显示时的参数了:
	//知道了目标的大小后,就可以设置与显示有关的BMP头信息结构了:
	dib.CreateBITMAPINFO(pBMIBitmapTemplateBuffer,dwHeight,dwWidth,8);  //模板图像BMP信息结构
	dib.CreateBITMAPINFO(pBMIBitmapTargetBuffer,dwTargetHeight,dwTargetWidth,8);    //目标图像BMP信息结构
	dib.CreateBITMAPINFO(pBMIBitmapInputBuffer,dwBitmapInputHeight,dwBitmapInputWidth,8);//输入图像BMP信息结构

	CString str;
	str.Format("目标宽:%d, 高:%d",dwTargetWidth,dwTargetHeight);
	CMainFrame* pMainFrame;
	pMainFrame = (CMainFrame*) AfxGetMainWnd();
	pMainFrame->m_wndStatusBar.SetPaneText(2,str);

	//if(if(SourceType!=TST_USB_CAMERA))
	bTemplateButtonOnce = true;

	bBufferNotReady = true;
	Invalidate(true);
}
void CMyView::OnUpdateTrackGetTemplate(CCmdUI* pCmdUI) 
{
	if(SourceType!=TST_USB_CAMERA)
		pCmdUI->Enable((pBitmapInput || ghWndCap)&& !bTrackBegin && bTemplateButton);
	else
		pCmdUI->Enable((pBitmapInput || ghWndCap)&& (!bTrackBegin));
}
/////////////////////////////////////////////////////
//  跟踪开始
void CMyView::OnTrackBegin() 
{

	if(!pBitmapTemplate) return;

	bTrackBegin = true;
	bTrackStopButton = true;

   //导入到Track对象中:
    if(bReset)
		track.TrackSet(pEigenSpace,pEigenSpace_SecondLevel,
		   nEigenSpaceSelectVector,pBitmapTemplate,
		   dwTargetHeight,dwTargetWidth,
		   dwBitmapInputHeight,dwBitmapInputWidth,
		   dDelt,
		   nPyramidLevel,
		   nMaxIterateTimes,
		   dTemplateUpdatePower,
		   TrackType,
		   TemplateUpdateType,
		   a);
	bReset = false;

	if(TrackType!=TT_AFFINE)	delete pBMIBitmapTemplateBuffer;
	pBMIBitmapTemplateBuffer = NULL;
	dib.CreateBITMAPINFO(pBMIBitmapTemplateBuffer,dwTargetHeight,dwTargetWidth,8);  //模板图像BMP信息结构

	//对于从磁盘输入数据的格式需要在此处引起循环:
   if(SourceType!=TST_USB_CAMERA)
   {
		WORD flag; 
		BYTE *pTemp=NULL;
		for(;(nInputBitmapFileNumber>=0)&&(bTrackBegin);nInputBitmapFileNumber--)
		{
			if(!dib.LoadVectorFromBMPFile(strInputBitmapFilePath,pTemp,dwBitmapInputHeight,dwBitmapInputWidth,flag)) {OnTrackStop(); return;}
			dib.TranslateVectorToBitmap(dwBitmapInputHeight,dwBitmapInputWidth,pTemp,pDisplayBitmapInputBuffer,8);
			DWORD i,j = dwBitmapInputHeight*dwBitmapInputWidth;
			if(pBitmapInput) delete pBitmapInput;
			pBitmapInput = new double [j];
			for(i=0;i<j;i++)
				pBitmapInput[i] = pTemp[i];
			dib.FindNextFileName(strInputBitmapFilePath,1);
			delete pTemp; pTemp=NULL;
			
			if(!Track()) 
			{  OnTrackStop();	return;	}

			MSG message;
			if(::PeekMessage(&message,NULL,0,0,PM_REMOVE) )
			{	::TranslateMessage(&message);
				::DispatchMessage(&message);
	}	}	}

	bBufferNotReady = true;

}	
static int nTrackNo=0;
bool CMyView::Track() //当采用摄像头时,本函数将在摄像头中被调用:
{
	if(!bTrackBegin) return true;

	DWORD time_begin;
    time_begin = timeGetTime();
	if(!track.Track(pBitmapInput))//MatchInCurrentInputImage(pBitmapInput))
		OnTrackStop();
	else 
	{
		track.GetRect(arrpointTrackWindow);
		bool bStop=false;
		int i;
		for(i=0;i<4&&!bStop;i++)
			bStop = arrpointTrackWindow[i].x<0 || arrpointTrackWindow[i].y<0 || arrpointTrackWindow[i].x >dwBitmapInputWidth-1 || arrpointTrackWindow[i].y >dwBitmapInputHeight-1;
		if(bStop)
		{
			for(i=0;i<4;i++)
				arrpointTrackWindow[i].x = arrpointTrackWindow[i].y = 0;
			return false;
		}

		BYTE * pTemp = NULL;
		track.GetTargetBitmap(pTemp);
		dib.TranslateVectorToBitmap(dwTargetHeight,dwTargetWidth,pTemp,pDisplayBitmapTargetBuffer,8);
		track.GetTemplateBitmap(pTemp);
		dib.TranslateVectorToBitmap(dwTargetHeight,dwTargetWidth,pTemp,pDisplayBitmapTemplateBuffer,8);
		Invalidate(false);
	}
	DWORD time_end;
	time_end = ::timeGetTime();

	bBufferNotReady = true ;
	if(ghWndCap)
	{
		bBufferNotReady = true;
		::SendMessage(ghWndCap,WM_CAP_GRAB_FRAME_NOSTOP,0,0L);
	}

	CString str;
	CMainFrame* pMainFrame;
	pMainFrame = (CMainFrame*) AfxGetMainWnd();
	str.Format("速度:  %5u毫秒 ",time_end-time_begin);
	pMainFrame->m_wndStatusBar.SetPaneText(1,str);
	str.Format("   当前跟踪帧数:  %d",nTrackNo++);
	pMainFrame->m_wndStatusBar.SetPaneText(0,str);

	return true;
}
void CMyView::OnUpdateTrackBegin(CCmdUI* pCmdUI) 
{	if(SourceType!=TST_USB_CAMERA)
		pCmdUI->Enable(pBitmapInput&&(!bTrackBegin || bTemplateButtonOnce)&&(!bTrackStopButton));	
	else
		pCmdUI->Enable((pBitmapInput||ghWndCap)&&(!bTrackBegin));}
/////////////////////////////////////////////////////
//  跟踪结束
void CMyView::OnTrackStop() 
{	
	if(!bReset)		nTrackNo = 0;
    bReset = true; 	bTemplateButton=true; bTrackBegin = false; bTrackStopButton =false;
}
void CMyView::OnUpdateTrackStop(CCmdUI* pCmdUI) 
{	pCmdUI->Enable(true);//bTrackStopButton);
}
///////////////////////////////////////////////////////
BOOL CMyView::OnEraseBkgnd(CDC* pDC) 
{
	DWORD dwHeight,dwWidth;
	
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP_DRAGON);
	
	BITMAP stBitmap;
    bmp.GetObject(sizeof(BITMAP),&stBitmap); 
	dwHeight = stBitmap.bmHeight;
	dwWidth = stBitmap.bmWidth;

	CDC cdc;
	cdc.CreateCompatibleDC(pDC);
	cdc.SelectObject(&bmp);

	RECT rect;
	GetClientRect(&rect);

	pDC->SetStretchBltMode(COLORONCOLOR);
	pDC->StretchBlt(0,0,rect.right,rect.bottom,&cdc,0,0,(int)dwWidth,(int)dwHeight,SRCCOPY); 
	cdc.DeleteDC();

	return true;//CScrollView::OnEraseBkgnd(pDC);//
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -