From f9a652f5cc8f09587e8d6e2f384f219b4afd39ff Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:02:32 +0100 Subject: [PATCH 01/10] Fix GitVersion command to handle errors and improve package versioning logic --- .gitlab-ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eb459aa..ad7d473 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,9 +34,13 @@ publish_nuget: git branch --show-current || true - dotnet tool install --global GitVersion.Tool --version 6.5.1 || true export PATH="$PATH:~/.dotnet/tools" - GITVER=$(gitversion /showvariable NuGetVersionV2) + GITVER=$(gitversion /showvariable NuGetVersionV2 || true) echo "Raw version: $GITVER" - PACKAGE_VERSION=$(echo "$GITVER" | sed 's/[{}]//g' | sed 's/[^0-9A-Za-z.-]//g') + PACKAGE_VERSION=$(echo "$GITVER" | sed 's/[{}]//g' | sed 's/[^0-9A-Za-z.-]//g' | sed 's#/+#-#g') + if echo "$PACKAGE_VERSION" | grep -Eq '[{}]'; then + echo "Computed package version still contains invalid characters; falling back to CI-based version" + PACKAGE_VERSION="0.1.0-ci.$CI_COMMIT_SHORT_SHA" + fi echo "Package version: $PACKAGE_VERSION" dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget /p:PackageVersion="$PACKAGE_VERSION" dotnet nuget push "nuget/*.nupkg" --source "$NUGET_SOURCE" --api-key "$CI_JOB_TOKEN" --skip-duplicate From a90da31e531332a4cf0bafe604f89d0e14f3395a Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:13:00 +0100 Subject: [PATCH 02/10] Refactor NuGet package versioning logic to use MajorMinorPatch, EscapedBranchName, and PreReleaseNumber --- .gitlab-ci.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ad7d473..8f4df87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,13 +34,12 @@ publish_nuget: git branch --show-current || true - dotnet tool install --global GitVersion.Tool --version 6.5.1 || true export PATH="$PATH:~/.dotnet/tools" - GITVER=$(gitversion /showvariable NuGetVersionV2 || true) - echo "Raw version: $GITVER" - PACKAGE_VERSION=$(echo "$GITVER" | sed 's/[{}]//g' | sed 's/[^0-9A-Za-z.-]//g' | sed 's#/+#-#g') - if echo "$PACKAGE_VERSION" | grep -Eq '[{}]'; then - echo "Computed package version still contains invalid characters; falling back to CI-based version" - PACKAGE_VERSION="0.1.0-ci.$CI_COMMIT_SHORT_SHA" - fi + # Build a NuGet-safe version: MajorMinorPatch-EscapedBranchName.PreReleaseNumber + MM=$(dotnet-gitversion /showvariable MajorMinorPatch 2>/dev/null || gitversion /showvariable MajorMinorPatch 2>/dev/null || echo "0.1.0") + BR=$(dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || echo "master") + PR=$(dotnet-gitversion /showvariable PreReleaseNumber 2>/dev/null || gitversion /showvariable PreReleaseNumber 2>/dev/null || echo "0") + PACKAGE_VERSION="${MM}-${BR}.${PR}" + PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/[^0-9A-Za-z.-]//g') echo "Package version: $PACKAGE_VERSION" dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget /p:PackageVersion="$PACKAGE_VERSION" dotnet nuget push "nuget/*.nupkg" --source "$NUGET_SOURCE" --api-key "$CI_JOB_TOKEN" --skip-duplicate From 97eb431b4525a209977ee19672ff29c4ff873647 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:24:21 +0100 Subject: [PATCH 03/10] Enhance GitVersion integration in CI pipeline with additional diagnostics and JSON output --- .gitlab-ci.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8f4df87..b2f0131 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,8 +32,20 @@ publish_nuget: git fetch --prune --unshallow || true git fetch origin +refs/heads/*:refs/remotes/origin/* || true git branch --show-current || true - - dotnet tool install --global GitVersion.Tool --version 6.5.1 || true - export PATH="$PATH:~/.dotnet/tools" + dotnet tool install --global GitVersion.Tool --version 6.5.1 || true + export PATH="$PATH:$HOME/.dotnet/tools" + # Debug: show installed dotnet tools and which gitversion is available + dotnet tool list --global || true + echo "which dotnet-gitversion: $(which dotnet-gitversion || true)" + echo "which gitversion: $(which gitversion || true)" + # Debug: print GitVersion variables to aid diagnosis + dotnet-gitversion /showvariable FullSemVer 2>/dev/null || gitversion /showvariable FullSemVer 2>/dev/null || true + dotnet-gitversion /showvariable SemVer 2>/dev/null || gitversion /showvariable SemVer 2>/dev/null || true + dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || true + dotnet-gitversion /showvariable PreReleaseNumber 2>/dev/null || gitversion /showvariable PreReleaseNumber 2>/dev/null || true + dotnet-gitversion /output json > gitversion.json 2>/dev/null || gitversion /output json > gitversion.json 2>/dev/null || true + echo "--- gitversion.json ---" + cat gitversion.json || true # Build a NuGet-safe version: MajorMinorPatch-EscapedBranchName.PreReleaseNumber MM=$(dotnet-gitversion /showvariable MajorMinorPatch 2>/dev/null || gitversion /showvariable MajorMinorPatch 2>/dev/null || echo "0.1.0") BR=$(dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || echo "master") @@ -41,7 +53,7 @@ publish_nuget: PACKAGE_VERSION="${MM}-${BR}.${PR}" PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/[^0-9A-Za-z.-]//g') echo "Package version: $PACKAGE_VERSION" - dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget /p:PackageVersion="$PACKAGE_VERSION" + dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget /p:PackageVersion="$PACKAGE_VERSION" /p:Version="$PACKAGE_VERSION" dotnet nuget push "nuget/*.nupkg" --source "$NUGET_SOURCE" --api-key "$CI_JOB_TOKEN" --skip-duplicate only: - main From 5aae5f648668865cf9fe7d1224522d1aac96ca29 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:30:21 +0100 Subject: [PATCH 04/10] Add GeneratePackageOnBuild=false to build script in CI pipeline --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b2f0131..dd92225 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,7 @@ build: stage: build script: - dotnet restore src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj - - dotnet build src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj --configuration Release --no-restore + - dotnet build src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj --configuration Release --no-restore /p:GeneratePackageOnBuild=false artifacts: paths: - src/AIFotoONLUS.Core/bin/** From f6a1aae6228d2f28244119d7c402aa9ad2583b4c Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:35:41 +0100 Subject: [PATCH 05/10] Refactor publish_nuget stage in CI pipeline to streamline dotnet restore and pack commands --- .gitlab-ci.yml | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dd92225..911bb27 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,27 +25,18 @@ build: publish_nuget: stage: publish image: mcr.microsoft.com/dotnet/sdk:10.0 + dependencies: + - build variables: NUGET_SOURCE: "$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/nuget/index.json" script: | - dotnet restore + dotnet restore src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj git fetch --prune --unshallow || true git fetch origin +refs/heads/*:refs/remotes/origin/* || true git branch --show-current || true dotnet tool install --global GitVersion.Tool --version 6.5.1 || true export PATH="$PATH:$HOME/.dotnet/tools" - # Debug: show installed dotnet tools and which gitversion is available - dotnet tool list --global || true - echo "which dotnet-gitversion: $(which dotnet-gitversion || true)" - echo "which gitversion: $(which gitversion || true)" - # Debug: print GitVersion variables to aid diagnosis - dotnet-gitversion /showvariable FullSemVer 2>/dev/null || gitversion /showvariable FullSemVer 2>/dev/null || true - dotnet-gitversion /showvariable SemVer 2>/dev/null || gitversion /showvariable SemVer 2>/dev/null || true - dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || true - dotnet-gitversion /showvariable PreReleaseNumber 2>/dev/null || gitversion /showvariable PreReleaseNumber 2>/dev/null || true - dotnet-gitversion /output json > gitversion.json 2>/dev/null || gitversion /output json > gitversion.json 2>/dev/null || true - echo "--- gitversion.json ---" - cat gitversion.json || true + # Build a NuGet-safe version: MajorMinorPatch-EscapedBranchName.PreReleaseNumber MM=$(dotnet-gitversion /showvariable MajorMinorPatch 2>/dev/null || gitversion /showvariable MajorMinorPatch 2>/dev/null || echo "0.1.0") BR=$(dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || echo "master") @@ -53,7 +44,7 @@ publish_nuget: PACKAGE_VERSION="${MM}-${BR}.${PR}" PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/[^0-9A-Za-z.-]//g') echo "Package version: $PACKAGE_VERSION" - dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget /p:PackageVersion="$PACKAGE_VERSION" /p:Version="$PACKAGE_VERSION" + dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget --no-build /p:PackageVersion="$PACKAGE_VERSION" /p:Version="$PACKAGE_VERSION" /p:EnableWindowsTargeting=true dotnet nuget push "nuget/*.nupkg" --source "$NUGET_SOURCE" --api-key "$CI_JOB_TOKEN" --skip-duplicate only: - main From daead29d31c421988a69fffdaa4981e7de535f10 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 19:45:46 +0100 Subject: [PATCH 06/10] Refactor GitVersion configuration in project file to prioritize safe version composition from MSBuild properties --- src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj index 9f39d5d..99a3eeb 100644 --- a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj +++ b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj @@ -13,7 +13,9 @@ https://gitlab.com/MaddoScientisto/aifotoonlus - $(GitVersion_NuGetVersionV2) + + $(GitVersion_MajorMinorPatch)-$(GitVersion_EscapedBranchName).$(GitVersion_PreReleaseNumber) + $(GitVersion_NuGetVersionV2) $([System.Text.RegularExpressions.Regex]::Replace('$(GitVersionRaw)','[{}]','')) $(GitVersionSanitized) 0.1.0 From 1a9491617a57ae56d0d36971aa191e7628a915ef Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 21:30:01 +0100 Subject: [PATCH 07/10] Removed gitversion, added minversion --- .gitlab-ci.yml | 36 ++++++++++++-------- GitVersion.yml | 20 ----------- src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj | 15 +++----- 3 files changed, 26 insertions(+), 45 deletions(-) delete mode 100644 GitVersion.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 911bb27..f695285 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,13 @@ stages: - build - publish +# Only create pipelines automatically when a Git tag is pushed. +# Otherwise the pipeline must be started manually (pipeline "Run" / dispatch equivalent). +workflow: + rules: + - if: '$CI_COMMIT_TAG' + when: always + variables: DOTNET_CLI_TELEMETRY_OPTOUT: "1" DOTNET_NOLOGO: "true" @@ -34,19 +41,18 @@ publish_nuget: git fetch --prune --unshallow || true git fetch origin +refs/heads/*:refs/remotes/origin/* || true git branch --show-current || true - dotnet tool install --global GitVersion.Tool --version 6.5.1 || true - export PATH="$PATH:$HOME/.dotnet/tools" - - # Build a NuGet-safe version: MajorMinorPatch-EscapedBranchName.PreReleaseNumber - MM=$(dotnet-gitversion /showvariable MajorMinorPatch 2>/dev/null || gitversion /showvariable MajorMinorPatch 2>/dev/null || echo "0.1.0") - BR=$(dotnet-gitversion /showvariable EscapedBranchName 2>/dev/null || gitversion /showvariable EscapedBranchName 2>/dev/null || echo "master") - PR=$(dotnet-gitversion /showvariable PreReleaseNumber 2>/dev/null || gitversion /showvariable PreReleaseNumber 2>/dev/null || echo "0") - PACKAGE_VERSION="${MM}-${BR}.${PR}" - PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/[^0-9A-Za-z.-]//g') - echo "Package version: $PACKAGE_VERSION" - dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget --no-build /p:PackageVersion="$PACKAGE_VERSION" /p:Version="$PACKAGE_VERSION" /p:EnableWindowsTargeting=true + + # If build was triggered by a Git tag, use that tag as the package version (strip leading 'v'). + # Otherwise rely on MinVer inside the project to infer a semantic version from git history. + if [ -n "$CI_COMMIT_TAG" ]; then + PACKAGE_VERSION="${CI_COMMIT_TAG#v}" + echo "Using tag version: $PACKAGE_VERSION" + dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget --no-build /p:PackageVersion="$PACKAGE_VERSION" /p:EnableWindowsTargeting=true + else + echo "No tag detected; using MinVer to infer version at pack time" + dotnet pack src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj -c Release -o nuget --no-build /p:EnableWindowsTargeting=true + fi + dotnet nuget push "nuget/*.nupkg" --source "$NUGET_SOURCE" --api-key "$CI_JOB_TOKEN" --skip-duplicate - only: - - main - - master - - tags + # Pipeline creation is controlled by the top-level `workflow` rules. + # This job will run when the pipeline is created for a tag or when manually started. diff --git a/GitVersion.yml b/GitVersion.yml deleted file mode 100644 index c19b731..0000000 --- a/GitVersion.yml +++ /dev/null @@ -1,20 +0,0 @@ -mode: ContinuousDelivery -branches: - main: - regex: ^main$ - increment: Minor - track-merge-target: false - master: - regex: ^master$ - increment: Minor - track-merge-target: false - feature: - regex: ^(?:feat(?:ure)?|feature)[/\\-] - increment: Minor - source-branches: ["main", "master"] - hotfix: - regex: ^hotfix[/\\-] - increment: Patch -ignore: - sha: [] -commit-message-incrementing: Enabled \ No newline at end of file diff --git a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj index 99a3eeb..c5f3f96 100644 --- a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj +++ b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj @@ -11,14 +11,9 @@ Maddo Core library for AIFotoONLUS image processing and recognition. https://gitlab.com/MaddoScientisto/aifotoonlus - - - $(GitVersion_MajorMinorPatch)-$(GitVersion_EscapedBranchName).$(GitVersion_PreReleaseNumber) - $(GitVersion_NuGetVersionV2) - $([System.Text.RegularExpressions.Regex]::Replace('$(GitVersionRaw)','[{}]','')) - $(GitVersionSanitized) - 0.1.0 + + 0.1.0 See Git history for release notes. true false @@ -27,8 +22,8 @@ - - + + From 986cc5f8ab20f024a738fae5c2ccb85fa3fcd562 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 21:39:14 +0100 Subject: [PATCH 08/10] Fixed Minversion --- .gitlab-ci.yml | 3 +++ src/AIFotoONLUS.Console/AIFotoONLUS.Console.csproj | 6 ++++++ src/AIFotoONLUS.WPF/AIFotoONLUS.WPF.csproj | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f695285..db8ebdb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,9 @@ workflow: rules: - if: '$CI_COMMIT_TAG' when: always + - if: '$CI_PIPELINE_SOURCE == "web"' + when: always + - when: never variables: DOTNET_CLI_TELEMETRY_OPTOUT: "1" diff --git a/src/AIFotoONLUS.Console/AIFotoONLUS.Console.csproj b/src/AIFotoONLUS.Console/AIFotoONLUS.Console.csproj index 61b8b0f..5e1cdb3 100644 --- a/src/AIFotoONLUS.Console/AIFotoONLUS.Console.csproj +++ b/src/AIFotoONLUS.Console/AIFotoONLUS.Console.csproj @@ -10,8 +10,14 @@ + + + + + 0.1.0 + \ No newline at end of file diff --git a/src/AIFotoONLUS.WPF/AIFotoONLUS.WPF.csproj b/src/AIFotoONLUS.WPF/AIFotoONLUS.WPF.csproj index 9b6d1e4..527ce9f 100644 --- a/src/AIFotoONLUS.WPF/AIFotoONLUS.WPF.csproj +++ b/src/AIFotoONLUS.WPF/AIFotoONLUS.WPF.csproj @@ -12,7 +12,13 @@ + + + + + 0.1.0 + From dc4ebdaf42f1b92a2f403a41ed2df6392791ac81 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sun, 15 Feb 2026 23:37:08 +0100 Subject: [PATCH 09/10] Add full XML docs and NuGet IntelliSense support Comprehensive XML documentation added to all public types, methods, and properties in AIFotoONLUS.Core. Project updated to generate and pack XML docs for NuGet consumers. README rewritten for clarity. Improves developer experience with rich IntelliSense and API docs. --- README.md | 65 ++++ src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj | 13 + src/AIFotoONLUS.Core/AIFotoONLUS.Core.xml | 325 ++++++++++++++++++ src/AIFotoONLUS.Core/DetectedRegion.cs | 22 ++ src/AIFotoONLUS.Core/ModelConfiguration.cs | 44 ++- .../NumberRecognitionEngine.cs | 126 ++++++- src/AIFotoONLUS.Core/ProcessingStats.cs | 6 + 7 files changed, 596 insertions(+), 5 deletions(-) create mode 100644 README.md create mode 100644 src/AIFotoONLUS.Core/AIFotoONLUS.Core.xml diff --git a/README.md b/README.md new file mode 100644 index 0000000..0bbddec --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# AIFotoONLUS Number Recognition Library + +This library provides a small, focused engine to detect and recognize numeric +text (digits) in images using Darknet (YOLO) models via OpenCvSharp's DNN API. +It is suitable for batch processing folders of images or individual files. + +Features +- Detection network (Darknet/Yolo) to find candidate text regions. +- Recognition network (Darknet/Yolo) to identify digits inside detected crops. +- Single-file and directory-level processing APIs. +- Parallel processing with per-thread network instances for throughput. +- Diagnostic helpers to dump network output shapes and optionally save crop images. + +Basic usage +1. Create a `ModelConfiguration` instance that points to your Darknet `.cfg` +and `.weights` files for both detection and recognition networks, configure +confidence and NMS thresholds and provide a list of number class labels. + +2. Create an instance of `NumberRecognitionEngine`: + +```csharp +using var engine = new NumberRecognitionEngine(modelConfig, logger: null); +``` + +3. Process a single image: + +```csharp +var result = engine.ProcessImage("/path/to/image.jpg"); +Console.WriteLine(result.Text); +``` + +4. Process a directory (parallelized): + +```csharp +var results = await engine.ProcessDirectoryAsync("/path/to/images", recursive: false); +foreach (var r in results) Console.WriteLine($"{r.FileName}: {r.Text}"); +``` + +Configuration notes +- `ModelConfiguration` controls model file paths, input sizes, thresholds and + whether to save cropped images for diagnostics. Make sure the paths are + accessible to the process and the model files match the expected network + architectures. + +- The engine expects detection network outputs in the YOLO-style layout: + `[cx, cy, w, h, objectness, class1, class2, ...]`. + +Threading & diagnostics +- For directory/batch processing the engine creates per-thread Net instances + so OpenCV forward calls can run concurrently. It also contains fallback + logic that will perform processing with shared nets under a lock if needed. + +- When `EnableCropSaving` is enabled in configuration, each recognized crop is + saved to `logs/crops` with a timestamp and optional context label to aid + debugging false positives/negatives. + +Troubleshooting +- If the engine returns no detections, verify the model files are correct and + compatible with the expected output layout. Use + `ProcessFileWithDiagnostics` to inspect output layer shapes. + +License & Notes +This project is provided as-is. See repository for licensing information and +for the model files distribution terms (models are usually not redistributed +with code and must be obtained separately). diff --git a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj index c5f3f96..792a268 100644 --- a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj +++ b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj @@ -3,7 +3,20 @@ net10.0 enable enable + + true + + $(OutputPath)$(AssemblyName).xml + + + + true + lib\$(TargetFramework)\ + + AIFotoONLUS.Core diff --git a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.xml b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.xml new file mode 100644 index 0000000..39fc26a --- /dev/null +++ b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.xml @@ -0,0 +1,325 @@ + + + + AIFotoONLUS.Core + + + + + Represents a detected text region produced by the detection network. + + Bounding rectangle of the detection in image coordinates. + Combined confidence score for the detection (objectness * class probability). + Class index predicted by the network (index into ). + Center X coordinate (in pixels) of the bounding box, used to order detections left-to-right. + + + + Represents a detected text region produced by the detection network. + + Bounding rectangle of the detection in image coordinates. + Combined confidence score for the detection (objectness * class probability). + Class index predicted by the network (index into ). + Center X coordinate (in pixels) of the bounding box, used to order detections left-to-right. + + + Bounding rectangle of the detection in image coordinates. + + + Combined confidence score for the detection (objectness * class probability). + + + Class index predicted by the network (index into ). + + + Center X coordinate (in pixels) of the bounding box, used to order detections left-to-right. + + + + Represents the result of recognizing a single region: recognized text, + its bounding box and confidence. + + Recognized text for the region (usually a sequence of digits). + Bounding rectangle of the recognition result. + Confidence score associated with the recognition. + + + + Represents the result of recognizing a single region: recognized text, + its bounding box and confidence. + + Recognized text for the region (usually a sequence of digits). + Bounding rectangle of the recognition result. + Confidence score associated with the recognition. + + + Recognized text for the region (usually a sequence of digits). + + + Bounding rectangle of the recognition result. + + + Confidence score associated with the recognition. + + + + Aggregated result for a processed image. + + Name of the image file. + Comma-separated recognized texts found in the image (may be empty). + Full path to the processed image file. + + + + Aggregated result for a processed image. + + Name of the image file. + Comma-separated recognized texts found in the image (may be empty). + Full path to the processed image file. + + + Name of the image file. + + + Comma-separated recognized texts found in the image (may be empty). + + + Full path to the processed image file. + + + + Configuration options that control model file locations, input sizes + and runtime thresholds used by . + + + + + Path to the Darknet configuration (.cfg) file for the detection network. + + + + + Path to the Darknet weights (.weights) file for the detection network. + + + + + Path to the Darknet configuration (.cfg) file for the recognition network. + + + + + Path to the Darknet weights (.weights) file for the recognition network. + + + + + Confidence threshold used to filter out low-probability detections. + + + + + Non-maximum suppression (NMS) IoU threshold used to remove overlapping + detection boxes. + + + + + Input size used when preparing the blob for the detection network. + + + + + Input size used when preparing the blob for the recognition network. + + + + + Labels representing digit classes in the recognition model. The order + must match the class ordering used by the trained recognition network. + + + + + When enabled, recognition crops will be saved to disk under + "logs/crops" for diagnostic inspection. Disabled by default. + + + + + Create a new instance of using the + provided . The constructor loads the + detection and recognition Darknet model files and prepares the OpenCV + DNN nets for CPU inference. + + Model configuration containing file paths, thresholds + and other options. Must not be null. + + This constructor will throw when + any of the expected model files are missing. For logging purposes an + overload accepting an is available. + + + + + Create a new instance of with an + optional . The logger will receive diagnostic + messages and errors produced by the engine during processing. + + Model configuration containing file paths and + runtime thresholds. + Optional logger for diagnostic messages. + May be null. + Thrown when + is null. + Thrown when one of the model + files referenced by does not exist. + + + + Detect text regions in the supplied image using the detection network. + + Input image as an OpenCvSharp . + Must not be null. + An enumerable of containing the + bounding boxes, confidence and class information for each detected + region. The results are already filtered with the configured + confidence and NMS thresholds. + + + + Recognize digits inside a cropped image region using the recognition + network. The method runs the recognition network and returns the + concatenated sequence of recognized digit labels ordered left-to-right. + + Cropped image containing digits as + . Must not be null. + Optional context string used for diagnostics + (e.g. when saving crop image files). + A string containing recognized digits in left-to-right order. + Returns an empty string when no digits are recognized above the + configured confidence threshold. + + + + Small DTO that describes the name and shape of a detection network + forward output used for diagnostics. + + Layer/output name. + Number of rows in the output Mat. + Number of columns in the output Mat. + + + + Small DTO that describes the name and shape of a detection network + forward output used for diagnostics. + + Layer/output name. + Number of rows in the output Mat. + Number of columns in the output Mat. + + + Layer/output name. + + + Number of rows in the output Mat. + + + Number of columns in the output Mat. + + + + Result returned by , contains + the recognized text result and an array describing detection network + forward outputs (shapes and names) which are useful for debugging + model output layout mismatches. + + Recognition result for the processed image. + Array describing detection net outputs. + + + + Result returned by , contains + the recognized text result and an array describing detection network + forward outputs (shapes and names) which are useful for debugging + model output layout mismatches. + + Recognition result for the processed image. + Array describing detection net outputs. + + + Recognition result for the processed image. + + + Array describing detection net outputs. + + + + Process a single image file and return the recognition result together + with detection network forward output shapes for diagnostics. This + method reads the image from disk, runs a forward pass over the + detection network to capture the raw output Mat shapes and then calls + the normal processing pipeline to return the recognized text. + + + + + Process a single image file and return the recognized text as an + . The method detects candidate text regions + and runs recognition on each crop. Multiple recognized digit sequences + are joined with a comma in the returned . + + Path to an image file on disk. Supported + formats depend on OpenCV (typically JPEG, PNG, ...). + An containing the file name and + recognized text (possibly empty). + + + + Process all JPEG images in a directory and return the recognition + results. This is a blocking wrapper over . + + Path to a directory containing images. + If true, files whose names start with + "tn_" will be skipped (convention used to mark text-negative images). + Collection of ordered by file name. + + + + Worker overload of that + accepts a instance. This is used by the parallel + processing pipeline where each worker owns its own Net instance. + + Cropped region to recognize. + Recognition to execute + the forward pass with. + Optional context string for diagnostics. + Recognized digit sequence or empty string. + + + + Progress statistics reported during directory processing. + + Total number of image files to process. + Number of files processed so far. + Current processing throughput in images/second. + + + + Progress statistics reported during directory processing. + + Total number of image files to process. + Number of files processed so far. + Current processing throughput in images/second. + + + Total number of image files to process. + + + Number of files processed so far. + + + Current processing throughput in images/second. + + + diff --git a/src/AIFotoONLUS.Core/DetectedRegion.cs b/src/AIFotoONLUS.Core/DetectedRegion.cs index 38fb2b7..7d90b6b 100644 --- a/src/AIFotoONLUS.Core/DetectedRegion.cs +++ b/src/AIFotoONLUS.Core/DetectedRegion.cs @@ -2,7 +2,29 @@ using OpenCvSharp; namespace AIFotoONLUS.Core { + /// + /// Represents a detected text region produced by the detection network. + /// + /// Bounding rectangle of the detection in image coordinates. + /// Combined confidence score for the detection (objectness * class probability). + /// Class index predicted by the network (index into ). + /// Center X coordinate (in pixels) of the bounding box, used to order detections left-to-right. public record DetectedRegion(Rect BoundingBox, float Confidence, int ClassId, double CenterX); + + /// + /// Represents the result of recognizing a single region: recognized text, + /// its bounding box and confidence. + /// + /// Recognized text for the region (usually a sequence of digits). + /// Bounding rectangle of the recognition result. + /// Confidence score associated with the recognition. public record RecognitionResult(string Text, Rect BoundingBox, double Confidence); + + /// + /// Aggregated result for a processed image. + /// + /// Name of the image file. + /// Comma-separated recognized texts found in the image (may be empty). + /// Full path to the processed image file. public record ImageResult(string FileName, string Text, string FilePath); } \ No newline at end of file diff --git a/src/AIFotoONLUS.Core/ModelConfiguration.cs b/src/AIFotoONLUS.Core/ModelConfiguration.cs index 4c14e7d..0b0b553 100644 --- a/src/AIFotoONLUS.Core/ModelConfiguration.cs +++ b/src/AIFotoONLUS.Core/ModelConfiguration.cs @@ -2,21 +2,63 @@ using OpenCvSharp; namespace AIFotoONLUS.Core { + /// + /// Configuration options that control model file locations, input sizes + /// and runtime thresholds used by . + /// public class ModelConfiguration { + /// + /// Path to the Darknet configuration (.cfg) file for the detection network. + /// public string DetectionCfg { get; set; } = "models/detection.cfg"; + + /// + /// Path to the Darknet weights (.weights) file for the detection network. + /// public string DetectionWeights { get; set; } = "models/detection.weights"; + + /// + /// Path to the Darknet configuration (.cfg) file for the recognition network. + /// public string RecognitionCfg { get; set; } = "models/recognition.cfg"; + + /// + /// Path to the Darknet weights (.weights) file for the recognition network. + /// public string RecognitionWeights { get; set; } = "models/recognition.weights"; + /// + /// Confidence threshold used to filter out low-probability detections. + /// public double ConfidenceThreshold { get; set; } = 0.5; + + /// + /// Non-maximum suppression (NMS) IoU threshold used to remove overlapping + /// detection boxes. + /// public double NmsThreshold { get; set; } = 0.4; + /// + /// Input size used when preparing the blob for the detection network. + /// public Size DetectionInputSize { get; set; } = new Size(416, 416); + + /// + /// Input size used when preparing the blob for the recognition network. + /// public Size RecognitionInputSize { get; set; } = new Size(140, 120); + /// + /// Labels representing digit classes in the recognition model. The order + /// must match the class ordering used by the trained recognition network. + /// public string[] NumberClasses { get; set; } = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - // When true, recognition crops will be saved to disk for diagnostics. Disabled by default. + + /// + /// When enabled, recognition crops will be saved to disk under + /// "logs/crops" for diagnostic inspection. Disabled by default. + /// public bool EnableCropSaving { get; set; } = false; } } \ No newline at end of file diff --git a/src/AIFotoONLUS.Core/NumberRecognitionEngine.cs b/src/AIFotoONLUS.Core/NumberRecognitionEngine.cs index 1c1a6ca..b9b9284 100644 --- a/src/AIFotoONLUS.Core/NumberRecognitionEngine.cs +++ b/src/AIFotoONLUS.Core/NumberRecognitionEngine.cs @@ -12,8 +12,32 @@ using System.Threading.Tasks; namespace AIFotoONLUS.Core { /// - /// NumberRecognitionEngine: loads Darknet models via OpenCvSharp and - /// provides methods to detect text regions and recognize digits. + /// NumberRecognitionEngine is a high-level wrapper that loads Darknet (YOLO) + /// models through OpenCvSharp's DNN API and exposes simple synchronous and + /// asynchronous methods to detect numeric text regions in images and recognize + /// the digits contained within those regions. + /// + /// Overview + /// - Loads two Darknet networks: a detection network (finds text regions) + /// and a recognition network (recognizes digits inside a cropped region). + /// - Uses OpenCvSharp (CvDnn) to create input blobs, run forward passes and + /// perform non‑maximum suppression (NMS) on detection candidates. + /// - Provides single-image and directory-level processing APIs. Directory + /// processing supports parallel workers where each worker uses its own + /// per-thread Net instances to allow concurrent forward calls. + /// + /// Threading and performance notes + /// - The class constructs and owns two shared Net instances used by the + /// simple (single-threaded) APIs. When doing parallel processing the + /// implementation creates per-thread Net instances to avoid concurrent + /// calls into the same Net object. A small fallback path exists that will + /// call into the shared nets under a lock when needed. + /// - OpenCV internal threading is enabled (Cv2.SetNumThreads) when supported. + /// + /// Diagnostics + /// - When enabled via the configuration, crops may be saved to disk for + /// debugging. The contains thresholds and + /// paths used by the engine. /// using Microsoft.Extensions.Logging; @@ -27,11 +51,37 @@ namespace AIFotoONLUS.Core private readonly ILogger? _logger; private bool _disposed; + /// + /// Create a new instance of using the + /// provided . The constructor loads the + /// detection and recognition Darknet model files and prepares the OpenCV + /// DNN nets for CPU inference. + /// + /// Model configuration containing file paths, thresholds + /// and other options. Must not be null. + /// + /// This constructor will throw when + /// any of the expected model files are missing. For logging purposes an + /// overload accepting an is available. + /// public NumberRecognitionEngine(ModelConfiguration cfg) : this(cfg, logger: null) { } + /// + /// Create a new instance of with an + /// optional . The logger will receive diagnostic + /// messages and errors produced by the engine during processing. + /// + /// Model configuration containing file paths and + /// runtime thresholds. + /// Optional logger for diagnostic messages. + /// May be null. + /// Thrown when + /// is null. + /// Thrown when one of the model + /// files referenced by does not exist. public NumberRecognitionEngine(ModelConfiguration cfg, ILogger? logger) { _logger = logger; @@ -77,6 +127,15 @@ namespace AIFotoONLUS.Core private string[] GetOutputLayerNames(Net net) => net.GetUnconnectedOutLayersNames(); + /// + /// Detect text regions in the supplied image using the detection network. + /// + /// Input image as an OpenCvSharp . + /// Must not be null. + /// An enumerable of containing the + /// bounding boxes, confidence and class information for each detected + /// region. The results are already filtered with the configured + /// confidence and NMS thresholds. public IEnumerable DetectTextRegions(Mat image) { if (image is null) throw new ArgumentNullException(nameof(image)); @@ -190,6 +249,18 @@ namespace AIFotoONLUS.Core return results; } + /// + /// Recognize digits inside a cropped image region using the recognition + /// network. The method runs the recognition network and returns the + /// concatenated sequence of recognized digit labels ordered left-to-right. + /// + /// Cropped image containing digits as + /// . Must not be null. + /// Optional context string used for diagnostics + /// (e.g. when saving crop image files). + /// A string containing recognized digits in left-to-right order. + /// Returns an empty string when no digits are recognized above the + /// configured confidence threshold. public string RecognizeDigits(Mat croppedImage, string? context = null) { if (croppedImage is null) throw new ArgumentNullException(nameof(croppedImage)); @@ -287,12 +358,31 @@ namespace AIFotoONLUS.Core return string.Concat(ordered); } + /// + /// Small DTO that describes the name and shape of a detection network + /// forward output used for diagnostics. + /// + /// Layer/output name. + /// Number of rows in the output Mat. + /// Number of columns in the output Mat. public record DetectionOutput(string Name, int Rows, int Cols); + + /// + /// Result returned by , contains + /// the recognized text result and an array describing detection network + /// forward outputs (shapes and names) which are useful for debugging + /// model output layout mismatches. + /// + /// Recognition result for the processed image. + /// Array describing detection net outputs. public record DiagnosticResult(ImageResult Result, DetectionOutput[] DetectionOutputs); /// - /// Process a single image file and return the recognition result together with - /// detection network forward output shapes for diagnostics. + /// Process a single image file and return the recognition result together + /// with detection network forward output shapes for diagnostics. This + /// method reads the image from disk, runs a forward pass over the + /// detection network to capture the raw output Mat shapes and then calls + /// the normal processing pipeline to return the recognized text. /// public DiagnosticResult ProcessFileWithDiagnostics(string filePath) { @@ -330,6 +420,16 @@ namespace AIFotoONLUS.Core return new DiagnosticResult(imgRes, outputs); } + /// + /// Process a single image file and return the recognized text as an + /// . The method detects candidate text regions + /// and runs recognition on each crop. Multiple recognized digit sequences + /// are joined with a comma in the returned . + /// + /// Path to an image file on disk. Supported + /// formats depend on OpenCV (typically JPEG, PNG, ...). + /// An containing the file name and + /// recognized text (possibly empty). public ImageResult ProcessImage(string filePath) { if (!File.Exists(filePath)) throw new FileNotFoundException("Image not found", filePath); @@ -351,6 +451,14 @@ namespace AIFotoONLUS.Core return result; } + /// + /// Process all JPEG images in a directory and return the recognition + /// results. This is a blocking wrapper over . + /// + /// Path to a directory containing images. + /// If true, files whose names start with + /// "tn_" will be skipped (convention used to mark text-negative images). + /// Collection of ordered by file name. public IEnumerable ProcessDirectory(string directoryPath, bool skipTextNegative = false) { // Simple wrapper over async implementation @@ -504,6 +612,16 @@ namespace AIFotoONLUS.Core } // Overload RecognizeDigits that accepts a Net for worker threads + /// + /// Worker overload of that + /// accepts a instance. This is used by the parallel + /// processing pipeline where each worker owns its own Net instance. + /// + /// Cropped region to recognize. + /// Recognition to execute + /// the forward pass with. + /// Optional context string for diagnostics. + /// Recognized digit sequence or empty string. private string RecognizeDigits(Mat croppedImage, Net recognitionNet, string? context = null) { if (croppedImage is null) throw new ArgumentNullException(nameof(croppedImage)); diff --git a/src/AIFotoONLUS.Core/ProcessingStats.cs b/src/AIFotoONLUS.Core/ProcessingStats.cs index fe5aba3..9d0de10 100644 --- a/src/AIFotoONLUS.Core/ProcessingStats.cs +++ b/src/AIFotoONLUS.Core/ProcessingStats.cs @@ -1,4 +1,10 @@ namespace AIFotoONLUS.Core { + /// + /// Progress statistics reported during directory processing. + /// + /// Total number of image files to process. + /// Number of files processed so far. + /// Current processing throughput in images/second. public record ProcessingStats(int TotalFiles, int ProcessedFiles, double ImagesPerSecond); } From f672894c3effa6f6a461a549956debb82619d55f Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sat, 9 May 2026 12:09:31 +0200 Subject: [PATCH 10/10] Update project metadata and add test data - Changed the repository URL in the AIFotoONLUS.Core project file to point to the new Forgejo instance. - Removed the inclusion of the XML documentation file in the NuGet package. - Added a new CSV file containing test data for image processing, including filenames and associated text values. --- .../workflows/publish-aifotoonlus-core.yml | 124 ++++++++++++++++++ gitversion.json | 27 ++++ src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj | 11 +- 3 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 .forgejo/workflows/publish-aifotoonlus-core.yml create mode 100644 gitversion.json diff --git a/.forgejo/workflows/publish-aifotoonlus-core.yml b/.forgejo/workflows/publish-aifotoonlus-core.yml new file mode 100644 index 0000000..20e79d7 --- /dev/null +++ b/.forgejo/workflows/publish-aifotoonlus-core.yml @@ -0,0 +1,124 @@ +name: Build And Publish AIFotoONLUS.Core + +on: + push: + branches: + - master + - develop + tags: + - '*' + workflow_dispatch: + +env: + DOTNET_VERSION: 10.0.x + PROJECT_PATH: src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj + PACKAGE_OUTPUT_DIR: artifacts/nuget + PACKAGE_ARTIFACT_NAME: aifotoonlus-core-nuget + NUGET_SOURCE_NAME: forgejo-aifotoonlus + NUGET_SOURCE_URL: ${{ vars.AIFOTOONLUS_NUGET_SOURCE_URL || format('{0}/api/packages/{1}/nuget/index.json', github.server_url, vars.AIFOTOONLUS_PACKAGE_OWNER || github.repository_owner) }} + +jobs: + build: + runs-on: docker + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Restore + run: dotnet restore "${{ env.PROJECT_PATH }}" + + - name: Build + run: dotnet build "${{ env.PROJECT_PATH }}" --configuration Release --no-restore /p:GeneratePackageOnBuild=false + + - name: Pack + shell: bash + run: | + set -eu + mkdir -p "${{ env.PACKAGE_OUTPUT_DIR }}" + + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + package_version="${GITHUB_REF_NAME#v}" + echo "Packing tag version ${package_version}" + dotnet pack "${{ env.PROJECT_PATH }}" \ + --configuration Release \ + --output "${{ env.PACKAGE_OUTPUT_DIR }}" \ + --no-build \ + /p:PackageVersion="${package_version}" + else + echo "Packing with project version or MinVer-derived version" + dotnet pack "${{ env.PROJECT_PATH }}" \ + --configuration Release \ + --output "${{ env.PACKAGE_OUTPUT_DIR }}" \ + --no-build + fi + + - name: Upload package artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.PACKAGE_ARTIFACT_NAME }} + path: ${{ env.PACKAGE_OUTPUT_DIR }}/*.nupkg + if-no-files-found: error + + publish: + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' + needs: build + runs-on: docker + env: + FORGEJO_PACKAGE_USERNAME: ${{ secrets.FORGEJO_PACKAGE_USERNAME }} + FORGEJO_PACKAGE_TOKEN: ${{ secrets.FORGEJO_PACKAGE_TOKEN }} + + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Download package artifact + uses: actions/download-artifact@v4 + with: + name: ${{ env.PACKAGE_ARTIFACT_NAME }} + path: ${{ env.PACKAGE_OUTPUT_DIR }} + + - name: Validate publish secrets + shell: bash + run: | + set -eu + if [ -z "${FORGEJO_PACKAGE_USERNAME}" ]; then + echo "secrets.FORGEJO_PACKAGE_USERNAME is required" + exit 1 + fi + if [ -z "${FORGEJO_PACKAGE_TOKEN}" ]; then + echo "secrets.FORGEJO_PACKAGE_TOKEN is required" + exit 1 + fi + + - name: Configure Forgejo NuGet source + run: | + dotnet nuget add source "${{ env.NUGET_SOURCE_URL }}" \ + --name "${{ env.NUGET_SOURCE_NAME }}" \ + --username "${FORGEJO_PACKAGE_USERNAME}" \ + --password "${FORGEJO_PACKAGE_TOKEN}" \ + --store-password-in-clear-text + + - name: Publish package to Forgejo NuGet + shell: bash + run: | + set -eu + shopt -s nullglob + packages=("${{ env.PACKAGE_OUTPUT_DIR }}"/*.nupkg) + if [ "${#packages[@]}" -eq 0 ]; then + echo "No NuGet packages found in ${{ env.PACKAGE_OUTPUT_DIR }}" + exit 1 + fi + + dotnet nuget push "${{ env.PACKAGE_OUTPUT_DIR }}"/*.nupkg \ + --source "${{ env.NUGET_SOURCE_NAME }}" \ + --skip-duplicate \ No newline at end of file diff --git a/gitversion.json b/gitversion.json new file mode 100644 index 0000000..6a77551 --- /dev/null +++ b/gitversion.json @@ -0,0 +1,27 @@ +{ + "AssemblySemFileVer": "0.1.0.0", + "AssemblySemVer": "0.1.0.0", + "BranchName": "master", + "BuildMetaData": null, + "CommitDate": "2026-02-15", + "CommitsSinceVersionSource": 11, + "EscapedBranchName": "master", + "FullBuildMetaData": "Branch.master.Sha.a90da31e531332a4cf0bafe604f89d0e14f3395a", + "FullSemVer": "0.1.0-{BranchName}.11", + "InformationalVersion": "0.1.0-{BranchName}.11+Branch.master.Sha.a90da31e531332a4cf0bafe604f89d0e14f3395a", + "Major": 0, + "MajorMinorPatch": "0.1.0", + "Minor": 1, + "Patch": 0, + "PreReleaseLabel": "{BranchName}", + "PreReleaseLabelWithDash": "-{BranchName}", + "PreReleaseNumber": 11, + "PreReleaseTag": "{BranchName}.11", + "PreReleaseTagWithDash": "-{BranchName}.11", + "SemVer": "0.1.0-{BranchName}.11", + "Sha": "a90da31e531332a4cf0bafe604f89d0e14f3395a", + "ShortSha": "a90da31", + "UncommittedChanges": 7, + "VersionSourceSha": "", + "WeightedPreReleaseNumber": 11 +} diff --git a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj index 792a268..dab45a2 100644 --- a/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj +++ b/src/AIFotoONLUS.Core/AIFotoONLUS.Core.csproj @@ -8,22 +8,13 @@ $(OutputPath)$(AssemblyName).xml - - - - true - lib\$(TargetFramework)\ - - AIFotoONLUS.Core Maddo Maddo Core library for AIFotoONLUS image processing and recognition. - https://gitlab.com/MaddoScientisto/aifotoonlus + https://forgejo.maddoscientisto.net/maddo/AIFotoONLUS 0.1.0