diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 96ef366..41b74cc 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,119 +2,65 @@ name: Build and Test
on:
push:
- branches: [ main ]
+ branches: [main]
pull_request:
- branches: [ main ]
+ branches: [main]
jobs:
-
build-and-test:
name: Build and test
strategy:
matrix:
- os: [ubuntu-latest]
- #os: [ubuntu-latest, windows-latest, macos-latest]
+ os: [ubuntu-latest]
+ #os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
+ - uses: actions/checkout@v2
- - uses: actions/checkout@v2
-
- - name: Setup .NET Core 2.1
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: 2.1.x
- - name: Setup .NET Core 3.1
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: 3.1.x
- - name: Setup .NET Core 5.0
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: 5.0.x
-
- - name: Restore dependencies
- run: dotnet restore
+ - name: Setup .NET Core 9.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 9.0.x
- - name: Build
- run: dotnet build --no-restore
+ - name: Restore dependencies
+ run: dotnet restore
- - name: Test with dotnet
- run: dotnet test --no-restore --verbosity normal --logger trx --results-directory "TestResults-${{ matrix.os }}"
+ - name: Build
+ run: dotnet build --no-restore
- - name: Upload dotnet test results
- uses: actions/upload-artifact@v2
- with:
- name: dotnet-results-${{ matrix.os }}
- path: TestResults-${{ matrix.os }}
- # Use always() to always run this step to publish test results when there are test failures
- if: ${{ always() }}
-
-
- sonar:
- runs-on: windows-latest
- needs: build-and-test
- steps:
+ - name: Test with dotnet
+ run: dotnet test --no-restore --verbosity normal --logger trx --results-directory "TestResults-${{ matrix.os }}"
- - name: Set up JDK 11
- uses: actions/setup-java@v1
- with:
- java-version: 1.11
- - uses: actions/checkout@v2
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- - name: Cache SonarCloud packages
- uses: actions/cache@v1
- with:
- path: ~\sonar\cache
- key: ${{ runner.os }}-sonar
- restore-keys: ${{ runner.os }}-sonar
- - name: Cache SonarCloud scanner
- id: cache-sonar-scanner
- uses: actions/cache@v1
- with:
- path: .\.sonar\scanner
- key: ${{ runner.os }}-sonar-scanner
- restore-keys: ${{ runner.os }}-sonar-scanner
- - name: Install SonarCloud scanner
- if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
- shell: powershell
- run: |
- New-Item -Path .\.sonar\scanner -ItemType Directory
- dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
- - name: Build and analyze
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- shell: powershell
- run: |
- .\.sonar\scanner\dotnet-sonarscanner begin /k:"keesschollaart81_SortCS" /o:"keesschollaart81" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io"
- dotnet build
- .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
+ - name: Upload dotnet test results
+ uses: actions/upload-artifact@v4
+ with:
+ name: dotnet-results-${{ matrix.os }}
+ path: TestResults-${{ matrix.os }}
+ # Use always() to always run this step to publish test results when there are test failures
+ if: ${{ always() }}
deploy:
runs-on: ubuntu-latest
needs: build-and-test
steps:
+ - uses: actions/checkout@v2
+
+ - name: Setup .NET Core 9.0
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 9.0.x
- - uses: actions/checkout@v2
+ - name: Restore dependencies
+ run: dotnet restore
+ working-directory: src/SortCS
- - name: Setup .NET Core 5.0
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: 5.0.x
-
- - name: Restore dependencies
- run: dotnet restore
- working-directory: src/SortCS
-
- - name: Build
- run: dotnet build -c Release --no-restore
- working-directory: src/SortCS
+ - name: Build
+ run: dotnet build -c Release --no-restore
+ working-directory: src/SortCS
- - name: Build
- run: dotnet pack -c Release --no-restore
- working-directory: src/SortCS
-
\ No newline at end of file
+ - name: Build
+ run: dotnet pack -c Release --no-restore
+ working-directory: src/SortCS
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ae464fd..9a5df36 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,10 +21,10 @@ jobs:
- name: Set VERSION variable from tag
run: echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
- - name: Setup .NET Core 5.0
+ - name: Setup .NET Core 9.0
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 5.0.x
+ dotnet-version: 9.0.x
- name: Build
working-directory: src/SortCS
diff --git a/SortCS.sln b/SortCS.sln
index 4f31d11..30ecbf2 100644
--- a/SortCS.sln
+++ b/SortCS.sln
@@ -16,10 +16,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
LICENSE = LICENSE
README.md = README.md
.github\workflows\release.yml = .github\workflows\release.yml
+ sonar-project.properties = sonar-project.properties
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SortCS.Tests", "src\SortCS.Tests\SortCS.Tests.csproj", "{13002E85-6B03-49DA-9700-906A24692C98}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SortCS.Benchmarks", "src\SortCS.Benchmarks\SortCS.Benchmarks.csproj", "{9A2468E6-4556-4C7C-8D29-996200A10EF3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -38,6 +41,10 @@ Global
{13002E85-6B03-49DA-9700-906A24692C98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13002E85-6B03-49DA-9700-906A24692C98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13002E85-6B03-49DA-9700-906A24692C98}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A2468E6-4556-4C7C-8D29-996200A10EF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A2468E6-4556-4C7C-8D29-996200A10EF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A2468E6-4556-4C7C-8D29-996200A10EF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A2468E6-4556-4C7C-8D29-996200A10EF3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -45,4 +52,6 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C31716C-280A-44DD-ADAB-E48CEDFBF779}
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ EndGlobalSection
EndGlobal
diff --git a/analyzers.targets b/analyzers.targets
index 801eed6..0f340e9 100644
--- a/analyzers.targets
+++ b/analyzers.targets
@@ -1,32 +1,27 @@
-
+
-
- true
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+ true
+
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/resources/logo.psd b/resources/logo.psd
index a2797a4..7b49138 100644
Binary files a/resources/logo.psd and b/resources/logo.psd differ
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000..8f0d442
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,16 @@
+sonar.projectKey=keesschollaart81_SortCS
+sonar.organization=keesschollaart81
+
+# This is the name and version displayed in the SonarCloud UI.
+sonar.projectName=SortCS
+#sonar.projectVersion=1.0
+
+# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
+sonar.sources=.
+
+# Encoding of the source code. Default is default system encoding
+#sonar.sourceEncoding=UTF-8
+
+# Exclusions
+sonar.exclusions=**/Benchmarks/**,**/obj/**,**/*.dll
+sonar.coverage.exclusions=**/*.Tests.cs,**/*.Tests/**
diff --git a/src/SortCS.Benchmarks/Program.cs b/src/SortCS.Benchmarks/Program.cs
new file mode 100644
index 0000000..5093cae
--- /dev/null
+++ b/src/SortCS.Benchmarks/Program.cs
@@ -0,0 +1,52 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Running;
+using SortCS;
+using System.Drawing;
+
+BenchmarkRunner.Run();
+
+[MemoryDiagnoser]
+public class SortCSBenchmarks
+{
+ private ITracker? _tracker;
+ private List? _frames;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _tracker = new SortTracker();
+ _frames = GenerateTestFrames(100, 10);
+ }
+
+ [Benchmark]
+ public void TrackMultipleFrames()
+ {
+ foreach (var frame in _frames ?? [])
+ {
+ _tracker!.Track(frame);
+ }
+ }
+
+ private List GenerateTestFrames(int numFrames, int objectsPerFrame)
+ {
+ var random = new Random(42);
+ var frames = new List();
+
+ for (var i = 0; i < numFrames; i++)
+ {
+ var objects = new RectangleF[objectsPerFrame];
+ for (var j = 0; j < objectsPerFrame; j++)
+ {
+ objects[j] = new RectangleF(
+ random.Next(0, 1000),
+ random.Next(0, 1000),
+ random.Next(50, 200),
+ random.Next(50, 200)
+ );
+ }
+ frames.Add(objects);
+ }
+
+ return frames;
+ }
+}
\ No newline at end of file
diff --git a/src/SortCS.Benchmarks/SortCS.Benchmarks.csproj b/src/SortCS.Benchmarks/SortCS.Benchmarks.csproj
new file mode 100644
index 0000000..ae86ee2
--- /dev/null
+++ b/src/SortCS.Benchmarks/SortCS.Benchmarks.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SortCS.Evaluate/Program.cs b/src/SortCS.Evaluate/Program.cs
index 14f9550..004d232 100644
--- a/src/SortCS.Evaluate/Program.cs
+++ b/src/SortCS.Evaluate/Program.cs
@@ -8,68 +8,71 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-namespace SortCS.Evaluate
+namespace SortCS.Evaluate;
+
+class Program
{
- class Program
- {
- private static ILogger _logger;
+ private static ILogger _logger;
- static async Task Main(string[] args)
+ static async Task Main(string[] args)
+ {
+ var services = new ServiceCollection();
+ services.AddLogging(loggerBuilder =>
{
- var services = new ServiceCollection();
- services.AddLogging(loggerBuilder =>
- {
- loggerBuilder.ClearProviders();
- loggerBuilder.AddConsole();
- });
- var serviceProvider = services.BuildServiceProvider();
+ loggerBuilder.ClearProviders();
+ loggerBuilder.AddConsole();
+ });
+ var serviceProvider = services.BuildServiceProvider();
- _logger = serviceProvider.GetService>();
+ _logger = serviceProvider.GetService>();
- var rootCommand = new RootCommand
- {
- new Option(
- "--data-folder",
- getDefaultValue: () => new DirectoryInfo(@"../../../../../../TrackEval/data"), // Sssuming SortCS/src/SortCS.Evaluate/bin/debug/net5.0 is working directory
- description: "Location where data is stored using this format: https://github.com/JonathonLuiten/TrackEval/blob/master/docs/MOTChallenge-format.txt"),
- new Option(
- "--benchmark",
- getDefaultValue: () => "MOT20",
- description: "Name of the benchmark, e.g. MOT15, MO16, MOT17 or MOT20 (default : MOT20)"),
- new Option(
- "--split-to-eval",
- getDefaultValue: () => "train",
- description: "Data split on which to evalute e.g. train, test (default : train)"),
- };
+ var dataFolderOption = new Option(
+ "--data-folder",
+ getDefaultValue: () => new DirectoryInfo(@"../../../../../../TrackEval/data"), // Sssuming SortCS/src/SortCS.Evaluate/bin/debug/net5.0 is working directory
+ description: "Location where data is stored using this format: https://github.com/JonathonLuiten/TrackEval/blob/master/docs/MOTChallenge-format.txt");
- rootCommand.Description = "App to evaluate the SortCS tracking algoritm";
- rootCommand.Handler = CommandHandler.Create(async (dataFolder, benchmark, splitToEval) =>
- {
- if (!dataFolder.Exists || !dataFolder.GetDirectories().Any())
- {
- await DownloadTrackEvalExampleAsync(dataFolder);
- }
- var sortCsEvaluator = new SortCsEvaluator(dataFolder, benchmark, splitToEval, serviceProvider.GetService>());
- await sortCsEvaluator.EvaluateAsync();
- });
+ var benchmarkOption = new Option(
+ "--benchmark",
+ getDefaultValue: () => "MOT20",
+ description: "Name of the benchmark, e.g. MOT15, MO16, MOT17 or MOT20 (default : MOT20)");
- return await rootCommand.InvokeAsync(args);
- }
+ var splitOption = new Option(
+ "--split-to-eval",
+ getDefaultValue: () => "train",
+ description: "Data split on which to evalute e.g. train, test (default : train)");
- private static async Task DownloadTrackEvalExampleAsync(DirectoryInfo groundTruthFolder)
+ var rootCommand = new RootCommand
{
- var dataZipUrl = "https://omnomnom.vision.rwth-aachen.de/data/TrackEval/data.zip";
- groundTruthFolder.Create();
- var targetZipFile = Path.Combine(groundTruthFolder.ToString(), "..", "data.zip");
- _logger.LogInformation(Path.GetFullPath(targetZipFile));
+ dataFolderOption,benchmarkOption,splitOption
+ };
+
+ rootCommand.Description = "App to evaluate the SortCS tracking algoritm";
+ rootCommand.SetHandler(async (dataFolder, benchmark, splitToEval) =>
+ {
+ if (!dataFolder.Exists || !dataFolder.GetDirectories().Any())
+ {
+ await DownloadTrackEvalExampleAsync(dataFolder);
+ }
+ var sortCsEvaluator = new SortCsEvaluator(dataFolder, benchmark, splitToEval, serviceProvider.GetService>());
+ await sortCsEvaluator.EvaluateAsync();
+ }, dataFolderOption, benchmarkOption, splitOption);
+
+ return await rootCommand.InvokeAsync(args);
+ }
+
+ private static async Task DownloadTrackEvalExampleAsync(DirectoryInfo groundTruthFolder)
+ {
+ var dataZipUrl = "https://omnomnom.vision.rwth-aachen.de/data/TrackEval/data.zip";
+ groundTruthFolder.Create();
+ var targetZipFile = Path.Combine(groundTruthFolder.ToString(), "..", "data.zip");
+ _logger.LogInformation(Path.GetFullPath(targetZipFile));
- _logger.LogInformation($"Downloading data.zip (150mb) from {dataZipUrl} to {targetZipFile}");
- using var httpClient = new HttpClient();
- var zipStream = await httpClient.GetStreamAsync(dataZipUrl);
- using var fs = new FileStream(targetZipFile, FileMode.CreateNew);
- await zipStream.CopyToAsync(fs);
- ZipFile.ExtractToDirectory(targetZipFile, Path.Combine(groundTruthFolder.ToString(), ".."));
- _logger.LogInformation("data.zip downloaded & extracted");
- }
+ _logger.LogInformation($"Downloading data.zip (150mb) from {dataZipUrl} to {targetZipFile}");
+ using var httpClient = new HttpClient();
+ var zipStream = await httpClient.GetStreamAsync(dataZipUrl);
+ using var fs = new FileStream(targetZipFile, FileMode.CreateNew);
+ await zipStream.CopyToAsync(fs);
+ ZipFile.ExtractToDirectory(targetZipFile, Path.Combine(groundTruthFolder.ToString(), ".."));
+ _logger.LogInformation("data.zip downloaded & extracted");
}
-}
+}
\ No newline at end of file
diff --git a/src/SortCS.Evaluate/SortCS.Evaluate.csproj b/src/SortCS.Evaluate/SortCS.Evaluate.csproj
index b376855..b5ed445 100644
--- a/src/SortCS.Evaluate/SortCS.Evaluate.csproj
+++ b/src/SortCS.Evaluate/SortCS.Evaluate.csproj
@@ -2,14 +2,14 @@
Exe
- net5.0
+ net9.0
latest
-
-
+
+
diff --git a/src/SortCS.Evaluate/SortCsEvaluator.cs b/src/SortCS.Evaluate/SortCsEvaluator.cs
index b787190..987dd12 100644
--- a/src/SortCS.Evaluate/SortCsEvaluator.cs
+++ b/src/SortCS.Evaluate/SortCsEvaluator.cs
@@ -9,134 +9,133 @@
using Microsoft.Extensions.Logging;
using System.Diagnostics;
-namespace SortCS.Evaluate
+namespace SortCS.Evaluate;
+
+public class SortCsEvaluator
{
- public class SortCsEvaluator
- {
- private readonly DirectoryInfo _dataFolderMot;
+ private readonly DirectoryInfo _dataFolderMot;
- private readonly DirectoryInfo _destinationDir;
- private readonly ILogger _logger;
+ private readonly DirectoryInfo _destinationDir;
+ private readonly ILogger _logger;
- public SortCsEvaluator(DirectoryInfo dataFolder, string benchmark, string splitToEval, ILogger logger)
+ public SortCsEvaluator(DirectoryInfo dataFolder, string benchmark, string splitToEval, ILogger logger)
+ {
+ _dataFolderMot = new DirectoryInfo(Path.Combine($"{dataFolder}", "gt", "mot_challenge", $"{benchmark}-{splitToEval}"));
+ _destinationDir = new DirectoryInfo(Path.Combine($"{dataFolder}", "trackers", "mot_challenge", $"{benchmark}-{splitToEval}", "SortCS", "data"));
+ if (_destinationDir.Exists)
{
- _dataFolderMot = new DirectoryInfo(Path.Combine($"{dataFolder}", "gt", "mot_challenge", $"{benchmark}-{splitToEval}"));
- _destinationDir = new DirectoryInfo(Path.Combine($"{dataFolder}", "trackers", "mot_challenge", $"{benchmark}-{splitToEval}", "SortCS", "data"));
- if (_destinationDir.Exists)
- {
- _destinationDir.Delete(true);
- }
- _destinationDir.Create();
- _logger = logger;
+ _destinationDir.Delete(true);
}
+ _destinationDir.Create();
+ _logger = logger;
+ }
- public async Task EvaluateAsync()
+ public async Task EvaluateAsync()
+ {
+ var stopwatch = Stopwatch.StartNew();
+ var tasks = new List>();
+ foreach (var benchmarkDir in _dataFolderMot.GetDirectories())
{
- var stopwatch = Stopwatch.StartNew();
- var tasks = new List>();
- foreach (var benchmarkDir in _dataFolderMot.GetDirectories())
- {
- tasks.Add(EvaluateBenchMark(benchmarkDir));
- }
- await Task.WhenAll(tasks);
- stopwatch.Stop();
- var totalFrames = tasks.Sum(x => x.Result);
- _logger.LogInformation("Finished evaluating {totalFrames} frames in {totalSeconds:0.} seconds ({fps:0.0} fps)", totalFrames, stopwatch.Elapsed.TotalSeconds, totalFrames / stopwatch.Elapsed.TotalSeconds);
+ tasks.Add(EvaluateBenchMark(benchmarkDir));
}
+ await Task.WhenAll(tasks);
+ stopwatch.Stop();
+ var totalFrames = tasks.Sum(x => x.Result);
+ _logger.LogInformation("Finished evaluating {totalFrames} frames in {totalSeconds:0.} seconds ({fps:0.0} fps)", totalFrames, stopwatch.Elapsed.TotalSeconds, totalFrames / stopwatch.Elapsed.TotalSeconds);
+ }
- private async Task EvaluateBenchMark(DirectoryInfo benchmarkFolder)
+ private async Task EvaluateBenchMark(DirectoryInfo benchmarkFolder)
+ {
+ try
{
- try
- {
- var detFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "gt", "gt.txt"));
- var sequenceIniFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "seqinfo.ini"));
+ var detFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "gt", "gt.txt"));
+ var sequenceIniFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "seqinfo.ini"));
+ if (!detFile.Exists)
+ {
+ detFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "det", "det.txt"));
if (!detFile.Exists)
{
- detFile = new FileInfo(Path.Combine($"{benchmarkFolder}", "det", "det.txt"));
- if (!detFile.Exists)
- {
- _logger.LogWarning("Benchmark folder {benchmarkFolder} has no GroundTruth file (gt/gt.txt)", benchmarkFolder);
- return 0;
- }
+ _logger.LogWarning("Benchmark folder {benchmarkFolder} has no GroundTruth file (gt/gt.txt)", benchmarkFolder);
+ return 0;
}
+ }
- var benchmarkKey = GetBenchmarkKeyFromSeqIni(sequenceIniFile);
- var frames = await GetFramesFromFile(detFile);
+ var benchmarkKey = GetBenchmarkKeyFromSeqIni(sequenceIniFile);
+ var frames = await GetFramesFromFile(detFile);
- var path = Path.Combine(_destinationDir.ToString(), $"{benchmarkKey}.txt");
- _logger.LogInformation("Read {framesCount} frames, output to {outputFile}", frames.Count, path);
+ var path = Path.Combine(_destinationDir.ToString(), $"{benchmarkKey}.txt");
+ _logger.LogInformation("Read {framesCount} frames, output to {outputFile}", frames.Count, path);
- await FramesToDetectionsFile(frames, path);
+ await FramesToDetectionsFile(frames, path);
- return frames.Count;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Exception evaluating benchmark {benchmarkFolder}: {ex.Message}", benchmarkFolder, ex.Message);
- throw;
- }
+ return frames.Count;
}
-
- private async Task FramesToDetectionsFile(Dictionary> frames, string path)
+ catch (Exception ex)
{
- using var file = new StreamWriter(path, false);
-
- ITracker tracker = new SortTracker(_logger);
- foreach (var frame in frames)
- {
- var tracks = tracker.Track(frame.Value);
- foreach (var track in tracks)
- {
- if (track.State == TrackState.Started || track.State == TrackState.Active)
- {
- //var boxForLog = track.History.Last();
- var boxForLog = track.Prediction;
- //, , , , , , , , ,
- var line = $"{frame.Key:0.},{track.TrackId:0.},{boxForLog.Left:0.},{boxForLog.Top:0.},{boxForLog.Width:0.},{boxForLog.Height:0.},1,-1,-1,-1";
- await file.WriteLineAsync(line);
- }
- }
- }
+ _logger.LogError(ex, "Exception evaluating benchmark {benchmarkFolder}: {ex.Message}", benchmarkFolder, ex.Message);
+ throw;
}
+ }
- private static string GetBenchmarkKeyFromSeqIni(FileInfo sequenceIniFile)
- {
- var iniString = File.ReadAllText(sequenceIniFile.FullName);
- var parser = new IniDataParser();
- var data = parser.Parse(iniString);
- var benchmarkKey = data["Sequence"]["name"];
- return benchmarkKey;
- }
+ private async Task FramesToDetectionsFile(Dictionary> frames, string path)
+ {
+ using var file = new StreamWriter(path, false);
- private static async Task>> GetFramesFromFile(FileInfo detFile)
+ ITracker tracker = new SortTracker(_logger);
+ foreach (var frame in frames)
{
- // GT file format (no header): , , , , , , , , ,
- var lines = await File.ReadAllLinesAsync(detFile.FullName);
-
- var frames = new Dictionary>();
- var numberInfo = new NumberFormatInfo() { NumberDecimalSeparator = "." };
- foreach (var line in lines)
+ var tracks = tracker.Track(frame.Value);
+ foreach (var track in tracks)
{
- var parts = line.Split(',');
- var frameId = int.Parse(parts[0]);
- var gtTrackId = int.Parse(parts[1]);
- var bbLeft = float.Parse(parts[2], numberInfo);
- var bbTop = float.Parse(parts[3], numberInfo);
- var bbWidth = float.Parse(parts[4], numberInfo);
- var bbHeight = float.Parse(parts[5], numberInfo);
- var bbConf = float.Parse(parts[6], numberInfo);
- if (!frames.ContainsKey(frameId))
- {
- frames.Add(frameId, new List());
- }
- if (bbConf > 0)
+ if (track.State == TrackState.Started || track.State == TrackState.Active)
{
- frames[frameId].Add(new RectangleF(bbLeft, bbTop, bbWidth, bbHeight));
+ //var boxForLog = track.History.Last();
+ var boxForLog = track.Prediction;
+ //, , , , , , , , ,
+ var line = $"{frame.Key:0.},{track.TrackId:0.},{boxForLog.Left:0.},{boxForLog.Top:0.},{boxForLog.Width:0.},{boxForLog.Height:0.},1,-1,-1,-1";
+ await file.WriteLineAsync(line);
}
}
+ }
+ }
+
+ private static string GetBenchmarkKeyFromSeqIni(FileInfo sequenceIniFile)
+ {
+ var iniString = File.ReadAllText(sequenceIniFile.FullName);
+ var parser = new IniDataParser();
+ var data = parser.Parse(iniString);
+ var benchmarkKey = data["Sequence"]["name"];
+ return benchmarkKey;
+ }
- return frames;
+ private static async Task>> GetFramesFromFile(FileInfo detFile)
+ {
+ // GT file format (no header): , , , , , , , , ,
+ var lines = await File.ReadAllLinesAsync(detFile.FullName);
+
+ var frames = new Dictionary>();
+ var numberInfo = new NumberFormatInfo() { NumberDecimalSeparator = "." };
+ foreach (var line in lines)
+ {
+ var parts = line.Split(',');
+ var frameId = int.Parse(parts[0]);
+ var gtTrackId = int.Parse(parts[1]);
+ var bbLeft = float.Parse(parts[2], numberInfo);
+ var bbTop = float.Parse(parts[3], numberInfo);
+ var bbWidth = float.Parse(parts[4], numberInfo);
+ var bbHeight = float.Parse(parts[5], numberInfo);
+ var bbConf = float.Parse(parts[6], numberInfo);
+ if (!frames.ContainsKey(frameId))
+ {
+ frames.Add(frameId, new List());
+ }
+ if (bbConf > 0)
+ {
+ frames[frameId].Add(new RectangleF(bbLeft, bbTop, bbWidth, bbHeight));
+ }
}
+
+ return frames;
}
-}
+}
\ No newline at end of file
diff --git a/src/SortCS.Tests/Frame.cs b/src/SortCS.Tests/Frame.cs
index 5a01c7d..f3fbcd5 100644
--- a/src/SortCS.Tests/Frame.cs
+++ b/src/SortCS.Tests/Frame.cs
@@ -1,14 +1,13 @@
using System.Collections.Generic;
using System.Drawing;
-namespace SortCS.Tests
+namespace SortCS.Tests;
+
+public class Frame
{
- public class Frame
+ public Frame(List boundingBoxes)
{
- public Frame(List boundingBoxes)
- {
- BoundingBoxes = boundingBoxes;
- }
- public List BoundingBoxes { get; set; }
+ BoundingBoxes = boundingBoxes;
}
-}
+ public List BoundingBoxes { get; set; }
+}
\ No newline at end of file
diff --git a/src/SortCS.Tests/SortCS.Tests.csproj b/src/SortCS.Tests/SortCS.Tests.csproj
index ce886a4..088a9e3 100644
--- a/src/SortCS.Tests/SortCS.Tests.csproj
+++ b/src/SortCS.Tests/SortCS.Tests.csproj
@@ -1,16 +1,16 @@
- net5.0
+ net9.0
latest
false
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/SortCS.Tests/SortTrackerTests.cs b/src/SortCS.Tests/SortTrackerTests.cs
index b7a19a7..0bfb7b0 100644
--- a/src/SortCS.Tests/SortTrackerTests.cs
+++ b/src/SortCS.Tests/SortTrackerTests.cs
@@ -3,119 +3,118 @@
using System.Drawing;
using System.Linq;
-namespace SortCS.Tests
+namespace SortCS.Tests;
+
+[TestClass]
+public class SortTrackerTests
{
- [TestClass]
- public class SortTrackerTests
+ [TestMethod]
+ public void SortTracker_FourEasyTracks_TrackedToEnd()
{
- [TestMethod]
- public void SortTracker_FourEasyTracks_TrackedToEnd()
- {
- // Arrange
- var mot15Track = new List{
- new Frame(new List{
- new RectangleF(1703,385,157,339),
- new RectangleF(1293,455,83,213),
- new RectangleF(259,449,101,261),
- new RectangleF(1253,529,55,127)
- }),
- new Frame(new List{
- new RectangleF(1699,383,159,341),
- new RectangleF(1293,455,83,213),
- new RectangleF(261,447,101,263),
- new RectangleF(1253,529,55,127)
- }),
- new Frame(new List{
- new RectangleF(1697,383,159,343),
- new RectangleF(1293,455,83,213),
- new RectangleF(263,447,101,263),
- new RectangleF(1255,529,55,127),
- new RectangleF(429,300,55,127)
- }),
- new Frame(new List{
- new RectangleF(1695,383,159,343),
- new RectangleF(1293,455,83,213),
- new RectangleF(265,447,101,263),
- new RectangleF(1257,529,55,127)
- }),
- new Frame(new List{
- new RectangleF(1693,381,159,347),
- new RectangleF(1295,455,83,213),
- new RectangleF(267,447,101,263),
- new RectangleF(1259, 529,55,129)
- }),
- };
+ // Arrange
+ var mot15Track = new List{
+ new(new List{
+ new(1703,385,157,339),
+ new(1293,455,83,213),
+ new(259,449,101,261),
+ new(1253,529,55,127)
+ }),
+ new(new List{
+ new(1699,383,159,341),
+ new(1293,455,83,213),
+ new(261,447,101,263),
+ new(1253,529,55,127)
+ }),
+ new(new List{
+ new(1697,383,159,343),
+ new(1293,455,83,213),
+ new(263,447,101,263),
+ new(1255,529,55,127),
+ new(429,300,55,127)
+ }),
+ new(new List{
+ new(1695,383,159,343),
+ new(1293,455,83,213),
+ new(265,447,101,263),
+ new(1257,529,55,127)
+ }),
+ new(new List{
+ new(1693,381,159,347),
+ new(1295,455,83,213),
+ new(267,447,101,263),
+ new(1259, 529,55,129)
+ }),
+ };
- var tracks = Enumerable.Empty