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

📄 templatematch.c

📁 学习跟踪的好程序
💻 C
字号:
 /*****************************************************************************
 * File:	TemplateMatch.c
 * Desc:	functions of Template Match Tracking Algorithm
 * Author:	Xuhui Zhou  @ Carnegie Mellon University
 * Date:	05/20/2004
 *****************************************************************************/

#include "TemplateMatch.h"

IplImage	*gTemplate;		//initialized template image (w*h)
IplImage	*gTrackChannel;	//single channel from current frame (W*H)
IplImage	*gResultImg;		//matching result (W-w+1)*(H-h+1)
IplImage	*gMatchImg;		//matching result with same size of input frame
IplImage	*gImgFgMask;
IplImage	*gImgObjMask;

///////////////////////////////////////////////////////////////////////////////
void temp_TrackCleanUp()
//release memory
{
	//projection image
	cvReleaseImage(&gTemplate);
	cvReleaseImage(&gTrackChannel);	
	cvReleaseImage(&gResultImg);
	cvReleaseImage(&gMatchImg);	
	cvReleaseImage(&gImgFgMask);
	cvReleaseImage(&gImgObjMask);
}

///////////////////////////////////////////////////////////////////////////////
void temp_TrackInit_Coeff(IplImage* inImage, IplImage* inMask, RECT inTargetBox)
//tracker init with box and mask
{	
	int		imgWidth, imgHeight;
	CvRect	templRoi;

	//check whether input is valid
	if (inImage==NULL) return;
	utl_RectCheckBound(&inTargetBox, inImage->width, inImage->height);

	imgWidth	= inImage->width;
	imgHeight	= inImage->height;

	//release memory in case re-initialization
	temp_TrackCleanUp();

	//create track template
	gTemplate	= cvCreateImage(cvSize(imgWidth, imgHeight), 8, 1);
	//create one channel image
	gTrackChannel = cvCreateImage(cvSize(imgWidth, imgHeight), 8, 1);
	//create weight image
	gMatchImg = cvCreateImage(cvSize(imgWidth, imgHeight), 8, 1);
	//create result image
	gResultImg = cvCreateImage(cvSize(imgWidth, imgHeight), 32, 1);
	gImgFgMask = cvCreateImage(cvGetSize(inImage), 8, 1);
	gImgObjMask = cvCreateImage(cvGetSize(inImage), 8, 3);

	//get green channel
	cvCvtPixToPlane(inImage, NULL, gTrackChannel, NULL, NULL);		

	//get template
	//cvSetZero(gTemplate);	
	cvCopy(gTrackChannel, gTemplate, NULL);
	templRoi.x = inTargetBox.left;
	templRoi.y = inTargetBox.top;
	templRoi.width = inTargetBox.right - inTargetBox.left+1;
	templRoi.height = inTargetBox.bottom - inTargetBox.top+1;
	cvSetImageROI(gTemplate, templRoi);		
	
	//debug display
	//cvFlip(gTrackChannel,NULL,0);
	//cvSaveImage("c:\\CTracker\\gTemplate.bmp", gTemplate);
}

//////////////////////////////////////////////////////////////////////////////
void temp_TrackNextFrame_Coeff(IplImage* inImage, RECT inStartBox, TkResult *outResult)
//track one frame
{		
	double	max;
	int		maxX, maxY;
	RECT	targetBox;
	int		boxWidth, boxHeight;
	int		boxHalfWidth, boxHalfHeight;
	int		border;
	CvRect srcRoi, rstRoi;
	CvPoint	maxPoint;
	
	//check whether input is valid
	if (inImage==NULL) return;
	utl_RectCheckBound(&inStartBox, inImage->width, inImage->height);

	boxWidth	= inStartBox.right-inStartBox.left;
	boxHeight	= inStartBox.bottom-inStartBox.top;
	boxHalfWidth	= boxWidth/2;
	boxHalfHeight	= boxHeight/2;

	//get green channel (gMatchImg as a temporary buffer.)
	cvCvtPixToPlane(inImage, NULL, gTrackChannel, NULL, NULL);		

	//get search window
	border = (int)fn_Round(0.5*max(gTemplate->roi->width,gTemplate->roi->height));
	utl_RectSizeIncrease(&inStartBox, border, inImage->width, inImage->height);

	//set search roi
	srcRoi.x = inStartBox.left;
	srcRoi.y = inStartBox.top;
	srcRoi.width = inStartBox.right - inStartBox.left;
	srcRoi.height = inStartBox.bottom - inStartBox.top;	

	cvSetZero(gResultImg);
	rstRoi.x = srcRoi.x + (gTemplate->roi->width-1)/2;
	rstRoi.y = srcRoi.y + (gTemplate->roi->height-1)/2;
	rstRoi.width = srcRoi.width - gTemplate->roi->width + 1;
	rstRoi.height = srcRoi.height - gTemplate->roi->height + 1;	
	if (rstRoi.width<=0 || rstRoi.height<=0) return;

	cvSetImageROI(gTrackChannel, srcRoi);
	cvSetImageROI(gResultImg, rstRoi);
	
	//match with template		
	cvMatchTemplate(gTrackChannel, gTemplate, gResultImg, CV_TM_CCOEFF_NORMED);
	//cvMatchTemplate(gTrackChannel, gTemplate, gResultImg, CV_TM_SQDIFF_NORMED);

	//reset roi
	gTrackChannel->roi = NULL;
	gResultImg->roi = NULL;	

	//scale 255 and convert to Byte image	
	cvConvertScale(gResultImg, gMatchImg, 255, 0);		

	//get max location
	cvMinMaxLoc(gMatchImg, NULL,  &max, NULL, &maxPoint,NULL);
	maxX = maxPoint.x;
	maxY = maxPoint.y;

	//get target rect
	targetBox.left		= (long)(maxX - boxHalfWidth);
	targetBox.right		= targetBox.left + boxWidth;
	targetBox.top		= (long)(maxY - boxHalfHeight);
	targetBox.bottom	= targetBox.top + boxHeight;	
	
	targetBox.left		= max(targetBox.left,0);
	targetBox.top		= max(targetBox.top,0);
	targetBox.right		= min(targetBox.right,inImage->width-1);
	targetBox.bottom	= min(targetBox.bottom,inImage->height-1);

	//get FG object mask image
	{
		CvRect  roi;	
		cvSetZero(gImgFgMask);	
		cvSetZero(gImgObjMask);	
		roi.x = targetBox.left;
		roi.y = targetBox.top;
		roi.width = targetBox.right-targetBox.left+1;
		roi.height = targetBox.bottom-targetBox.top+1;
		cvSetImageROI(gImgFgMask, roi);		
		cvSetImageROI(inImage, roi);
		cvSetImageROI(gImgObjMask, roi);		
		cvThreshold(gImgFgMask, gImgFgMask, 0, 255, CV_THRESH_BINARY_INV);
		cvCopy(inImage, gImgObjMask, gImgFgMask);		
		cvResetImageROI(gImgFgMask);
		cvResetImageROI(inImage);		
		cvResetImageROI(gImgObjMask);	
	}	
	outResult->FGMask	= gImgFgMask;
	outResult->ObjMask	= gImgObjMask;
	
	//return tracker result
	outResult->targetBox	= targetBox;
	outResult->FGImage		= gMatchImg;
	outResult->score		= (float)max;
	outResult->occlusion	= (max<170? TRUE:FALSE);		
}

⌨️ 快捷键说明

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