Skip to content

Add saliency wrapper - #1854

Merged
shimat merged 1 commit into
mainfrom
saliency
Apr 2, 2026
Merged

shimat merged 1 commit into
mainfrom
saliency

Conversation

@shimat

@shimat shimat commented Apr 2, 2026 •

Copy link
Copy Markdown
Owner

Fix #1826

This pull request adds C# bindings for the OpenCV Saliency module, enabling .NET users to access various saliency detection algorithms. The changes introduce new wrapper classes and their corresponding native method declarations for four different saliency algorithms, providing object-oriented APIs for creating, configuring, and using these algorithms in managed code.

The most important changes are:

New Saliency Algorithm Wrappers:

P/Invoke Declarations:

  • Introduced new P/Invoke native method definitions for each of the above algorithms, enabling interop with the native OpenCV library functions. (NativeMethods_saliency_MotionSaliencyBinWangApr2014.cs, [1]; NativeMethods_saliency_ObjectnessBING.cs, [2]; NativeMethods_saliency_StaticSaliencyFineGrained.cs, [3]; NativeMethods_saliency_StaticSaliencySpectralResidual.cs, [4]

Summary by CodeRabbit

Release Notes

  • New Features

    • Added four saliency detection algorithms: MotionSaliencyBinWangApr2014 for motion-based saliency detection, ObjectnessBING for objectness detection with bounding boxes, StaticSaliencySpectralResidual for spectral residual-based saliency, and StaticSaliencyFineGrained for fine-grained static saliency analysis. Each algorithm supports computing saliency maps and configurable parameters.
  • Tests

    • Added comprehensive test coverage for all new saliency algorithms.

@shimat shimat self-assigned this Apr 2, 2026
@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR adds comprehensive support for OpenCV saliency computation algorithms including MotionSaliencyBinWangApr2014, ObjectnessBING, StaticSaliencySpectralResidual, and StaticSaliencyFineGrained. The implementation spans C++ interop wrappers, C# P/Invoke bindings, managed algorithm classes, and unit tests.

Changes

Cohort / File(s) Summary
P/Invoke Native Bindings
src/OpenCvSharp/Internal/PInvoke/NativeMethods/saliency/*
Added four partial NativeMethods classes exposing native P/Invoke extern functions for lifecycle management (create, delete, get), compute operations (computeSaliency, computeBinaryMap), property getters/setters (image dimensions, training paths, algorithm parameters), and state initialization. All functions decorated with DllImport(DllExtern, CallingConvention.Cdecl, ExactSpelling=true) returning ExceptionStatus.
Managed Algorithm API
src/OpenCvSharp/Modules/saliency/MotionSaliencyBinWangApr2014.cs, ObjectnessBING.cs, StaticSaliencyFineGrained.cs, StaticSaliencySpectralResidual.cs
Added four public Algorithm-derived wrapper classes providing high-level C# APIs with factory Create() methods, ComputeSaliency() virtual methods, and algorithm-specific configuration methods/properties. Each wraps native P/Invoke calls with lifecycle management via GC.KeepAlive, input validation, and exception handling.
C++ Interop Wrappers
src/OpenCvSharpExtern/saliency_*.h, saliency.cpp, include_opencv.h
Added six header files defining CVAPI(ExceptionStatus) C-callable wrapper functions for four saliency algorithms, implementing object creation/deletion, pointer retrieval, compute operations, and parameter accessors using BEGIN_WRAP/END_WRAP exception handling. Header include aggregator and OpenCV saliency module include added.
Unit Tests
test/OpenCvSharp.Tests/saliency/MotionSaliencyTest.cs, ObjectnessBINGTest.cs, StaticSaliencyTest.cs
Added three test classes validating creation/disposal, parameter get/set round-trips, property persistence, and end-to-end saliency computation workflows using test images and xUnit [Fact] assertions.

Sequence Diagram

sequenceDiagram
    participant User as User Code
    participant API as C# Saliency API<br/>(e.g., MotionSaliencyBinWangApr2014)
    participant PInvoke as P/Invoke Native<br/>Binding
    participant Cpp as C++ Wrapper<br/>(saliency_*.h)
    participant OpenCV as OpenCV<br/>C++ Library

    User->>API: Create()
    API->>PInvoke: saliency_MotionSaliencyBinWangApr2014_create()
    PInvoke->>Cpp: Call extern function
    Cpp->>OpenCV: cv::saliency::MotionSaliencyBinWangApr2014::create()
    OpenCV-->>Cpp: cv::Ptr<...>
    Cpp-->>PInvoke: ExceptionStatus + IntPtr
    PInvoke-->>API: IntPtr (native handle)
    API-->>User: Managed instance

    User->>API: SetImagesize(width, height)
    API->>PInvoke: saliency_MotionSaliencyBinWangApr2014_setImagesize()
    PInvoke->>Cpp: Call extern function
    Cpp->>OpenCV: obj->setImagesize(W, H)
    OpenCV-->>Cpp: void
    Cpp-->>PInvoke: ExceptionStatus
    PInvoke-->>API: ExceptionStatus
    API-->>User: (no return)

    User->>API: Init()
    API->>PInvoke: saliency_MotionSaliencyBinWangApr2014_init()
    PInvoke->>Cpp: Call extern function
    Cpp->>OpenCV: obj->init()
    OpenCV-->>Cpp: bool result
    Cpp-->>PInvoke: ExceptionStatus + int (0/1)
    PInvoke-->>API: ExceptionStatus + int
    API-->>User: bool (success)

    User->>API: ComputeSaliency(image, saliencyMap)
    API->>PInvoke: saliency_MotionSaliencyBinWangApr2014_computeSaliency()
    PInvoke->>Cpp: Call extern function
    Cpp->>OpenCV: obj->computeSaliency(image, saliencyMap)
    OpenCV-->>Cpp: bool result
    Cpp-->>PInvoke: ExceptionStatus + int (0/1)
    PInvoke-->>API: ExceptionStatus + int
    API->>API: Fix output array
    API-->>User: bool (success/failure)

    User->>API: Dispose()
    API->>PInvoke: saliency_Ptr_MotionSaliencyBinWangApr2014_delete()
    PInvoke->>Cpp: Call extern function
    Cpp->>OpenCV: delete cv::Ptr<...>
    OpenCV-->>Cpp: (cleanup)
    Cpp-->>PInvoke: ExceptionStatus
    PInvoke-->>API: ExceptionStatus
    API-->>User: (disposed)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.55% 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 'Add saliency wrapper' is concise and accurately describes the main change—adding saliency algorithm wrappers to OpenCvSharp.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #1826 by implementing C# bindings for four OpenCV saliency algorithms (MotionSaliencyBinWangApr2014, ObjectnessBING, StaticSaliencyFineGrained, StaticSaliencySpectralResidual) with full managed wrapper classes and native P/Invoke interop support.
Out of Scope Changes check ✅ Passed All changes are directly related to adding saliency support: wrapper classes, native interop declarations, header includes, tests, and infrastructure files. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 saliency

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 and usage tips.

@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)
test/OpenCvSharp.Tests/saliency/MotionSaliencyTest.cs (1)

48-51: Consider asserting Init() return value for consistency.

For robustness, assert the Init() return value in the ComputeSaliency test, similar to how it's done in SetImagesizeAndInit.

Suggested fix
         using var saliency = MotionSaliencyBinWangApr2014.Create();
         saliency.SetImagesize(width, height);
-        saliency.Init();
+        Assert.True(saliency.Init());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/OpenCvSharp.Tests/saliency/MotionSaliencyTest.cs` around lines 48 - 51,
The test currently calls MotionSaliencyBinWangApr2014.Create(),
SetImagesize(width, height) and Init() without checking Init()'s return; update
the ComputeSaliency test to assert the boolean result of saliency.Init() (like
in SetImagesizeAndInit) so initialization failures fail the test: after calling
saliency.SetImagesize(...) call var ok = saliency.Init() and assert ok (or
Assert.IsTrue/Assert.True) before proceeding to ComputeSaliency to ensure
consistent behavior across tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/OpenCvSharp/Modules/saliency/ObjectnessBING.cs`:
- Around line 74-94: The P/Invoke signatures for
saliency_ObjectnessBING_setTrainingPath and saliency_ObjectnessBING_setBBResDir
currently use ANSI marshaling and must be updated to UTF-8-safe marshaling;
locate their declarations in the NativeMethods class and change the string
parameter marshaling from [MarshalAs(UnmanagedType.LPStr)] to a UTF-8-safe
alternative (e.g., [MarshalAs(UnmanagedType.LPUTF8Str)] for .NET 5+ or the
project’s platform-specific UTF8 marshaling wrapper used elsewhere like
imgcodecs_imread), then rebuild and run tests to ensure non-ASCII file paths are
handled correctly when calling SetTrainingPath and SetBBResDir.

---

Nitpick comments:
In `@test/OpenCvSharp.Tests/saliency/MotionSaliencyTest.cs`:
- Around line 48-51: The test currently calls
MotionSaliencyBinWangApr2014.Create(), SetImagesize(width, height) and Init()
without checking Init()'s return; update the ComputeSaliency test to assert the
boolean result of saliency.Init() (like in SetImagesizeAndInit) so
initialization failures fail the test: after calling saliency.SetImagesize(...)
call var ok = saliency.Init() and assert ok (or Assert.IsTrue/Assert.True)
before proceeding to ComputeSaliency to ensure consistent behavior across tests.
🪄 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: 86144a2a-f568-4754-88ba-22e7af998341

📥 Commits

Reviewing files that changed from the base of the PR and between ef767e1 and e5385f9.

📒 Files selected for processing (17)
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/saliency/NativeMethods_saliency_MotionSaliencyBinWangApr2014.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/saliency/NativeMethods_saliency_ObjectnessBING.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/saliency/NativeMethods_saliency_StaticSaliencyFineGrained.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/saliency/NativeMethods_saliency_StaticSaliencySpectralResidual.cs
  • src/OpenCvSharp/Modules/saliency/MotionSaliencyBinWangApr2014.cs
  • src/OpenCvSharp/Modules/saliency/ObjectnessBING.cs
  • src/OpenCvSharp/Modules/saliency/StaticSaliencyFineGrained.cs
  • src/OpenCvSharp/Modules/saliency/StaticSaliencySpectralResidual.cs
  • src/OpenCvSharpExtern/include_opencv.h
  • src/OpenCvSharpExtern/saliency.cpp
  • src/OpenCvSharpExtern/saliency_MotionSaliencyBinWangApr2014.h
  • src/OpenCvSharpExtern/saliency_ObjectnessBING.h
  • src/OpenCvSharpExtern/saliency_StaticSaliencyFineGrained.h
  • src/OpenCvSharpExtern/saliency_StaticSaliencySpectralResidual.h
  • test/OpenCvSharp.Tests/saliency/MotionSaliencyTest.cs
  • test/OpenCvSharp.Tests/saliency/ObjectnessBINGTest.cs
  • test/OpenCvSharp.Tests/saliency/StaticSaliencyTest.cs

Comment on lines +74 to +94
public void SetTrainingPath(string trainingPath)
{
ThrowIfDisposed();
if (trainingPath is null)
throw new ArgumentNullException(nameof(trainingPath));
NativeMethods.HandleException(
NativeMethods.saliency_ObjectnessBING_setTrainingPath(RawPtr, trainingPath));
GC.KeepAlive(this);
}

/// <summary>
/// Sets the directory path for writing optional output results.
/// </summary>
public void SetBBResDir(string resultsDir)
{
ThrowIfDisposed();
if (resultsDir is null)
throw new ArgumentNullException(nameof(resultsDir));
NativeMethods.HandleException(
NativeMethods.saliency_ObjectnessBING_setBBResDir(RawPtr, resultsDir));
GC.KeepAlive(this);

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify how ObjectnessBING path setters marshal strings in P/Invoke layer.

set -euo pipefail

echo "== Locate P/Invoke declaration file =="
fd -i 'NativeMethods_saliency_ObjectnessBING.cs' src

echo
echo "== Inspect DllImport/LibraryImport attributes and string param declarations =="
for f in $(fd -i 'NativeMethods_saliency_ObjectnessBING.cs' src); do
  echo "--- $f ---"
  sed -n '1,260p' "$f"
done

echo
echo "== Focused search for marshaling hints =="
rg -n -C3 --type=cs 'saliency_ObjectnessBING_setTrainingPath|saliency_ObjectnessBING_setBBResDir|StringMarshalling|MarshalAs|CharSet|Utf8' src

Repository: shimat/opencvsharp

Length of output: 50375


Update P/Invoke string marshaling for path parameters to UTF-8-safe alternatives.

The saliency_ObjectnessBING_setTrainingPath and saliency_ObjectnessBING_setBBResDir P/Invoke declarations use [MarshalAs(UnmanagedType.LPStr)], which is ANSI/ASCII marshaling and will fail on non-ASCII file paths (e.g., accented characters, CJK, emoji in directory/file names). Other path-handling P/Invoke methods in the codebase (e.g., imgcodecs_imread) use platform-specific or UTF-8 marshaling. Change these declarations to either UnmanagedType.LPUTF8Str (for .NET 5+) or adopt the platform-specific marshaling pattern used elsewhere in the codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/OpenCvSharp/Modules/saliency/ObjectnessBING.cs` around lines 74 - 94, The
P/Invoke signatures for saliency_ObjectnessBING_setTrainingPath and
saliency_ObjectnessBING_setBBResDir currently use ANSI marshaling and must be
updated to UTF-8-safe marshaling; locate their declarations in the NativeMethods
class and change the string parameter marshaling from
[MarshalAs(UnmanagedType.LPStr)] to a UTF-8-safe alternative (e.g.,
[MarshalAs(UnmanagedType.LPUTF8Str)] for .NET 5+ or the project’s
platform-specific UTF8 marshaling wrapper used elsewhere like imgcodecs_imread),
then rebuild and run tests to ensure non-ASCII file paths are handled correctly
when calling SetTrainingPath and SetBBResDir.

@shimat
shimat merged commit 485244e into main Apr 2, 2026
10 checks passed
@shimat
shimat deleted the saliency branch April 2, 2026 11:25
@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.

Saliency computation support ?

1 participant