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

📄 vehicletracedlg.cpp

📁 在车辆捕捉的基础上
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  
}

void CVehicleTraceDlg::TraceBest (HTuple Seedx, HTuple Seedy, HTuple PreSeedx, HTuple PreSeedy, HTuple AreaSC, HTuple RowSC, HTuple ColumnSC, HTuple Seedarea, HTuple *SeedMatchInd)
{
 //  结合最优匹配点与当前种子点之间的距离、角度和区域面积特征进行轨迹跟踪
  HTuple   DistancesSC, AnglesSC, RareasSC, w1, w2, w3, j;
  HTuple   DistanceSC, AngleSC, RareaSC, MaxDist, MaxAngle;
  HTuple   FResult, FIndices;

  DistancesSC = HTuple();
  AnglesSC = HTuple();
  RareasSC = HTuple();
  w1 = HTuple(0.5);
  w2 = HTuple(0.5);
  w3 = HTuple(0.5);
  (*SeedMatchInd) = HTuple();

  for (j=0; j<=(AreaSC.Num())-1; j+=1)
  {
     // 计算种子点与候选点之间的距离
    ::distance_pp(Seedx,Seedy,HTuple(RowSC[long(j[0])]),HTuple(ColumnSC[long(j[0])]),&DistanceSC);
    ::tuple_concat(DistancesSC,DistanceSC,&DistancesSC);
	 // 计算角度,分种子点与临时种子点
    if (PreSeedx!=0)  //种子点
    {
      ::angle_ll(PreSeedx,PreSeedy,Seedx,Seedy,Seedx,Seedy,HTuple(RowSC[long(j[0])]),HTuple(ColumnSC[long(j[0])]),&AngleSC);
      ::tuple_concat(AnglesSC,AngleSC.Abs(),&AnglesSC); // 计算两直线之间的夹角,顺时针旋转,-pi<alpha<pi
    }
    else    //倘若是临时种子点则角度不列入考虑
    {
      ::tuple_concat(AnglesSC,HTuple(0),&AnglesSC);    // 在尾部添加0
    }
	 // 计算面积相对差别
      RareaSC = ((HTuple(AreaSC[long(j[0])])-Seedarea).Abs())/Seedarea;
    ::tuple_concat(RareasSC,RareaSC,&RareasSC);
  }

  // 计算判断准则
  ::tuple_max(DistancesSC,&MaxDist);   //找出最大的距离
  ::tuple_max(AnglesSC,&MaxAngle);     //找出最大的角
  if(MaxDist>0)
	  ::tuple_div(DistancesSC,MaxDist,&DistancesSC); //DistancesSC中的每一个元素与MaxDist相除
  if(MaxAngle>0)
	  ::tuple_div(AnglesSC,MaxAngle,&AnglesSC);
  ::tuple_add(w1*DistancesSC,w2*AnglesSC,&FResult);
  ::tuple_add(FResult,w3*RareasSC,&FResult);
  ::tuple_sort_index(FResult,&FIndices);
  (*SeedMatchInd) = FIndices[long(0)];  //找到最小值对应的序号
  return;
/*  if (PreSeedx!=0)
  {
    if (MaxDist!=0)
    {
      if (MaxAngle!=0)
      {
        FResult = (((w1*DistancesSC)/MaxDist)+((w2*AnglesSC)/MaxAngle))+(w3*RareasSC);
        ::tuple_sort_index(FResult,&FIndices);
        if (HTuple(FResult[long(FIndices[long(0)])])<1.1)
        {
          (*SeedMatchInd) = FIndices[long(0)];
        }
      }
      else
      {
        FResult = ((w1*DistancesSC)/MaxDist)+(w3*RareasSC);
        ::tuple_sort_index(FResult,&FIndices);
        if (HTuple(FResult[long(FIndices[long(0)])])<1.1)
        {
          (*SeedMatchInd) = FIndices[long(0)];
        }
      }
    }
    else
    {
      if (MaxAngle!=0)
      {
        FResult = ((w2*AnglesSC)/MaxAngle)+(w3*RareasSC);
        ::tuple_sort_index(FResult,&FIndices);
        if (HTuple(FResult[long(FIndices[long(0)])])<1.1)
        {
          (*SeedMatchInd) = FIndices[long(0)];
        }
      }
      else
      {
        FResult = w3*RareasSC;
        ::tuple_sort_index(FResult,&FIndices);
        if (HTuple(FResult[long(FIndices[long(0)])])<1.1)
        {
          (*SeedMatchInd) = FIndices[long(0)];
        }
      }
    }
  }
  else
  {
    if (MaxDist!=0)
    {
      FResult = ((w1*DistancesSC)/MaxDist)+(w3*RareasSC);
      ::tuple_sort_index(FResult,&FIndices);
      if (HTuple(FResult[long(FIndices[long(0)])])<0.51)
      {
        (*SeedMatchInd) = FIndices[long(0)];
      }
    }
    else
    {
      FResult = w3*RareasSC;
      ::tuple_sort_index(FResult,&FIndices);
      if (HTuple(FResult[long(FIndices[long(0)])])<0.51)
      {
        (*SeedMatchInd) = FIndices[long(0)];
      }
    }
  }  */
}

void CVehicleTraceDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here

}


void CVehicleTraceDlg::OnCancelMode() 
{
	CDialog::OnCancelMode();
	
	// TODO: Add your message handler code here
	
}

void CVehicleTraceDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	CDialog::OnTimer(nIDEvent);

 //Hobject ActualImage,ImageZoomed,ForegroundRegion,RegionZoom;
    Hobject RegionRec;

if(isPlay==true)
{
  //***第一步:找出当前帧中所有运动目标********************************************
  //   该段程序的作用是将当前帧图像与背景图像进行灰度对比,在当前帧中提炼出所有运动目标
  //   的位置区域,为下面轨迹跟踪做好准备.
	   grab_image(&ActualImage,m_lFGHandle);   // m_lFGHandle由前面open_framegrabber得到 
	   FrameSerialNum++;
     // 估计背景灰度或是前景灰度一般先用zoom_image_factor将其缩小,估计完后再恢复至原大小
       ::zoom_image_factor(ActualImage,&ImageZoomed,HTuple(0.5),HTuple(0.5),HTuple("constant"));
       ::run_bg_esti(ImageZoomed,&ForegroundRegion,BgEstiHandle);  //BgEstiHandle由上面create_bg_esti()创建
       ::zoom_region(ForegroundRegion,&RegionZoom,HTuple(2),HTuple(2));  //放大到原图像大小

       ::intersection(RegionZoom,XingRegion,&RegionIntersection);  //求交集
       ::connection(RegionIntersection,&ConnectedRegions);
       ::select_shape(ConnectedRegions,&SelectedRegions,HTuple("area"),HTuple("and"),HTuple(200),HTuple(99999));
       ::shape_trans(SelectedRegions,&RegionTrans,HTuple("convex"));
       ::union1(RegionTrans,&RegionUnion);  //经该函数合并后元素个数为1
       ::connection(RegionUnion,&FinalConnected);
       ::select_gray(FinalConnected,ActualImage,&SelectedRegionsGray,HTuple("deviation"),HTuple("and"),HTuple(25),HTuple(1000));
	   ::copy_obj(SelectedRegionsGray,&RegionGray,HTuple(1),HTuple(-1)); // 备份
 

  //***第二步:对种子点进行轨迹跟踪**************************************************
       // 以下程序段是对已有的种子点逐一进行轨迹跟踪,搜索范围为上面检测到的
	   // 新的所有可能区域。在针对每一质点时,会确定一个更小的搜索范围。搜索成功则在
	   // 下一帧中继续,搜索失败则轨迹跟踪断裂。
	   // 注意:被连续跟踪两帧及两帧以上的轨迹链上的点称为种子点,倘若只有一帧被搜索
	   // 到,则称为临时种子点。
       for (int i=0; i<Vehicles.GetSize(); i++)
	   {
	       Vehicle existVehicle=Vehicles.GetAt(i);
	       if(existVehicle.isEnd==false)
		   {
	          int SeedNum=existVehicle.SeedX.Num();  // 求取目标的个数,即取当前车辆对应种子点的个数
	   
            // 由上两个点确定一个搜索的范围
              WinXlimit = HTuple(HTuple(3)*HTuple(existVehicle.SeedX[SeedNum-2])-HTuple(2)*HTuple(existVehicle.SeedX[SeedNum-1])).Concat((HTuple(6)*HTuple(existVehicle.SeedX[SeedNum-1]))-(HTuple(5)*HTuple(existVehicle.SeedX[SeedNum-2])));   // concat用于将两个tuple变量合为一个
//		     WinXlimit = HTuple(-).Concat(()-());
//           HTuple(3)*HTuple(existVehicle.SeedX[SeedNum-2])
//           HTuple(2)*HTuple(existVehicle.SeedX[SeedNum-1])
//           HTuple(6)*HTuple(existVehicle.SeedX[SeedNum-1])
//           HTuple(5)*HTuple(existVehicle.SeedX[SeedNum-2])

              WinYlimit = HTuple(HTuple(3)*HTuple(existVehicle.SeedY[SeedNum-2])-HTuple(2)*HTuple(existVehicle.SeedY[SeedNum-1])).Concat((HTuple(6)*HTuple(existVehicle.SeedY[SeedNum-1]))-(HTuple(5)*HTuple(existVehicle.SeedY[SeedNum-2])));
//		     WinYlimit = HTuple(-).Concat(()-());
//           HTuple(3)*HTuple(existVehicle.SeedY[SeedNum-2])
//		     HTuple(2)*HTuple(existVehicle.SeedY[SeedNum-1])
//		     HTuple(6)*HTuple(existVehicle.SeedY[SeedNum-1])
//           HTuple(5)*HTuple(existVehicle.SeedY[SeedNum-2])

		   
		   
		      ::tuple_sort(WinXlimit,&WinXlimit);  // 将winXlimit中的元素按升序排列!
              ::tuple_sort(WinYlimit,&WinYlimit);
              ::select_shape(SelectedRegionsGray,&ObjRegionCandinates,HTuple("row").Concat("column"),HTuple("and"),HTuple(WinXlimit[long(0)]).Concat(HTuple(WinYlimit[long(0)])),HTuple(WinXlimit[long(1)]).Concat(HTuple(WinYlimit[long(1)])));
// 上句对应:select_shape(SelectedRegionsGray,result,['row','column'],'and',[WinXlimit[0],WinYlimit[0]],[WinXlimit[1],WinXlimit[1]])
// 将中心坐标落在上述确定范围的区域选出来!

              ::area_center(ObjRegionCandinates,&AreaSC,&RowSC,&ColumnSC); //SC--新一代候选种子点
           if ((AreaSC.Num())!=0)   // 倘若有满足要求的区域存在,则进一步筛选
		   {
              TraceBest(HTuple(existVehicle.SeedX[SeedNum-1]),HTuple(existVehicle.SeedY[SeedNum-1]),HTuple(existVehicle.SeedX[SeedNum-2]),HTuple(existVehicle.SeedY[SeedNum-2]),AreaSC,RowSC,ColumnSC,HTuple(existVehicle.SeedArea[SeedNum-2]),&SeedMatchInd);
              if ((SeedMatchInd.Num())!=0)  // 倘若有最佳目标出现...
			  {
				  // 将目标选出,然后剔除
                  ::select_obj(ObjRegionCandinates,&ObjectMatched,SeedMatchInd+1);
                  ::difference(SelectedRegionsGray,ObjectMatched,&SelectedRegionsGray);
         
				  // 将新得到的种子点添加到种子序列中(保存row,column,area)
			      ::tuple_concat(existVehicle.SeedX,HTuple(RowSC[long(SeedMatchInd[0])]),&(existVehicle.SeedX));
			      ::tuple_concat(existVehicle.SeedY,HTuple(ColumnSC[long(SeedMatchInd[0])]),&(existVehicle.SeedY));
			      ::tuple_concat(existVehicle.SeedArea,HTuple(AreaSC[long(SeedMatchInd[0])]),&(existVehicle.SeedArea));
			      
				  //将得到的图像坐标(row,column)转化为世界坐标(Qx,Qy)--(实质上是二维至二维)
			      HTuple Qx,Qy,Qw,XResult,YResult;
			      ::projective_trans_point_2d(HomMat2D,HTuple(RowSC[long(SeedMatchInd[0])]),HTuple(ColumnSC[long(SeedMatchInd[0])]),HTuple(1),&Qx,&Qy,&Qw);
                  XResult = Qx/Qw;
                  YResult = Qy/Qw;

				  // 求得两点间的距离及目标运动速度
                  HTuple dist=HTuple((existVehicle.WorldX[SeedNum-1]-XResult)*(existVehicle.WorldX[SeedNum-1]-XResult)+(existVehicle.WorldY[SeedNum-1]-YResult)*(existVehicle.WorldY[SeedNum-1]-YResult)).Sqrt() ;
				  HTuple v=dist/HTuple(FrameTime);

				  // 记录新种子点的世界坐标和运动速度
                  ::tuple_concat(existVehicle.WorldX,XResult,&(existVehicle.WorldX));
                  ::tuple_concat(existVehicle.WorldY,YResult,&(existVehicle.WorldY));
                  ::tuple_concat(existVehicle.Velocity,v,&(existVehicle.Velocity));
			  }
		      else    // 未找到新种子点则跟踪断裂
			  { 
				  existVehicle.isEnd=true;
		          existVehicle.FrameEnd=FrameSerialNum;
			  }
		   }
		   else 
		   {
			   existVehicle.isEnd=true;
		       existVehicle.FrameEnd=FrameSerialNum;
		   }
		   Vehicles.SetAt(i,existVehicle);

		   }

	   }

  //***第三步:对临时种子点进行轨迹跟踪**********************************************************
	   // 临时种子点即为轨迹还只存储过一个点的目标质点;
	   // 下面的SelectedRegionsGray是第二步选择后的结果,即已经剔除了那些成功匹配的区域
	   // (RowNS,ColumnNS)和AreaNS分别为临时种子点对应区域的中心点坐标和面积,LenNS=AreaNS的平方根。
	   // 注意:倘若临时种子点成功匹配到一个新点,则其与新点同时升级为种子点,同时保存其相关信息!!!!
    for(int r=0;r<AreaNS.Num();r++)    //NS----new seed
	{
       ::select_shape(SelectedRegionsGray,&ObjRegionCandinates,HTuple("row").Concat("column"),HTuple("and"),
	   (HTuple(RowNS[r])-HTuple(LenNS[r])).Concat(HTuple(ColumnNS[r])-HTuple(LenNS[r])),
	   (HTuple(RowNS[r])+HTuple(LenNS[r])).Concat(HTuple(ColumnNS[r])+HTuple(LenNS[r])));
       ::area_center(ObjRegionCandinates,&AreaSC,&RowSC,&ColumnSC);//计算候选区域面积,中心坐标
       if ((AreaSC.Num())!=0)
	   {
          TraceBest(HTuple(RowNS[r]),ColumnNS[r],HTuple(0),HTuple(0),AreaSC,RowSC,ColumnSC,HTuple(AreaNS[r]),&SeedMatchInd);
          if ((SeedMatchInd.Num())!=0)    // 成功匹配则保存!
		  {
		     ::select_obj(ObjRegionCandinates,&ObjectMatched,SeedMatchInd+1);
             ::difference(SelectedRegionsGray,ObjectMatched,&SelectedRegionsGray);   //剔除匹配过的点
			 
          // 将临时种子点之RowNS,ColumnNS,AreaNS及其相应的世界坐标添加到newVehicle的尾部
             Vehicle newVehicle;  
             ::tuple_concat(newVehicle.SeedX,RowNS[r],&newVehicle.SeedX);
	         ::tuple_concat(newVehicle.SeedY,ColumnNS[r],&newVehicle.SeedY);
	         ::tuple_concat(newVehicle.SeedArea,AreaNS[r],&newVehicle.SeedArea);
	      // 图像平面坐标向二维世界坐标转换
	         HTuple Qx1,Qy1,Qw1,XResult1,YResult1;
	         ::projective_trans_point_2d(HomMat2D,RowNS[r],ColumnNS[r],HTuple(1),&Qx1,&Qy1,&Qw1);
             XResult1 = Qx1/Qw1;
             YResult1 = Qy1/Qw1;
             ::tuple_concat(newVehicle.WorldX,XResult1,&(newVehicle.WorldX));
             ::tuple_concat(newVehicle.WorldY,YResult1,&(newVehicle.WorldY));

         // 将新匹配成功的候选点之RowSC,ColumnSC,AreaSC及其相应的世界坐标添加到newVehicle的尾部
	         ::tuple_concat(newVehicle.SeedX,HTuple(RowSC[long(SeedMatchInd[0])]),&(newVehicle.SeedX));
	         ::tuple_concat(newVehicle.SeedY,HTuple(ColumnSC[long(SeedMatchInd[0])]),&(newVehicle.SeedY));
	         ::tuple_concat(newVehicle.SeedArea,HTuple(AreaSC[long(SeedMatchInd[0])]),&(newVehicle.SeedArea));
	     // 图像平面坐标向二维世界坐标转换
			 HTuple Qx2,Qy2,Qw2,XResult2,YResult2;
             ::projective_trans_point_2d(HomMat2D,HTuple(RowSC[long(SeedMatchInd[0])]),HTuple(ColumnSC[long(SeedMatchInd[0])]),HTuple(1),&Qx2,&Qy2,&Qw2);
             XResult2 = Qx2/Qw2;
             YResult2 = Qy2/Qw2;
             ::tuple_concat(newVehicle.WorldX,XResult2,&(newVehicle.WorldX));
             ::tuple_concat(newVehicle.WorldY,YResult2,&(newVehicle.WorldY));

	     // 计算两点之间的距离及目标运动速度
             HTuple dist=HTuple((XResult2-XResult1)*(XResult2-XResult1)+(YResult2-YResult1)*(YResult2-YResult1)).Sqrt() ;
             HTuple v=dist/HTuple(FrameTime);
             ::tuple_concat(newVehicle.Velocity,v,&(newVehicle.Velocity));

         // 记录新轨迹开始的起始帧号,并将新发现的具有轨迹链的目标添加到运动目标中
	         newVehicle.FrameStart=FrameSerialNum-1;
	         newVehicle.isEnd=false;
	         Vehicles.Add(newVehicle);
		  }
	   }
	}
//////////////////Trace Join   轨迹连接
		  /*
	HTuple FrameSubs,AreaSubs,Distances,AngleSubs,VehicleIndex;
	HTuple FrameSubsMAX,AreaSubsMAX,DistancesMAX,AngleSubsMAX;

 for (int f=0; f<Vehicles.GetSize(); f++)
    {
	Vehicle existVehicle=Vehicles.GetAt(f);
	if(existVehicle.isEnd==true)
		if(k-existVehicle.FrameEnd<10)
	{
	int SeedNum=existVehicle.SeedX.Num();
	int FrameSub;

⌨️ 快捷键说明

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