From 985e7346c5b7fa977dd71b03112b8e050b5705dc Mon Sep 17 00:00:00 2001
From: mwinter <mwinter@drexel.edu>
Date: Thu, 21 Feb 2013 15:35:01 -0500
Subject: [PATCH] Basic cell MAT tracker.

---
 baseCellTracker.sln    |  26 +++
 baseCellTracker.vcproj | 375 +++++++++++++++++++++++++++++++++++++++++
 src/cost.cpp           | 168 ++++++++++++++++++
 src/cost.h             |  35 ++++
 src/detection.cpp      | 232 +++++++++++++++++++++++++
 src/detection.h        |  62 +++++++
 src/paths.cpp          | 144 ++++++++++++++++
 src/paths.h            |  65 +++++++
 src/tracker.cpp        | 218 ++++++++++++++++++++++++
 src/tracker.h          |  77 +++++++++
 10 files changed, 1402 insertions(+)
 create mode 100644 baseCellTracker.sln
 create mode 100644 baseCellTracker.vcproj
 create mode 100644 src/cost.cpp
 create mode 100644 src/cost.h
 create mode 100644 src/detection.cpp
 create mode 100644 src/detection.h
 create mode 100644 src/paths.cpp
 create mode 100644 src/paths.h
 create mode 100644 src/tracker.cpp
 create mode 100644 src/tracker.h

diff --git a/baseCellTracker.sln b/baseCellTracker.sln
new file mode 100644
index 0000000..b5b3e91
--- /dev/null
+++ b/baseCellTracker.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "baseCellTracker", "baseCellTracker.vcproj", "{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Debug|Win32.Build.0 = Debug|Win32
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Debug|x64.ActiveCfg = Debug|x64
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Debug|x64.Build.0 = Debug|x64
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Release|Win32.ActiveCfg = Release|Win32
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Release|Win32.Build.0 = Release|Win32
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Release|x64.ActiveCfg = Release|x64
+		{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/baseCellTracker.vcproj b/baseCellTracker.vcproj
new file mode 100644
index 0000000..53344f5
--- /dev/null
+++ b/baseCellTracker.vcproj
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="baseCellTracker"
+	ProjectGUID="{88FA6F51-2685-4A1D-8C95-BCD88E04B63D}"
+	RootNamespace="baseCellTracker"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)\Output\$(ConfigurationName)_$(PlatformName)"
+			IntermediateDirectory="$(SolutionDir)\Intermediate\$(ConfigurationName)_$(PlatformName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(SolutionDir)\Output\$(ConfigurationName)_$(PlatformName)"
+			IntermediateDirectory="$(SolutionDir)\Intermediate\$(ConfigurationName)_$(PlatformName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)\Output\$(ConfigurationName)_$(PlatformName)"
+			IntermediateDirectory="$(SolutionDir)\Intermediate\$(ConfigurationName)_$(PlatformName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)\Output\$(ConfigurationName)_$(PlatformName)"
+			IntermediateDirectory="$(SolutionDir)\Intermediate\$(ConfigurationName)_$(PlatformName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories=".\src"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\src\cost.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\detection.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\paths.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\tracker.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\src\cost.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\detection.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\paths.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\tracker.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/src/cost.cpp b/src/cost.cpp
new file mode 100644
index 0000000..864c0a2
--- /dev/null
+++ b/src/cost.cpp
@@ -0,0 +1,168 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include "tracker.h"
+
+#undef max
+#undef min
+
+const double costEpsilon = 1e-3;
+
+double GetCCDistance(int node0, int node1)
+{
+	if ( gDetect[node0].connCompDist.count(node1) == 0 )
+		return (gCCMax + 1.0);
+
+	return (gDetect[node0].connCompDist[node1]);
+} // GetCCDistance
+
+double GetCOMDistance(int node0, int node1)
+{
+	double distSq = (SQR(gDetect[node0].X-gDetect[node1].X) + SQR(gDetect[node0].Y-gDetect[node1].Y));
+				
+	return sqrt(distSq);
+} // GetCOMDistance
+
+double GetWeightedDistance(int node0, int node1, double vmax, double ccmax)
+{
+	double hd,sd;
+	double nmax,nmin,cd;
+
+	hd = GetCOMDistance(node0, node1);
+	if ( hd > vmax )
+		return dbltype::infinity();
+
+	nmax = std::max<int>(gDetect[node0].pixelCoords.size(), gDetect[node1].pixelCoords.size());
+	nmin = std::min<int>(gDetect[node0].pixelCoords.size(), gDetect[node1].pixelCoords.size());
+
+	cd = GetCCDistance(node0, node1);
+	if ( cd > ccmax )
+		return dbltype::infinity();
+		
+	sd = (nmax - nmin) / nmax;
+
+	return (10.0*hd + 100.0*sd + 1000.0*cd);
+
+} // GetWeightedDistances
+
+double GetCost(const std::vector<int>& path, int srcFrameIdx, int bCheck)
+{
+	int k;
+	double dlcd;
+	int startIdx;
+	double dlocnX,dlocnY;
+
+	double LocalCost = 0.0;
+	double LocationCost = 0.0; 
+	double TotalCost = 0.0;
+	double OcclusionCost=1.0;
+
+
+	if ( (path.size() - srcFrameIdx) < 2 )
+		return dbltype::infinity();
+	
+	if (bCheck)
+		startIdx = path.size() - 2;
+	else
+	{				
+		int tStart;
+			
+		tStart = GetTime(path[srcFrameIdx]) - gWindowSize+1;
+		tStart = std::max<int>(0, tStart);
+		startIdx = srcFrameIdx;
+		while ( (GetTime(path[startIdx]) > tStart) && (startIdx > 0) )
+			startIdx--;
+	}
+
+	for ( k=startIdx; k < path.size()-1; ++k )
+	{
+		dlcd = GetCOMDistance(path[k], path[k+1]);
+		if ( dlcd > gVMax )
+			return dbltype::infinity();		
+	}
+
+	OcclusionCost = 1.0;
+	for ( k=startIdx; k < path.size()-1; ++k )
+		OcclusionCost += GetTime(path[k+1]) - GetTime(path[k]) - 1;
+	
+	if (bCheck)
+		return 1.0;
+
+	LocalCost = 3 * GetWeightedDistance(path[srcFrameIdx], path[srcFrameIdx+1], gVMax, gCCMax);
+		
+	if ( LocalCost == dbltype::infinity() )			
+		return dbltype::infinity();
+
+	if ( srcFrameIdx > 0 )
+		LocalCost += GetWeightedDistance(path[srcFrameIdx-1], path[srcFrameIdx+1], 2*gVMax, 2*gCCMax);
+	else
+		LocalCost *= 2;
+	
+	if ( LocalCost == dbltype::infinity() )			
+		return dbltype::infinity();
+	
+	if ( (srcFrameIdx < path.size()-2) )
+		LocalCost += GetWeightedDistance(path[srcFrameIdx], path[srcFrameIdx+2], 2*gVMax, 2*gCCMax);
+	else
+		LocalCost *= 2;
+	
+	if ( LocalCost == dbltype::infinity() )
+			return dbltype::infinity();
+
+	dlocnX = gDetect[path[srcFrameIdx]].X;
+	dlocnY = gDetect[path[srcFrameIdx]].Y;
+	for (  k=startIdx; k < srcFrameIdx; ++k )	
+	{ 
+		dlocnX += gDetect[path[k]].X;
+		dlocnY += gDetect[path[k]].Y;
+	}
+	dlocnX /= (srcFrameIdx-startIdx+1);
+	dlocnY /= (srcFrameIdx-startIdx+1);
+
+	for ( k=srcFrameIdx; k < path.size(); ++k )
+	{
+		LocationCost += SQR(gDetect[path[k]].X - dlocnX) + SQR(gDetect[path[k]].Y - dlocnY);
+	}
+	LocationCost /= (path.size()-srcFrameIdx);
+	LocationCost = sqrt(LocationCost);
+
+	TotalCost = LocalCost + LocationCost;
+	if ( path.size() < 2*gWindowSize + 1 )
+	{
+		double LengthPenalty;
+		LengthPenalty = (2*gWindowSize + 1) - path.size();
+		TotalCost = 2*TotalCost*LengthPenalty; 
+	}
+
+	if (OcclusionCost > 1.0)
+		OcclusionCost *= 2;
+
+	TotalCost *= OcclusionCost;
+
+	if ( TotalCost < costEpsilon )
+		TotalCost = costEpsilon;
+
+	return TotalCost;
+}
+
diff --git a/src/cost.h b/src/cost.h
new file mode 100644
index 0000000..88e3fb0
--- /dev/null
+++ b/src/cost.h
@@ -0,0 +1,35 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+
+
+// Get cost from a path list.
+// path - vector of indices into gDetect, indicates current path being explored.
+// 
+// srcFrameIdx - the index into path index vector of the source point (start of new path).
+//		srcFrameIdx is trivially 0 if there is no history being used.
+// 
+// bCheck - If bCheck is true then only do a check to verify the path doesn't violate constraints.
+double GetCost(const std::vector<int>& path, int srcFrameIdx,int bCheck);
+
diff --git a/src/detection.cpp b/src/detection.cpp
new file mode 100644
index 0000000..60eca02
--- /dev/null
+++ b/src/detection.cpp
@@ -0,0 +1,232 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include "tracker.h"
+
+int gImageWidth;
+int gImageHeight;
+
+int GetGlobalIdx(int t, int idx)
+{
+	if ( t >= gFrameHash.size() )
+		return -1;
+
+	if ( idx >= gFrameHash[t].size() )
+		return -1;
+
+	return (gFrameHash[t][idx]);
+}
+
+int GetTime(int globalIdx)
+{
+	if ( globalIdx >= gDetect.size() )
+		return -1;
+
+	return (gDetect[globalIdx].time);
+}
+
+unsigned int GetLinearCoordIdx(int X, int Y)
+{
+	return X + gImageWidth * Y;
+}
+
+void MakeCoordSet(std::set<int>& coordSet, int detIdx)
+{
+	coordSet.clear();
+
+	int numCoord = gDetect[detIdx].pixelCoords.size();
+	for ( int i=0; i < numCoord; ++i )
+	{
+		unsigned int uniqueLinIdx = GetLinearCoordIdx(gDetect[detIdx].pixelCoords[i].X, gDetect[detIdx].pixelCoords[i].Y);
+		coordSet.insert(uniqueLinIdx);
+	}
+}
+
+double CalcConnectedDist(const std::set<int>& coordSet, int detIdx, int nextDetIdx)
+{
+	SDetection& curDet = gDetect[detIdx];
+	SDetection& nextDet = gDetect[nextDetIdx];
+
+	// Don't bother to calculate CC distance when past center of mass velocity threshold
+	double comDistSq = SQR(curDet.X - nextDet.X) + SQR(curDet.Y - nextDet.Y);
+	if ( comDistSq > SQR(gVMax) )
+		return dbltype::infinity();
+
+	// Overlap distance |A intersect B| / min(|A|,|B|);
+	int overlapCount = 0;
+	for ( int i=0; i < nextDet.pixelCoords.size(); ++i )
+		overlapCount += coordSet.count(GetLinearCoordIdx(nextDet.pixelCoords[i].X, nextDet.pixelCoords[i].Y));
+
+	if ( overlapCount > 0 )
+	{
+		int compSize = std::min(curDet.pixelCoords.size(), nextDet.pixelCoords.size());
+		return (1.0 - ((double) overlapCount) / compSize);
+	}
+
+	// If no overlap then find the minimum pixel distance
+	double minDistSq = dbltype::infinity();
+	for ( int i=0; i < curDet.pixelCoords.size(); ++i )
+	{
+		for ( int j=0; j < nextDet.pixelCoords.size(); ++j )
+		{
+			double chkDistSq = SQR(curDet.pixelCoords[i].X - nextDet.pixelCoords[j].X) + SQR(curDet.pixelCoords[i].Y - nextDet.pixelCoords[j].Y);
+			if ( chkDistSq > minDistSq )
+				continue;
+
+			minDistSq = chkDistSq;
+		}
+	}
+
+	return sqrt(minDistSq);
+}
+
+void CalcConnectedDistToFrame(const std::set<int>& coordSet, int detIdx, int time)
+{
+	SDetection& curDet = gDetect[detIdx];
+
+	if ( time >= gFrameHash.size() )
+		return;
+
+	for ( int i=0; i < gFrameHash[time].size(); ++i )
+	{
+		int nextDetIdx = GetGlobalIdx(time, i);
+
+		double connDist = CalcConnectedDist(coordSet, detIdx, nextDetIdx);
+		if ( connDist == dbltype::infinity() )
+			continue;
+
+		curDet.connCompDist.insert(std::pair<int,double>(nextDetIdx, connDist));
+	}
+}
+
+// Precalculates connected component distances for each detection
+// up to two frames into the future
+int CalcConnectedDistances()
+{
+	std::set<int> coordSet;
+
+	for ( int t=0; t < gNumFrames-1; ++t )
+	{
+		for ( int i=0; i < gFrameHash[t].size(); ++i )
+		{
+			int detIdx = GetGlobalIdx(t,i);
+
+			MakeCoordSet(coordSet, detIdx);
+			CalcConnectedDistToFrame(coordSet, detIdx, t+1);
+			CalcConnectedDistToFrame(coordSet, detIdx, t+2);
+		}
+	}
+
+	return 0;
+}
+
+// Read text segmentation data from a file
+int ReadSegmentationData(char* filename)
+{
+	FILE* fp;
+
+	fp = fopen(filename, "r");
+	if ( !fp )
+		return -1;
+
+	fscanf(fp, "%d %d\n", &gImageWidth, &gImageHeight);
+	fscanf(fp, "%d %d\n\n", &gNumFrames, &gNumDetections);
+
+	gDetect.resize(gNumDetections);
+	gFrameHash.resize(gNumFrames);
+
+	int totalRead = 0;
+
+	for ( int t=0; t < gNumFrames; ++t )
+	{
+		int frameDetections;
+		fscanf(fp, "%d\n", &frameDetections);
+
+		gFrameHash[t].resize(frameDetections);
+
+		for ( int ptItr = 0; ptItr < frameDetections; ++ptItr )
+		{
+			gFrameHash[t][ptItr] = totalRead + ptItr;
+
+			int numPixels;
+			SDetection* curPt = &gDetect[totalRead + ptItr];
+			fscanf(fp, "%lf %lf %d:", &(curPt->X), &(curPt->Y), &numPixels);
+
+			curPt->time = t;
+
+			// Read in pixel coordinates for each pixel in the detection
+			// This is used to calculate connected component distances
+			curPt->pixelCoords.resize(numPixels);
+			int xPix, yPix;
+			for ( int pixItr = 0; pixItr < numPixels; ++pixItr )
+			{
+				fscanf(fp, " (%d,%d)", &xPix,&yPix);
+				curPt->pixelCoords[pixItr].X = xPix;
+				curPt->pixelCoords[pixItr].Y = yPix;
+			}
+
+			fscanf(fp,"\n");
+		}
+
+		totalRead += frameDetections;
+	}
+
+	fclose(fp);
+
+	return gNumFrames;
+}
+
+int ReadDetectionData(int argc, char* argv[])
+{
+	int checkResult;
+
+	if ( argc < 1)
+		return -1;
+
+	checkResult = ReadSegmentationData(argv[0]);
+	if ( checkResult < 0 )
+		return -1;
+
+	checkResult = CalcConnectedDistances();
+	if ( checkResult < 0 )
+		return -1;
+
+	gConnectOut.resize(gDetect.size());
+	gConnectIn.resize(gDetect.size());
+
+	gAssignedConnectIn.resize(gDetect.size());
+	gAssignedConnectOut.resize(gDetect.size());
+
+	gAssignedTrackID.resize(gDetect.size());
+
+	for ( int i=0; i < gDetect.size(); ++i )
+	{
+		gAssignedConnectIn[i] = -1;
+		gAssignedConnectOut[i] = -1;
+		gAssignedTrackID[i] = -1;
+	}
+
+	return 1;
+}
+
diff --git a/src/detection.h b/src/detection.h
new file mode 100644
index 0000000..58c82a8
--- /dev/null
+++ b/src/detection.h
@@ -0,0 +1,62 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+// Detection related types and variables
+struct SPixelCoord
+{
+	int X;
+	int Y;
+};
+
+struct SDetection
+{
+	// Frame the detection is in
+	int time;
+
+	// centroid coordinates
+	double X;
+	double Y;
+	
+	// Pixel coordinates
+	std::vector<SPixelCoord> pixelCoords;
+
+	// Connected component distances
+	std::map<int,double> connCompDist;
+};
+
+// Read and initialize detection related data.  All globals listed below must be filled or initialized by the end of this routine.
+
+// Globals:
+//  gDetect - filled with detection data for all frames
+//  gFrameHash - lists indices (into gDetect) for each frame of movie
+
+//  gConnectOut,gConnectIn - initialized to numPts(total detections) empty std::maps each
+//  gAssignedConnectIn - same size as gConnectIn, initialized to -1
+//  gAssignedConnectOut - same as gAssignedConnectIn, these are for quick lookup of assigned paths
+int ReadDetectionData(int argc, char* argv[]);
+
+int GetGlobalIdx(int t, int idx);
+int GetTime(int globalIdx);
+int GetLocalIdx(int globalIdx);
+
diff --git a/src/paths.cpp b/src/paths.cpp
new file mode 100644
index 0000000..0bdec61
--- /dev/null
+++ b/src/paths.cpp
@@ -0,0 +1,144 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include "tracker.h"
+
+int BuildHistoryPath(CSourcePath* historyPath, CSourcePath* path, int occlLookback)
+{
+	int pathStartGIdx = path->index[0];
+
+	// Find the assigned in-edge
+	int histTrackID = -1;
+	int histIdx = gAssignedConnectIn[pathStartGIdx];
+	if ( histIdx >=0 )
+	{
+		CSourcePath* histpath = gConnectIn[pathStartGIdx][histIdx];
+		// Single segment agreement requirement
+		if ( histpath->index.size() > 2	)
+			histTrackID = histpath->trackletID;
+	}
+
+	if ( histTrackID >= 0 )
+	{
+		tPathList::iterator histIter = gAssignedTracklets[histTrackID].begin();
+		while ( histIter != gAssignedTracklets[histTrackID].end() )
+		{
+			CSourcePath* curPath = *histIter;
+
+			historyPath->PushPoint(curPath->index[0]);
+			++histIter;
+		}
+	}
+
+	for ( int i=0; i < path->index.size(); ++i )
+		historyPath->PushPoint(path->index[i]);
+
+	return histTrackID;
+}
+
+int DepthFirstBestPathSearch(CSourcePath path, int bestGIdx, int t, int tEnd, int occlLookback)
+{
+	bool bFinishedSearch = true;
+	if ( t < tEnd )
+	{
+		for ( int nextPt=0; nextPt < gFrameHash[t].size(); ++nextPt )
+		{
+			int nextGIdx = GetGlobalIdx(t, nextPt);
+			path.PushPoint(nextGIdx);
+			double chkCost = GetCost(path.index, 0, 1);
+			path.PopPoint();
+
+			if ( chkCost == dbltype::infinity() )
+				continue;
+
+			bFinishedSearch = false;
+
+			path.PushPoint(nextGIdx);
+			bestGIdx = DepthFirstBestPathSearch(path, bestGIdx, t+1, tEnd, occlLookback);
+			path.PopPoint();
+		}
+	}
+
+	if ( bFinishedSearch && (path.index.size() > 1) )
+	{
+		CSourcePath historyPath;
+
+		int startGIdx = path.index[0];
+		int nextGIdx = path.index[1];
+
+		int historyTrackID = BuildHistoryPath(&historyPath, &path, occlLookback);
+		int srcPathIdx = historyPath.index.size() - path.index.size();
+
+		double newPathCost = GetCost(historyPath.index, srcPathIdx, 0);
+		if ( newPathCost == dbltype::infinity() )
+			return bestGIdx;
+
+		path.trackletID = historyTrackID;
+		path.cost = newPathCost;
+
+		if ( gConnectOut[startGIdx].count(nextGIdx) == 0 )
+		{
+			CSourcePath* newPath = new CSourcePath(path);
+			gConnectOut[startGIdx].insert(std::pair<int,CSourcePath*>(nextGIdx, newPath));
+			gConnectIn[nextGIdx].insert(std::pair<int,CSourcePath*>(startGIdx, newPath));
+		}
+		else if ( newPathCost < gConnectOut[startGIdx][nextGIdx]->cost )
+		{
+			*(gConnectOut[startGIdx][nextGIdx]) = path;
+		}
+
+		if ( bestGIdx < 0 || newPathCost < gConnectOut[startGIdx][bestGIdx]->cost )
+		{
+			bestGIdx = nextGIdx;
+		}
+	}
+
+	return bestGIdx;
+}
+
+void BuildBestPaths(std::map<int,int>& bestOutEdges, int t, int occlLookback)
+{
+	if ( t-occlLookback < 0 )
+		return;
+
+	int numDetections = gFrameHash[t-occlLookback].size();
+
+	int tEnd = std::min<int>(t+gWindowSize, gNumFrames);
+
+	for ( int srcIdx=0; srcIdx < numDetections; ++srcIdx )
+	{
+		int startGIdx = GetGlobalIdx(t-occlLookback, srcIdx); 
+		if ( occlLookback > 0 && gAssignedConnectOut[startGIdx] > 0 )
+			continue;
+
+		CSourcePath srcPath;
+		srcPath.PushPoint(startGIdx);
+		int bestGIdx = DepthFirstBestPathSearch(srcPath, -1, t+1, tEnd, occlLookback);
+		if ( bestGIdx >= 0 )
+		{
+			bestOutEdges[startGIdx] = bestGIdx;
+		}
+	}
+}
+
diff --git a/src/paths.h b/src/paths.h
new file mode 100644
index 0000000..6e6b853
--- /dev/null
+++ b/src/paths.h
@@ -0,0 +1,65 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include <vector>
+#include <list>
+#include <map>
+
+typedef std::numeric_limits<double> dbltype;
+
+class CSourcePath
+{
+public:
+	CSourcePath()
+	{
+		trackletID = -1;
+		cost = dbltype::infinity();
+	}
+
+	void PushPoint(int globalIdx)
+	{
+		index.push_back(globalIdx);
+	}
+
+	void PopPoint()
+	{
+		if ( index.size() <= 1 )
+			return;
+
+		index.pop_back();
+	}
+
+public:
+
+	int trackletID;
+	double cost;
+
+	std::vector<int> index;
+};
+
+int GetGlobalIdx(int t, int idx);
+int GetTime(int globalIdx);
+int GetLocalIdx(int globalIdx);
+void BuildBestPaths(std::map<int,int>& bestOutEdges, int t, int occlLookcback = 0);
+
diff --git a/src/tracker.cpp b/src/tracker.cpp
new file mode 100644
index 0000000..1858d32
--- /dev/null
+++ b/src/tracker.cpp
@@ -0,0 +1,218 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include "tracker.h"
+
+// Global variables
+int gNumFrames;
+int gNumDetections;
+
+std::vector<SDetection> gDetect;
+std::vector<std::vector<int>> gFrameHash;
+
+// Path-graph global variables
+std::vector<std::map<int,CSourcePath*>> gConnectOut;
+std::vector<std::map<int,CSourcePath*>> gConnectIn;
+
+// For quick edge lookup from point (like inID/outID)
+std::vector<int> gAssignedConnectOut;
+std::vector<int> gAssignedConnectIn;
+std::vector<int> gAssignedTrackID;
+
+// Final tracklet assignments
+std::vector<tPathList> gAssignedTracklets;
+
+// Global tracking parameters
+int gWindowSize;
+double gVMax;
+double gCCMax;
+
+
+void WriteTracklets(int argc, char* argv[], int argIdx)
+{
+	std::map<int,CSourcePath*>::iterator cIter;
+	CSourcePath* inPath;
+	double dinCost;
+
+	if ( argIdx >= argc )
+		return;
+
+	FILE* fPathFile = fopen(argv[argIdx], "w");
+
+	if ( !fPathFile )
+		return;
+
+	for ( int i=0; i < gAssignedTracklets.size(); ++i )
+	{
+		tPathList::iterator trackIter;
+		tPathList::iterator lastPathIter = (--gAssignedTracklets[i].end());
+		for ( trackIter=gAssignedTracklets[i].begin(); trackIter != gAssignedTracklets[i].end(); ++trackIter )
+		{
+			fprintf(fPathFile, "%d,%d,%d\n", i+1,(*trackIter)->index[0] + 1,(*trackIter)->index[1] + 1);
+		}
+	}
+				
+	fprintf(fPathFile, "-1,-1,-1\n");
+	for ( int i=0; i < gDetect.size(); ++i )
+	{
+		cIter = gConnectIn[i].begin();
+		for ( int j=0; j < gConnectIn[i].size(); ++j )
+		{
+			inPath=cIter->second;
+			dinCost=inPath->cost;
+			if (dinCost!=dinCost) // test for -1.#IND!
+				continue;
+			fprintf(fPathFile, "%d,%d,%lf\n",i+1,cIter->first+1,dinCost);
+			cIter++;
+
+		}
+	}
+
+	fclose(fPathFile);
+}
+
+int FindMinInEdgeIdx(int nextGIdx)
+{
+	double cmin = dbltype::infinity();
+	int bestIdx = -1;
+
+	std::map<int,CSourcePath*>::iterator cIter = gConnectIn[nextGIdx].begin();
+	while ( cIter != gConnectIn[nextGIdx].end() )
+	{
+		CSourcePath* inPath = cIter->second;
+		if ( inPath->cost < cmin )
+		{
+			cmin = inPath->cost;
+			bestIdx = cIter->first;
+		}
+
+		++cIter;
+	}
+
+	return bestIdx;
+}
+
+int FindMinCostIdx(std::vector<CSourcePath*>& edges)
+{
+	int minidx = -1;
+	double mincost = dbltype::infinity();
+	for ( int i=0; i < edges.size(); ++i )
+	{
+		if ( edges[i]->cost < mincost )
+		{
+			minidx = i;
+			mincost = edges[i]->cost;
+		}
+	}
+
+	return minidx;
+}
+
+int main(int argc, char* argv[])
+{
+	system("echo %TIME% > ttt.txt");
+
+	// Set default gate values and window size.
+	gWindowSize = 4;
+	gVMax = 40.0;
+	gCCMax = 20.0;
+	
+	int nxtArg = 1;
+	// Specify all the parameters (or none)
+	if ( argc > 4 )
+	{
+		nxtArg = 3;
+		
+		sscanf(argv[1], "%d", &gWindowSize);
+		sscanf(argv[2], "%lf", &gVMax);
+		sscanf(argv[3], "%lf", &gCCMax);
+	}
+
+	argc += nxtArg;
+	argv += nxtArg;
+	
+	int outputArgIdx = ReadDetectionData(argc, argv);
+
+	if ( outputArgIdx < 0 )
+		return 0;
+
+	system("echo %TIME% >> ttt.txt");
+	
+	argc += outputArgIdx;
+	argv += outputArgIdx;	
+
+	std::map<int,int> bestOutEdges;
+	for ( int t=0; t < gFrameHash.size()-1; ++t )
+	{
+		bestOutEdges.clear();
+		BuildBestPaths(bestOutEdges, t);
+
+		//Occlusions
+		for ( int iLookback=1; iLookback < 2; ++iLookback )
+		{
+			BuildBestPaths(bestOutEdges, t, iLookback);
+		}
+
+		printf("t = %d, %d detections\n", t, gFrameHash[t].size());
+
+		for ( int destPtIdx=0; destPtIdx < gFrameHash[t+1].size(); ++destPtIdx)
+		{
+			int nextGIdx = GetGlobalIdx(t+1, destPtIdx);
+			int bestTrackletIdx = FindMinInEdgeIdx(nextGIdx);
+			if ( bestTrackletIdx < 0 )
+				continue;
+
+			if ( (bestOutEdges.count(bestTrackletIdx) == 0) || bestOutEdges[bestTrackletIdx] != nextGIdx )
+				continue;
+
+			int newTrackletID = gConnectOut[bestTrackletIdx][nextGIdx]->trackletID;
+
+			if ( newTrackletID < 0 )
+			{
+				//Add new tracklet to list etc. and set id
+				newTrackletID = gAssignedTracklets.size();
+				gConnectOut[bestTrackletIdx][nextGIdx]->trackletID = newTrackletID;
+
+				tPathList newList;
+				gAssignedTracklets.push_back(newList);
+
+				gAssignedTrackID[bestTrackletIdx] = newTrackletID;
+			}
+
+			//Add path to tracklet list
+			gAssignedTracklets[newTrackletID].push_back(gConnectOut[bestTrackletIdx][nextGIdx]);
+
+			//Keep track of assignment for fast lookup
+			gAssignedConnectIn[nextGIdx] = bestTrackletIdx;
+			gAssignedConnectOut[bestTrackletIdx] = nextGIdx;
+			gAssignedTrackID[nextGIdx] = newTrackletID;
+		}
+	}
+
+	WriteTracklets(argc, argv, 0);
+
+	system("echo %TIME% >> ttt.txt");
+
+}
+
diff --git a/src/tracker.h b/src/tracker.h
new file mode 100644
index 0000000..a14d4eb
--- /dev/null
+++ b/src/tracker.h
@@ -0,0 +1,77 @@
+//***********************************************************************
+//
+//    Copyright 2013 Andrew Cohen and Mark Winter
+// 
+//    This file is part of the Multitemporal Association Tracker. See
+//    http://bioimage.coe.drexel.edu for details
+// 
+//    LEVer is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+// 
+//    LEVer is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+// 
+//    You should have received a copy of the GNU General Public License
+//    along with LEVer in file "gnu gpl v3.txt".  If not, see 
+//    <http://www.gnu.org/licenses/>.
+//
+//
+//***********************************************************************
+
+#include <stdio.h>
+
+#include <list>
+#include <vector>
+#include <set>
+#include <map>
+#include <limits>
+
+#include "detection.h"
+#include "cost.h"
+#include "paths.h"
+
+// Convenience defines
+#define SQR(x) ((x)*(x))
+#define DOT(x1,y1,x2,y2) ((x1)*(x2) + (y1)*(y2))
+#define LENGTH(x,y) (sqrt((SQR(x))+(SQR(y))))
+#define SIGN(x) (((x) >= 0.0) ? (1.0) : (-1.0) )
+
+typedef char int8;
+typedef short int16;
+typedef long int32;
+//typedef long long int64;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned long uint32;
+//typedef unsigned long long uint64;
+
+typedef std::list<CSourcePath*> tPathList;
+
+// Detection related global variables
+extern int gNumFrames;
+extern int gNumDetections;
+
+extern std::vector<SDetection> gDetect;
+extern std::vector<std::vector<int>> gFrameHash;
+
+// Path-graph global variables
+extern std::vector<std::map<int,CSourcePath*>> gConnectOut;
+extern std::vector<std::map<int,CSourcePath*>> gConnectIn;
+
+// For quick edge lookup from point (like inID/outID)
+extern std::vector<int> gAssignedConnectOut;
+extern std::vector<int> gAssignedConnectIn;
+extern std::vector<int> gAssignedTrackID;
+
+// Final tracklet assignments
+extern std::vector<tPathList> gAssignedTracklets;
+
+// Global tracking parameters
+extern int gWindowSize;
+extern double gVMax;
+extern double gCCMax;
+
-- 
GitLab