📄 图像特征跟踪系统view.cpp
字号:
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 + -