📄 track.cpp
字号:
//
// 计算拟合图像值:
//
//////////////////////////////////////////////////////////////////////////////
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 + -