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

📄 track.cpp

📁 利用web camera对目标进行特征跟踪的程序 对于初学机器视觉的有些帮助
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
//  计算拟合图像值:
//
//////////////////////////////////////////////////////////////////////////////
bool CTrack::ReconstructImageUseSVD(double* pImageTarget,DWORD dwSize,double* pVector,DWORD dwVectorNumber,double*& pImitate)
{
	if(pImitate) delete pImitate;
	pImitate = new double[dwSize];

	double *C=NULL;
	if(!(C=(double*)new double [dwVectorNumber]))
	{
		AfxMessageBox("分配内存失败!C \n PyramidCalculateImitateTargetImage()");
		return FALSE;
	}
    double temp;		
	DWORD position = 0;
    //计算拟合系数C值
	for( DWORD j=0; j<dwVectorNumber; j++){
		 C[j] = 0;
		 for(DWORD i=0; i<dwSize; i++)
			 C[j] += pVector[i+position] * pImageTarget[i];
		 position += dwSize;
	}

	//计算拟合图像
	for(DWORD i=0; i<dwSize; i++){
		  position = 0;
		  temp = 0;
		  for(j=0; j<dwVectorNumber; j++){
			  temp += pVector[i+position] * C[j];
			  position += dwSize;
		  }
		  pImitate[i] = temp>255? 255:temp;
	  }
	if(!C) delete C;

	return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////
//
//  从内存中装入模板图像:(目标大小已经在TrackSet中设置)
////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::LoadTemplate(BYTE *pBitmapData)
{
	DWORD dwSize = m_dwTargetWidth  * m_dwTargetWidth;
	if(m_pBitmapTemplate)
		delete m_pBitmapTemplate;
	
	m_pBitmapTemplate = (double*) new double [dwSize];
	if(!m_pBitmapTemplate)
	{
		AfxMessageBox("CTrack::LoadTemplate 分配内存出错!");
		return FALSE;
	}
	double dMean = 0;
	for(DWORD i=0; i< dwSize; i++)
	{
		m_pBitmapTemplate[i] = (int)pBitmapData[i];
		dMean += m_pBitmapTemplate[i];
	}
	dMean /= dwSize;
	for(i=0; i< dwSize; i++)
	{
		m_pBitmapTemplate[i] -= dMean;
	}

	PyramidSampleImage(m_dwTargetHeight,m_dwTargetWidth,m_pBitmapTemplate,m_pBitmapTemplate_SecondLevel);


//	SmoothImage(dwTargetWindowWidth,dwTargetWindowWidth,pBitmapTemplate);
	//使用梯度图像
//	if(!Sobel(pBitmapTemplate,dwTargetWindowWidth,dwTargetWindowWidth))
//		return false;

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////
//
//  改变图像的大小:
////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::ChangeImageSize(BYTE *pBitmap, DWORD dwWidth, DWORD dwHeight, BYTE *&pBitmapResult, DWORD dwWidthResult, DWORD dwHeightResult)
{
	if(!(dwWidth && dwHeight && dwWidthResult && dwHeightResult))
	{
		AfxMessageBox("CTrack::ChangeImageSize  \n 图像大小不能为0!");
		return FALSE;
	}
	if(pBitmapResult) delete pBitmapResult;
	pBitmapResult = new BYTE[dwWidthResult*dwHeightResult];
    double ratio_x,ratio_y;
	ratio_x = (double) dwWidth;
	ratio_x /= (double) dwWidthResult;
	ratio_y = (double) dwHeight;
	ratio_y /= (double) dwHeightResult;
	DWORD i,j,position,position_l=0;
	double x,y,temp,temp1;
	
	for(j=1; j<dwHeightResult-1; j++)
	for(i=1; i<dwWidthResult-1; i++)
	{
		x = i;
		y = j;
		x *= ratio_x;
		y *= ratio_y;
		position = ((int)y) * dwWidth + (int)(x);
		temp1 = pBitmap[position] - pBitmap[position+1];
		temp  = (double)pBitmap[position] - temp1* (x-(int)x);
		position += dwWidth;
		temp1 = pBitmap[position] - pBitmap[position+1];
		temp -= (temp-((double)pBitmap[position] - temp1* (x-(int)x)))*(y-(int)y);
        
		pBitmapResult[j*dwWidthResult+i] = (BYTE) temp;
	}

	//最后一行用边界外拓法:
	DWORD dwSize = dwHeightResult*dwWidthResult;
	for(i=0;i<dwSize;i+=dwWidthResult)
	{
		pBitmapResult[i]=pBitmapResult[i+1];
	    pBitmapResult[i+dwWidthResult-1] = pBitmapResult[i+dwWidthResult-2];
	}
	for(j=0;j<dwWidthResult;j++)
	{
		pBitmapResult[j]=pBitmapResult[j+dwWidthResult];
		pBitmapResult[dwSize-j-1] = pBitmapResult[dwSize-j-1-dwWidthResult];
	}

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////
//
//  改变图像的大小:
////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::ChangeImageSize(double *pBitmap, DWORD dwWidth, DWORD dwHeight, double *&pBitmapResult, DWORD dwWidthResult, DWORD dwHeightResult)
{
	if(!(dwWidth && dwHeight && dwWidthResult && dwHeightResult))
	{
		AfxMessageBox("CTrack::ChangeImageSize  \n 图像大小不能为0!");
		return FALSE;
	}
	if(pBitmapResult) delete pBitmapResult;
	pBitmapResult = new double[dwWidthResult*dwHeightResult];
    double ratio_x,ratio_y;
	ratio_x = (double) dwWidth;
	ratio_x /= (double) dwWidthResult;
	ratio_y = (double) dwHeight;
	ratio_y /= (double) dwHeightResult;
	DWORD i,j,position,position_l=0;
	double x,y,temp,temp1;
	
	for(j=1; j<dwHeightResult-1; j++)
	for(i=1; i<dwWidthResult-1; i++)
	{
		x = i;
		y = j;
		x *= ratio_x;
		y *= ratio_y;
		position = ((int)y) * dwWidth + (int)(x);
		temp1 = pBitmap[position] - pBitmap[position+1];
		temp  = (double)pBitmap[position] - temp1* (x-(int)x);
		position += dwWidth;
		temp1 = pBitmap[position] - pBitmap[position+1];
		temp -= (temp-((double)pBitmap[position] - temp1* (x-(int)x)))*(y-(int)y);
        
		pBitmapResult[j*dwWidthResult+i] = temp;
	}
	//最后一行用边界外拓法:
	DWORD dwSize = dwHeightResult*dwWidthResult;
	for(i=0;i<dwSize;i+=dwWidthResult)
	{
		pBitmapResult[i]=pBitmapResult[i+1];
	    pBitmapResult[i+dwWidthResult-1] = pBitmapResult[i+dwWidthResult-2];
	}
	for(j=0;j<dwWidthResult;j++)
	{
		pBitmapResult[j]=pBitmapResult[j+dwWidthResult];
		pBitmapResult[dwSize-j-1] = pBitmapResult[dwSize-j-1-dwWidthResult];
	}
	return true;
}
/////////////////////////////////////////////////////////////////////////////////
//
//将输入的布尔型向量图像转变为四分之一大小
/////////////////////////////////////////////////////////////////////////////////
bool CTrack::ChangeImageSize(BYTE *pBitmapInput, DWORD dwHeight, DWORD dwWidth, BYTE *&pBitmapResult)
{
 	DWORD position=0;
 	DWORD dwHeight_now,dwWidth_now;
 	dwHeight_now=dwHeight>>1;
 	dwWidth_now = dwWidth>>1;
 
 	DWORD k=0,l=0;
 	for(DWORD i=0; i<dwHeight_now; i++)	
 	{
 		l=0;
 		for(DWORD j=0; j<dwWidth_now; j++)
 		{
 			pBitmapResult[position]=pBitmapInput[k+l];
			l+=2;
 			position ++;
		}
		k=i<<1;
		k*=dwWidth;
 	}
 	return TRUE;
 }
////////////////////////////////////////////////////////////////////////////////////////////////////////
//  按照当前的参数到输入图像中截取目标图像:大小由目标长宽给出
//  得到的图像是0均值化的
////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::GetTargetImageByGivenAffineParameters(double*& pResult,double* a)
{
	double x,y,temp,x1,x2,x3,y1,y2,y3;
	double x_center = ((double)m_dwTargetWidth-1)/2;
	double y_center = ((double)m_dwTargetHeight-1)/2;
	double dMean    = 0;
	double dVariance = 0;
    DWORD position,i,j,position_l=0,dwObjectSize_now=m_dwTargetWidth*m_dwTargetHeight;
	double x_addition;
	double y_addition;
	
	
    //================有效性检测========================	
	if(a[1]*a[1]+a[4]*a[4] <0.001 || a[2]*a[2]+a[5]*a[5] <0.001)
	{
	//	AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太小!");
	//	return false;
	}
	if(a[1]*a[1]+a[4]*a[4] >9 || a[2]*a[2]+a[5]*a[5] >9)
	{
	//	AfxMessageBox("在采集当前选择框所覆盖的目标区时,区域瞬间变得太大!");
	//	return false;
	}
	//检测匹配框是否出界:(检测四个顶点是否出界)
	x  = a[0]-x_center*a[1]-y_center*a[2] -x_center ;
	x1 = a[0]+x_center*a[1]-y_center*a[2] +x_center ;
	x2 = a[0]-x_center*a[1]+y_center*a[2] -x_center ;
	x3 = a[0]+x_center*a[1]+y_center*a[2] +x_center ;
	y  = a[3]-x_center*a[4]-y_center*a[5] -y_center ;
	y1 = a[3]+x_center*a[4]-y_center*a[5] -y_center ;
	y2 = a[3]-x_center*a[4]+y_center*a[5] +y_center ;
	y3 = a[3]+x_center*a[4]+y_center*a[5] +y_center ;
	if(x<2||x1<2||x2<2||x3<2|| x>m_dwBitmapInputWidth-2||x1>m_dwBitmapInputWidth-2||x2>m_dwBitmapInputWidth-2||x3>m_dwBitmapInputWidth-2||  y<2||y1<2||y2<2||y3<2|| y1>m_dwBitmapInputHeight-2||y2>m_dwBitmapInputHeight-2||y3>m_dwBitmapInputHeight-2||y>m_dwBitmapInputHeight-2 ) 
	{
	//	AfxMessageBox("在采集当前选择框所覆盖的目标区时,发生越界!");
		return false;
	}

	//申请空间
	if(pResult) delete pResult;
	pResult = new double [m_dwTargetHeight*m_dwTargetWidth];

	double x_Left;
	double y_Left;
	//仿射变换,上中心偏移量
	x_Left = a[0] -x_center*a[1] -y_center*a[2] -x_center  ;
	y_Left = a[3] -x_center*a[4] -y_center*a[5] -y_center  ;

	x_addition = a[1]+1;
	y_addition = a[4];

	//采集目标图象
	for(j=0; j<m_dwTargetHeight; j++)
	{
		x = x_Left;
		y = y_Left;
		x_Left += a[2]; 
		y_Left += a[5]+1;
		for(i=0; i<m_dwTargetWidth; i++)
		{
			//计算当前点在输入图像中的位置
			position = (int)(y) * m_dwBitmapInputWidth + (int)(x);

    /////============采集该点处的灰度值================
			//抽样:在2*2临域内采用内插法:
			temp  = m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x);
			position += m_dwBitmapInputWidth ;
			temp -= (temp-(m_pBitmapInput[position] - (m_pBitmapInput[position] - m_pBitmapInput[position+1])* (x-(int)x)))*(y-(int)y);
			//插值结果赋给相应的标准化目标点:
			pResult[position_l] = temp;
			dMean += temp;
			dVariance+= temp*temp;

			position_l ++;//计算下一个点
			x += x_addition;
			y += y_addition;
		}
	}

	// 0 均值化:
	position = m_dwTargetWidth * m_dwTargetHeight;
	dMean /= (double)position;
	m_dVarianceTarget = sqrt(dVariance/position - dMean*dMean);

	if(TrackType==TT_AFFINE)
	{
		m_dGradationOffset= (BYTE) dMean;
		for(i=0; i<position;i++)
			pResult[i] -= dMean;
	} else
		m_dGradationOffset=0;

    return true;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 得到目标的图像:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::GetTargetBitmap(BYTE *&pTargetOut)
{
	if(!m_pBitmapTarget) 
	{	AfxMessageBox("没有目标图像");	return false;}

	DWORD i,j;
	j = m_dwTargetWidth*m_dwTargetHeight;

	if(pTargetOut) delete pTargetOut;
	pTargetOut = new BYTE[j];

	for(i=0;i<j;i++)
		pTargetOut[i] = (BYTE)(m_pBitmapTarget[i]+m_dGradationOffset);
	
	
	return true;
}
////////////////////////////////////////////////////////////////////////////////////
// 得到模板的图像:
////////////////////////////////////////////////////////////////////////////////////
bool CTrack::GetTemplateBitmap(BYTE *&pTemplateOut)
{
	if(!m_pBitmapTemplate) 
	{	
		AfxMessageBox("当前模板为空");	
		return false;	
	}

	DWORD i,j;
	j = m_dwTargetHeight * m_dwTargetWidth;

	if(pTemplateOut) delete pTemplateOut;
	pTemplateOut = new BYTE [j];

	for(i=0;i<j;i++)
		pTemplateOut[i] = (BYTE) (m_pBitmapTemplate[i]+m_dTempalteGradationOffset);

	return true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//
//  计算实际目标图象和真实位置之间的仿射差:a
//
///////////////////////////////////////////////////////////////////////////////////////////////////
bool CTrack::CalculateParameter(double *pTemplateImage, int nTargetHeight, int nTargetWidth, double *pTargetImage,double *pTargetDifference, double delt,double *a)
{
	//有效性检测:

⌨️ 快捷键说明

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