Skip to content

Add OpenCV 5 face, img_hash, and line_descriptor APIs - #2051

Merged
shimat merged 3 commits into
mainfrom
issue-2014-opencv5-api-coverage
Jul 16, 2026
Merged

shimat merged 3 commits into
mainfrom
issue-2014-opencv5-api-coverage

Conversation

@shimat

@shimat shimat commented Jul 16, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • add OpenCV 5 wrappers for the missing face APIs, including BIF, MACE, prediction collectors, trainable facemarks, FacemarkKazemi, AAM runtime configuration, and dataset utilities
  • add the six img_hash one-shot functions under Cv2.ImgHash
  • add BinaryDescriptor, BinaryDescriptorMatcher, multi-image operations, and drawing helpers for line_descriptor
  • add managed/native boundary validation and regression tests for the new APIs

OpenCV declares BinaryDescriptor::EDLineDetector and EDLineParam inside the class's private section, so they cannot be referenced by external C++ callers and are intentionally not exposed.

Testing

  • cmake --build src\build --config Release --target OpenCvSharpExtern
  • dotnet build src\OpenCvSharp\OpenCvSharp.csproj -c Release --no-restore (0 warnings, 0 errors)
  • dotnet test test\OpenCvSharp.Tests\OpenCvSharp.Tests.csproj -c Release --no-build (1,514 passed, 26 skipped, 0 failed)
  • git diff --check

Closes #2014

Summary by CodeRabbit

  • New Features
    • Added Cv2.ImgHash hashing helpers (average, block-mean, color-moment, Marr-Hildreth, pHash, radial-variance).
    • Introduced face-analysis and facemark training APIs: BIF, MACE, FacemarkTrain workflow, Kazemi, LBF/AAM model read/write, AAM config fitting/data access, plus Cv2.Face dataset/landmark utilities.
    • Added face-recognition prediction collection via PredictCollector/StandardCollector, including a Predict overload.
    • Added binary line-descriptor support: BinaryDescriptor, BinaryDescriptorMatcher, and Cv2.LineDescriptor drawing helpers.
  • Tests
    • Expanded coverage for image hashing, face utilities/training/serialization, collectors, and binary line-descriptors.

@shimat shimat self-assigned this Jul 16, 2026
@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7676e7c5-70b4-466c-bfb6-4e5be4437473

📥 Commits

Reviewing files that changed from the base of the PR and between bc82d63 and d6438b7.

📒 Files selected for processing (6)
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkKazemi.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs
  • test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkLBFTest.cs
🚧 Files skipped from review as they are similar to previous changes (5)
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkKazemi.cs
  • test/OpenCvSharp.Tests/face/FacemarkLBFTest.cs

📝 Walkthrough

Walkthrough

Adds OpenCV face-analysis and facemark APIs, one-shot image hashing, and binary line-descriptor detection, matching, drawing, native interop, and tests.

Changes

Face algorithms and prediction collectors

Layer / File(s) Summary
Face algorithms and collector-based prediction
src/OpenCvSharp/Modules/face/BIF.cs, src/OpenCvSharp/Modules/face/MACE.cs, src/OpenCvSharp/Modules/face/FaceRecognizer/*, src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/*, src/OpenCvSharpExtern/face*, test/OpenCvSharp.Tests/face/*Collector*, test/OpenCvSharp.Tests/face/BIFTest.cs, test/OpenCvSharp.Tests/face/MACETest.cs
Adds BIF and MACE wrappers, prediction collectors, collector-based recognizer prediction, native exports, and tests.

Facemark training and utilities

Layer / File(s) Summary
Facemark training, detection, and dataset utilities
src/OpenCvSharp/Modules/face/Facemark/*, src/OpenCvSharp/Modules/face/Cv2.Face.cs, src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/*, src/OpenCvSharpExtern/face_Facemark.h, test/OpenCvSharp.Tests/face/Facemark*, test/OpenCvSharp.Tests/face/FaceUtilitiesTest.cs
Adds trainable facemark abstractions, Kazemi support, managed detector callbacks, AAM runtime configuration, serialization, dataset loaders, face-point loading, and facemark drawing.

One-shot image hashing

Layer / File(s) Summary
Image-hash convenience wrappers and validation
src/OpenCvSharp/Modules/img_hash/Cv2.ImgHash.cs, src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_img_hash.cs, src/OpenCvSharpExtern/img_hash.h, test/OpenCvSharp.Tests/img_hash/ImgHashFunctionsTest.cs
Adds six one-shot image-hash methods and verifies their results against the corresponding algorithm objects.

Binary line descriptors and matching

Layer / File(s) Summary
Binary descriptor pipeline and drawing APIs
src/OpenCvSharp/Modules/line_descriptors/*, src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_line_descriptor.cs, src/OpenCvSharp/Internal/Vectors/VectorOfKeyLine.cs, src/OpenCvSharpExtern/line_descriptor.h, src/OpenCvSharpExtern/std_vector.h, test/OpenCvSharp.Tests/line_descriptor/BinaryDescriptorTest.cs
Adds binary descriptor configuration, detection, computation, matching, drawing, KeyLine vector construction, native marshaling, and single- and multi-image tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

  • shimat/opencvsharp issue 2019: Directly covers the face, img_hash, and line_descriptor API gaps implemented here.

Possibly related PRs

  • shimat/opencvsharp#1996: Shares the KeyLine native vector interop and VectorOfKeyLine plumbing extended by this change.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main additions: OpenCV 5 face, img_hash, and line_descriptor APIs.
Linked Issues check ✅ Passed The PR implements the requested face, img_hash, and line_descriptor wrappers, including the noted Facemark and collector coverage.
Out of Scope Changes check ✅ Passed No clearly unrelated code changes stand out; the extra serialization, bridge, and test updates support the requested API surface.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-2014-opencv5-api-coverage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/OpenCvSharp/Modules/face/FaceRecognizer/PredictCollector.cs (1)

102-111: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse the Combine helper to construct the dictionary.

Reusing the Combine helper here enforces the array length consistency check (as done in GetResults) and cleanly converts the outputs without redundant Zip and array materialization logic.

♻️ Proposed refactor
     public IReadOnlyDictionary<int, double> GetResultsMap()
     {
         ThrowIfDisposed();
         using var labels = new StdVector<int>();
         using var distances = new StdVector<double>();
         NativeMethods.HandleException(
             NativeMethods.face_StandardCollector_getResultsMap(
                 Handle, labels.CvPtr, distances.CvPtr));
-        return labels.ToArray().Zip(distances.ToArray()).ToDictionary(x => x.First, x => x.Second);
+        return Combine(labels.ToArray(), distances.ToArray()).ToDictionary(x => x.Label, x => x.Distance);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OpenCvSharp/Modules/face/FaceRecognizer/PredictCollector.cs` around lines
102 - 111, Update GetResultsMap to use the existing Combine helper when
converting labels and distances into the result dictionary. Preserve the current
native call and disposal flow, while replacing the direct Zip/ToDictionary
conversion so Combine enforces matching output lengths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/OpenCvSharp/Modules/face/Facemark/FacemarkTrain.cs`:
- Around line 58-67: Change FacemarkTrain.GetData(IntPtr items) from a public
API to an internal-only binding, preventing callers from supplying arbitrary
native pointers. Add or use typed per-algorithm data wrapper methods that
validate and marshal their data before invoking the native getData path, while
preserving disposal and native exception handling.

---

Nitpick comments:
In `@src/OpenCvSharp/Modules/face/FaceRecognizer/PredictCollector.cs`:
- Around line 102-111: Update GetResultsMap to use the existing Combine helper
when converting labels and distances into the result dictionary. Preserve the
current native call and disposal flow, while replacing the direct
Zip/ToDictionary conversion so Combine enforces matching output lengths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6c6b6f94-f361-4d12-8bc3-adb242c14e05

📥 Commits

Reviewing files that changed from the base of the PR and between 6126849 and a8b01de.

📒 Files selected for processing (39)
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_img_hash.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_line_descriptor.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_stdvector.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/FacemarkKazemiParamsData.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/NativeMethods_face_Additional.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/NativeMethods_face_FaceRecognizer.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/NativeMethods_face_Facemark.cs
  • src/OpenCvSharp/Internal/Vectors/VectorOfKeyLine.cs
  • src/OpenCvSharp/Modules/face/BIF.cs
  • src/OpenCvSharp/Modules/face/Cv2.Face.cs
  • src/OpenCvSharp/Modules/face/FaceRecognizer/FaceRecognizer.cs
  • src/OpenCvSharp/Modules/face/FaceRecognizer/PredictCollector.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkFaceDetector.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkKazemi.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkTrain.cs
  • src/OpenCvSharp/Modules/face/MACE.cs
  • src/OpenCvSharp/Modules/img_hash/Cv2.ImgHash.cs
  • src/OpenCvSharp/Modules/line_descriptors/BinaryDescriptor.cs
  • src/OpenCvSharp/Modules/line_descriptors/BinaryDescriptorMatcher.cs
  • src/OpenCvSharp/Modules/line_descriptors/Cv2.LineDescriptor.cs
  • src/OpenCvSharp/Modules/line_descriptors/DrawLinesMatchesFlags.cs
  • src/OpenCvSharpExtern/face.cpp
  • src/OpenCvSharpExtern/face_Additional.h
  • src/OpenCvSharpExtern/face_FaceRecognizer.h
  • src/OpenCvSharpExtern/face_Facemark.h
  • src/OpenCvSharpExtern/img_hash.h
  • src/OpenCvSharpExtern/line_descriptor.h
  • src/OpenCvSharpExtern/std_vector.h
  • test/OpenCvSharp.Tests/face/BIFTest.cs
  • test/OpenCvSharp.Tests/face/FaceUtilitiesTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs
  • test/OpenCvSharp.Tests/face/LBPHFaceRecognizerTest.cs
  • test/OpenCvSharp.Tests/face/MACETest.cs
  • test/OpenCvSharp.Tests/face/StandardCollectorTest.cs
  • test/OpenCvSharp.Tests/img_hash/ImgHashFunctionsTest.cs
  • test/OpenCvSharp.Tests/line_descriptor/BinaryDescriptorTest.cs

Comment thread src/OpenCvSharp/Modules/face/Facemark/FacemarkTrain.cs Outdated
- redesign FacemarkTrain.GetData(void*): the generic raw-pointer binding is
  removed entirely (it was unreferenced) in favor of a typed
  FacemarkAAM.GetData(out Point2f[] s0), since FacemarkAAM is the only
  concrete algorithm that populates anything through it (FacemarkLBF's
  override ignores the pointer and always returns false)
- reuse the Combine helper in StandardCollector.GetResultsMap, matching
  GetResults, instead of a separate Zip/ToDictionary conversion

While fixing the GetData exposure, found that FacemarkAAM/FacemarkLBF/
FacemarkKazemi (like the saliency classes fixed in #2052) crash when calling
Algorithm.Write/Read: cv::face::Facemark inherits cv::Algorithm *virtually*,
so the raw pointer these classes hand to the generic core_Algorithm_write/
read bridge (typed as cv::Algorithm*) is not the same address as the
correctly-adjusted pointer the compiler would produce from the concrete
type. Fixed by giving all three classes their own write/read bridge that
calls write()/read() on the pointer at its native concrete type, plus
regression tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@shimat

shimat commented Jul 16, 2026

Copy link
Copy Markdown
Owner Author

Pushed a follow-up commit addressing CodeRabbit's review:

  • GetData exposure (actionable, Major): removed FacemarkTrain.GetData(IntPtr items) entirely (it was unreferenced) and replaced it with a typed FacemarkAAM.GetData(out Point2f[] s0), since FacemarkAAM is the only concrete algorithm that actually populates anything through getData (confirmed against the opencv_contrib source: FacemarkLBFImpl::getData ignores the pointer and always returns false). The native side now builds and reads a FacemarkAAM::Data struct internally instead of handing callers a raw void*.
  • PredictCollector.GetResultsMap (nitpick): reused the existing Combine helper instead of a separate Zip/ToDictionary conversion, matching GetResults.

While redesigning GetData, found that FacemarkAAM/FacemarkLBF/FacemarkKazemi crash when calling Algorithm.Write/Read (the same bug class I found and fixed for the saliency module in #2052): cv::face::Facemark inherits cv::Algorithm virtually, so the raw pointer these classes hand to the generic core_Algorithm_write/read bridge (typed as cv::Algorithm*) isn't the same address as the correctly-adjusted pointer the compiler would produce from the concrete type. Fixed by giving all three classes their own write/read bridge that calls write()/read() on the pointer at its native concrete type, with regression tests for each.

Full suite: 1544 total, 1518 passed, 26 skipped, 0 failed - no regressions.

Not addressed: the docstring coverage warning (23.08% vs. the 80% threshold) - that's a broad documentation pass across the 39 files in this PR, out of scope for a targeted review-feedback fix.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs`:
- Around line 186-213: Use a unique Guid-based filename for each temporary file
in FacemarkAAMTest.cs lines 186-213, FacemarkKazemiTest.cs lines 21-48, and
FacemarkLBFTest.cs lines 21-48, updating the corresponding ReadWrite test setup
while preserving the existing cleanup logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ea04b6f9-5adb-4ba9-b38a-a0975998111e

📥 Commits

Reviewing files that changed from the base of the PR and between a8b01de and bc82d63.

📒 Files selected for processing (10)
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/face/NativeMethods_face_Facemark.cs
  • src/OpenCvSharp/Modules/face/FaceRecognizer/PredictCollector.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkKazemi.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkTrain.cs
  • src/OpenCvSharpExtern/face_Facemark.h
  • test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs
  • test/OpenCvSharp.Tests/face/FacemarkLBFTest.cs
💤 Files with no reviewable changes (1)
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkTrain.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkKazemi.cs
  • src/OpenCvSharpExtern/face_Facemark.h

Comment on lines +60 to +67
public override void Write(FileStorage fs)
{
ThrowIfDisposed();
ArgumentNullException.ThrowIfNull(fs);

NativeMethods.HandleException(NativeMethods.face_FacemarkAAM_write(Handle, fs.CvPtr));
GC.KeepAlive(fs);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add disposal checks for FileStorage and FileNode instances.

Passing a disposed FileStorage or FileNode object exposes its CvPtr as IntPtr.Zero, which causes an unmanaged segmentation fault when dereferenced by the native write or read functions. Always call ThrowIfDisposed() on these wrapper objects before interacting with their native pointers.

  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L60-L67: Call fs.ThrowIfDisposed(); immediately after the null check in Write.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L76-L83: Call fn.ThrowIfDisposed(); immediately after the null check in Read.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L264-L279: Call fn.ThrowIfDisposed(); immediately after the null check in Params.Read.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L285-L299: Call fs.ThrowIfDisposed(); immediately after the null check in Params.Write.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L60-L67: Call fs.ThrowIfDisposed(); immediately after the null check in Write.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L76-L83: Call fn.ThrowIfDisposed(); immediately after the null check in Read.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L202-L217: Call fn.ThrowIfDisposed(); immediately after the null check in Params.Read.
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L223-L237: Call fs.ThrowIfDisposed(); immediately after the null check in Params.Write.
📍 Affects 2 files
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L60-L67 (this comment)
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L76-L83
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L264-L279
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkAAM.cs#L285-L299
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L60-L67
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L76-L83
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L202-L217
  • src/OpenCvSharp/Modules/face/Facemark/FacemarkLBF.cs#L223-L237

Comment on lines +186 to +213
[Fact]
public void ReadWrite()
{
// cv::face::Facemark inherits Algorithm virtually; this exercises the P/Invoke plumbing
// that keeps the native pointer at its concrete type across the write/read call, rather
// than reinterpreting it as cv::Algorithm* (which would corrupt memory).
using var facemark = FacemarkAAM.Create();

var fileName = Path.Combine(Path.GetTempPath(), "facemark_aam_test.yml");
try
{
using (var fs = new FileStorage(fileName, FileStorage.Modes.Write))
{
fs.Write("marker", 1);
facemark.Write(fs);
}

using var fs2 = new FileStorage(fileName, FileStorage.Modes.Read);
var root = fs2.Root();
Assert.NotNull(root);
facemark.Read(root);
}
finally
{
if (File.Exists(fileName))
File.Delete(fileName);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Use unique filenames to prevent parallel test collisions.

Hardcoding static temporary file names can lead to file-lock conflicts or data corruption if the test suite is executed concurrently (e.g., across multiple CI workers or assemblies) or if a previous test run aborts before cleanup. Incorporate a Guid into the file names.

  • test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs#L186-L213: Change var fileName = Path.Combine(Path.GetTempPath(), "facemark_aam_test.yml"); to var fileName = Path.Combine(Path.GetTempPath(), $"facemark_aam_test_{Guid.NewGuid():N}.yml");.
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs#L21-L48: Change the hardcoded name to include a unique Guid suffix.
  • test/OpenCvSharp.Tests/face/FacemarkLBFTest.cs#L21-L48: Change the hardcoded name to include a unique Guid suffix.
📍 Affects 3 files
  • test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs#L186-L213 (this comment)
  • test/OpenCvSharp.Tests/face/FacemarkKazemiTest.cs#L21-L48
  • test/OpenCvSharp.Tests/face/FacemarkLBFTest.cs#L21-L48
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/OpenCvSharp.Tests/face/FacemarkAAMTest.cs` around lines 186 - 213, Use a
unique Guid-based filename for each temporary file in FacemarkAAMTest.cs lines
186-213, FacemarkKazemiTest.cs lines 21-48, and FacemarkLBFTest.cs lines 21-48,
updating the corresponding ReadWrite test setup while preserving the existing
cleanup logic.

- add fs.ThrowIfDisposed()/fn.ThrowIfDisposed() before dereferencing CvPtr
  in FacemarkAAM/FacemarkLBF/FacemarkKazemi's Write/Read overrides and in
  FacemarkAAM.Params/FacemarkLBF.Params's Read/Write, so a disposed
  FileStorage/FileNode throws ObjectDisposedException instead of handing
  native a null pointer to dereference
- use a Guid-suffixed temp filename in the three Facemark ReadWrite
  regression tests to avoid collisions under parallel test execution

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@shimat

shimat commented Jul 16, 2026

Copy link
Copy Markdown
Owner Author

Pushed a follow-up commit addressing the second round of CodeRabbit review (from the write/read bridge fix):

  • Disposal checks (actionable, Major): added fs.ThrowIfDisposed()/fn.ThrowIfDisposed() before dereferencing CvPtr in FacemarkAAM/FacemarkLBF's Write/Read overrides and in FacemarkAAM.Params/FacemarkLBF.Params's Read/Write - a disposed FileStorage/FileNode now throws ObjectDisposedException instead of handing native a null pointer. Applied the same fix to FacemarkKazemi.Write/Read too for consistency, even though CodeRabbit skipped re-reviewing that file this round (flagged as "similar to previous changes").
  • Unique temp filenames (actionable, Minor): the three ReadWrite regression tests now suffix their temp filename with a Guid, avoiding collisions under parallel test execution.

Full suite: 1544 total, 1518 passed, 26 skipped, 0 failed - no regressions.

Still not addressed: the docstring coverage warning (23.08% vs. 80% threshold) - unchanged from prior rounds, out of scope for a targeted review-feedback pass.

@shimat
shimat merged commit dbfa4de into main Jul 16, 2026
15 of 16 checks passed
@shimat
shimat deleted the issue-2014-opencv5-api-coverage branch July 16, 2026 08:05
@shimat shimat added the enhancement New feature or improvement to OpenCvSharp label Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or improvement to OpenCvSharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenCV 5.x API coverage: face, img_hash, line_descriptor gaps

1 participant