Skip to content

Add ximgproc EdgeDrawing#1850

Merged
shimat merged 5 commits into
mainfrom
ximgproc_EdgeDrawing
Mar 31, 2026
Merged

Add ximgproc EdgeDrawing#1850
shimat merged 5 commits into
mainfrom
ximgproc_EdgeDrawing

Conversation

@shimat
Copy link
Copy Markdown
Owner

@shimat shimat commented Mar 31, 2026

Fix #1791

This pull request adds a complete C# wrapper for the OpenCV EdgeDrawing algorithm, including support for its parameters, output types, and integration with the OpenCvSharp library. It introduces the new EdgeDrawing class, parameter handling, and support for the Vec6d vector type, following a documented pattern for wrapping OpenCV classes. The changes also provide a detailed checklist for future OpenCV class wrappers.

EdgeDrawing wrapper implementation:

  • Added a new EdgeDrawing class in src/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cs that exposes the full EdgeDrawing algorithm API, including edge, line, and ellipse detection, as well as parameter management through the new EdgeDrawingParams class.
  • Implemented P/Invoke bindings for EdgeDrawing methods in src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs, enabling native interop for all EdgeDrawing features.
  • Added a factory method CreateEdgeDrawing() to CvXImgProc for convenient creation of EdgeDrawing instances.

Support for new vector type:

  • Added support for std::vector<cv::Vec6d> (needed for ellipse detection results) by introducing the VectorOfVec6d class in src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs and corresponding P/Invoke bindings in NativeMethods_stdvector.cs. [1] [2]

Documentation and guidelines:

  • Provided a comprehensive checklist and code patterns for wrapping new OpenCV classes, especially those inheriting from cv::Algorithm, in .github/copilot-instructions.md. This includes file organization, C++/C# patterns, and handling of parameter structs and vector types, with EdgeDrawing as a reference implementation.

Summary by CodeRabbit

  • New Features

    • Added EdgeDrawing algorithm with APIs to detect edges, gradients, segments, lines and ellipses; factory creation and parameter get/set.
    • Added EdgeDrawingParams configuration and new GradientOperator enum.
    • Added Vec6d vector support and managed vector wrapper with array conversion.
  • Tests

    • Added comprehensive EdgeDrawing unit tests covering creation, detection flows, vector/array returns and parameter round-trips.
  • Documentation

    • Added detailed guidelines for standardized OpenCV wrapper bindings.

@shimat shimat self-assigned this Mar 31, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

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: ab68f210-b609-4466-b737-62fedee4f0ff

📥 Commits

Reviewing files that changed from the base of the PR and between 6cbd543 and 9e6d83e.

📒 Files selected for processing (1)
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs

📝 Walkthrough

Walkthrough

Adds ximgproc EdgeDrawing: C plain‑API header and implementation hooks, std::vectorcv::Vec6d support, P/Invoke declarations, managed Algorithm wrapper and params, Vec6d vector wrapper, factory/enum additions, XUnit tests, and developer documentation for creating similar wrappers.

Changes

Cohort / File(s) Summary
Documentation
\.github/copilot-instructions.md
Added step‑by‑step guidance and checklists for creating wrapper bindings for OpenCV C++ classes inheriting from cv::Algorithm.
Native C API & Headers
src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h, src/OpenCvSharpExtern/std_vector.h, src/OpenCvSharpExtern/ximgproc.cpp, src/OpenCvSharpExtern/aruco.h
New plain‑C interop header for cv::ximgproc::EdgeDrawing (CvEdgeDrawingParams, create/delete, detect/get/set, params default). Added std::vector<cv::Vec6d> wrappers and include; one minor indentation tweak in aruco.h.
P/Invoke Bindings
src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_stdvector.cs, src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs
Declared extern methods for Vec6d vector operations and EdgeDrawing native functions (creation, lifecycle, detect/get methods, params get/set). Added blittable CvEdgeDrawingParams struct for marshaling.
Managed Vector Wrapper
src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs
New VectorOfVec6d implementing IStdVector<Vec6d> with native allocation/free, Size/ElemPtr, ToArray() and generic ToArray<T>() using block memory copy and GC.KeepAlive.
Managed API & Enum
src/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cs, src/OpenCvSharp/Modules/ximgproc/CvXImgProc.cs, src/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cs
Added EdgeDrawing Algorithm wrapper and EdgeDrawingParams (Default/Get/Set), detection/retrieval methods (edges, gradient, segments, lines, ellipses), factory method CreateEdgeDrawing(), and GradientOperator enum.
Tests
test/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs
Added XUnit tests covering creation/disposal, edge/gradient detection, segments, lines/ellipses (Mat and vector variants), and params default and round‑trip get/set.

Sequence Diagram

sequenceDiagram
    participant Client as Client Code
    participant Mgd as EdgeDrawing (Managed)
    participant Params as EdgeDrawingParams
    participant PInvoke as P/Invoke Layer
    participant Native as Native C API

    Client->>Mgd: Create()
    Mgd->>PInvoke: ximgproc_createEdgeDrawing()
    PInvoke->>Native: ximgproc_createEdgeDrawing()
    Native-->>PInvoke: Ptr<EdgeDrawing>
    PInvoke-->>Mgd: native IntPtr
    Mgd-->>Client: EdgeDrawing instance

    Client->>Mgd: DetectEdges(src)
    Mgd->>PInvoke: ximgproc_EdgeDrawing_detectEdges(ptr, src)
    PInvoke->>Native: ximgproc_EdgeDrawing_detectEdges()
    Native-->>PInvoke: ExceptionStatus
    PInvoke-->>Mgd: status
    Mgd-->>Client: void

    Client->>Mgd: DetectLines()
    Mgd->>PInvoke: ximgproc_EdgeDrawing_detectLines_vector(ptr, vector_ptr)
    PInvoke->>Native: ximgproc_EdgeDrawing_detectLines_vector()
    Native-->>PInvoke: populated std::vector<cv::Vec4f>
    PInvoke-->>Mgd: vector ptr
    Mgd->>Mgd: Marshal vector -> Vec4f[]
    Mgd-->>Client: Vec4f[] result

    Client->>Mgd: GetParams()
    Mgd->>PInvoke: ximgproc_EdgeDrawing_getParams(ptr, out nativeParams)
    PInvoke->>Native: ximgproc_EdgeDrawing_getParams()
    Native-->>PInvoke: CvEdgeDrawingParams
    PInvoke-->>Mgd: native struct
    Mgd-->>Params: construct EdgeDrawingParams
    Params-->>Client: managed params

    Client->>Mgd: Dispose()
    Mgd->>PInvoke: ximgproc_Ptr_EdgeDrawing_delete(ptr)
    PInvoke->>Native: ximgproc_Ptr_EdgeDrawing_delete()
    Native-->>PInvoke: cleanup
    PInvoke-->>Mgd: done
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.53% 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 ximgproc EdgeDrawing' clearly and concisely summarizes the main change: adding EdgeDrawing wrapper functionality to the ximgproc module.
Linked Issues check ✅ Passed The PR fully implements EdgeDrawing wrapper for ximgproc module including C# class, P/Invoke bindings, parameter management, vector support, tests, and documentation as required by issue #1791.
Out of Scope Changes check ✅ Passed All changes are directly scoped to EdgeDrawing implementation: wrapper classes, P/Invoke bindings, vector support, factory methods, tests, and documentation. The minor aruco.h indentation fix is negligible.

✏️ 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 ximgproc_EdgeDrawing

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 (5)
src/OpenCvSharpExtern/aruco.h (1)

135-135: Unrelated formatting change in ArUco file.

This indentation adjustment to cornersVec declaration appears unrelated to the EdgeDrawing wrapper implementation described in the PR objectives. Consider removing unrelated changes to keep the PR focused.

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

In `@src/OpenCvSharpExtern/aruco.h` at line 135, The change to the ArUco header is
an unnecessary formatting-only edit; revert the altered line that declares
cornersVec (the declaration "std::vector<std::vector<cv::Point2f> >
cornersVec(cornersLength1);") back to its original formatting or remove the
whitespace-only edit so the ArUco file remains unchanged—ensure only
EdgeDrawing-related files contain PR changes and leave the symbols and
declarations (e.g., cornersVec) identical to their prior state.
src/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cs (1)

1-27: Consider using GradientOperator enum type in EdgeDrawingParams.EdgeDetectionOperator.

The enum is well-documented, but per the context snippet from EdgeDrawing.cs, EdgeDrawingParams.EdgeDetectionOperator is declared as int rather than GradientOperator. This reduces type safety—users must know to cast the enum or use raw integers.

If the int type is required for P/Invoke struct layout compatibility, consider adding a strongly-typed convenience property that wraps the int field, or document the expected usage in the property's XML comment.

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

In `@src/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cs` around lines 1 -
27, EdgeDrawingParams currently exposes EdgeDetectionOperator as an int which
reduces type safety; change the API to use the GradientOperator enum where
possible by replacing the int-typed property with a GradientOperator-typed
property (or add a new strongly-typed wrapper property) so consumers can use
GradientOperator.PreWitt/Sobel/etc. Update the EdgeDrawingParams class
(EdgeDrawingParams.EdgeDetectionOperator) to either change its type to
GradientOperator or add a pair of members: keep the existing int field for
P/Invoke compatibility and add a new property like EdgeDetectionOperatorEnum of
type GradientOperator that gets/sets the underlying int field (performing safe
casts and validation), and update any usages in EdgeDrawing/EdgeDrawing.cs to
use the enum property.
src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs (2)

15-19: Clarify the SafeHandle ownership pattern.

The constructor passes ownsHandle: false and releaseAction: null to OpenCvPtrSafeHandle, but cleanup is handled in DisposeUnmanaged(). While this works correctly, it's somewhat unusual—typically the SafeHandle would own the release responsibility.

This pattern appears intentional to maintain consistency with the base CvObject disposal pattern, but a brief comment explaining why ownsHandle: false is used here would improve maintainability.

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

In `@src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs` around lines 15 - 19, The
VectorOfVec6d constructor creates the native pointer via
NativeMethods.vector_Vec6d_new1() and wraps it with OpenCvPtrSafeHandle using
ownsHandle: false and releaseAction: null; add a concise comment in the
VectorOfVec6d() constructor explaining that ownsHandle is false intentionally
because actual cleanup is delegated to the class's DisposeUnmanaged()
(consistent with the CvObject disposal pattern) so reviewers understand why the
SafeHandle does not own the release responsibility; reference
OpenCvPtrSafeHandle, DisposeUnmanaged, and NativeMethods.vector_Vec6d_new1 in
the comment for clarity.

33-41: Potential integer overflow when casting nuint to int.

The Size property casts nuint to int, which could overflow for vectors larger than int.MaxValue (2.1 billion elements). However, given that each Vec6d is 48 bytes, this would require ~100GB of memory, making overflow practically impossible in real-world usage.

The current implementation is acceptable, but if future-proofing is desired, consider returning nuint or long and updating callers accordingly.

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

In `@src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs` around lines 33 - 41, The
Size property in VectorOfVec6d currently casts the nuint returned by
NativeMethods.vector_Vec6d_getSize(CvPtr) to int which can overflow; change the
Size API to return nuint (or long) instead of int and propagate that change
through all callers (update any code using VectorOfVec6d.Size to handle the
wider type), or if you must keep an int API add an explicit safe check: get the
nuint value from NativeMethods.vector_Vec6d_getSize(CvPtr), GC.KeepAlive(this),
then if the value > int.MaxValue throw or clamp before casting; reference
VectorOfVec6d.Size and NativeMethods.vector_Vec6d_getSize when making the
change.
src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h (1)

132-193: Extract the params marshaling into helpers.

ximgproc_EdgeDrawing_getParams, ximgproc_EdgeDrawing_setParams, and ximgproc_EdgeDrawing_Params_default now each spell out the full field copy. Since this wrapper is being used as a reference implementation, centralizing the CvEdgeDrawingParamsEdgeDrawing::Params projection will make the next params addition much harder to miss.

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

In `@src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h` around lines 132 - 193, The
three functions ximgproc_EdgeDrawing_getParams, ximgproc_EdgeDrawing_setParams,
and ximgproc_EdgeDrawing_Params_default duplicate field-by-field marshaling;
extract this logic into two helper routines (e.g., ToNativeParams(const
CvEdgeDrawingParams&, cv::ximgproc::EdgeDrawing::Params&) and ToCvParams(const
cv::ximgproc::EdgeDrawing::Params&, CvEdgeDrawingParams&)) and replace the
copies in getParams, setParams, and Params_default to call these helpers (use
obj->params with ToCvParams in get/default and use ToNativeParams then
obj->setParams in setParams) so future param additions are handled in one place
and reduce duplication.
🤖 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/ximgproc/EdgeDrawing.cs`:
- Around line 43-45: The EdgeDetectionOperator property is declared/used as int
but should be the GradientOperator enum; change the EdgeDrawing property/field
type EdgeDetectionOperator from int to GradientOperator and update all
assignments to cast/convert p.EdgeDetectionOperator to GradientOperator (e.g.,
EdgeDetectionOperator = (GradientOperator)p.EdgeDetectionOperator), and
similarly update any constructors or places that set/read this value (references
to PFmode, GradientThresholdValue and parameter p.EdgeDetectionOperator) so the
API uses GradientOperator everywhere instead of int.

---

Nitpick comments:
In `@src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs`:
- Around line 15-19: The VectorOfVec6d constructor creates the native pointer
via NativeMethods.vector_Vec6d_new1() and wraps it with OpenCvPtrSafeHandle
using ownsHandle: false and releaseAction: null; add a concise comment in the
VectorOfVec6d() constructor explaining that ownsHandle is false intentionally
because actual cleanup is delegated to the class's DisposeUnmanaged()
(consistent with the CvObject disposal pattern) so reviewers understand why the
SafeHandle does not own the release responsibility; reference
OpenCvPtrSafeHandle, DisposeUnmanaged, and NativeMethods.vector_Vec6d_new1 in
the comment for clarity.
- Around line 33-41: The Size property in VectorOfVec6d currently casts the
nuint returned by NativeMethods.vector_Vec6d_getSize(CvPtr) to int which can
overflow; change the Size API to return nuint (or long) instead of int and
propagate that change through all callers (update any code using
VectorOfVec6d.Size to handle the wider type), or if you must keep an int API add
an explicit safe check: get the nuint value from
NativeMethods.vector_Vec6d_getSize(CvPtr), GC.KeepAlive(this), then if the value
> int.MaxValue throw or clamp before casting; reference VectorOfVec6d.Size and
NativeMethods.vector_Vec6d_getSize when making the change.

In `@src/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cs`:
- Around line 1-27: EdgeDrawingParams currently exposes EdgeDetectionOperator as
an int which reduces type safety; change the API to use the GradientOperator
enum where possible by replacing the int-typed property with a
GradientOperator-typed property (or add a new strongly-typed wrapper property)
so consumers can use GradientOperator.PreWitt/Sobel/etc. Update the
EdgeDrawingParams class (EdgeDrawingParams.EdgeDetectionOperator) to either
change its type to GradientOperator or add a pair of members: keep the existing
int field for P/Invoke compatibility and add a new property like
EdgeDetectionOperatorEnum of type GradientOperator that gets/sets the underlying
int field (performing safe casts and validation), and update any usages in
EdgeDrawing/EdgeDrawing.cs to use the enum property.

In `@src/OpenCvSharpExtern/aruco.h`:
- Line 135: The change to the ArUco header is an unnecessary formatting-only
edit; revert the altered line that declares cornersVec (the declaration
"std::vector<std::vector<cv::Point2f> > cornersVec(cornersLength1);") back to
its original formatting or remove the whitespace-only edit so the ArUco file
remains unchanged—ensure only EdgeDrawing-related files contain PR changes and
leave the symbols and declarations (e.g., cornersVec) identical to their prior
state.

In `@src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h`:
- Around line 132-193: The three functions ximgproc_EdgeDrawing_getParams,
ximgproc_EdgeDrawing_setParams, and ximgproc_EdgeDrawing_Params_default
duplicate field-by-field marshaling; extract this logic into two helper routines
(e.g., ToNativeParams(const CvEdgeDrawingParams&,
cv::ximgproc::EdgeDrawing::Params&) and ToCvParams(const
cv::ximgproc::EdgeDrawing::Params&, CvEdgeDrawingParams&)) and replace the
copies in getParams, setParams, and Params_default to call these helpers (use
obj->params with ToCvParams in get/default and use ToNativeParams then
obj->setParams in setParams) so future param additions are handled in one place
and reduce duplication.
🪄 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: e0cc3492-620b-4c99-b127-5326e39c1c92

📥 Commits

Reviewing files that changed from the base of the PR and between f0d9186 and 4ce32a0.

📒 Files selected for processing (12)
  • .github/copilot-instructions.md
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_stdvector.cs
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs
  • src/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cs
  • src/OpenCvSharp/Modules/ximgproc/CvXImgProc.cs
  • src/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cs
  • src/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cs
  • src/OpenCvSharpExtern/aruco.h
  • src/OpenCvSharpExtern/std_vector.h
  • src/OpenCvSharpExtern/ximgproc.cpp
  • src/OpenCvSharpExtern/ximgproc_EdgeDrawing.h
  • test/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs

Comment thread src/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs (1)

2-2: Reduce layering coupling between Internal interop and module namespace.

NativeMethods_ximgproc_EdgeDrawing.cs (Internal layer) currently depends on OpenCvSharp.XImgProc for CvEdgeDrawingParams. Consider moving CvEdgeDrawingParams into an Internal interop-struct location so module wrappers depend on Internal, not vice versa.

Also applies to: 51-57

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

In
`@src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs`
at line 2, The Internal interop file NativeMethods_ximgproc_EdgeDrawing.cs
should not depend on the module namespace: move the CvEdgeDrawingParams
definition out of OpenCvSharp.XImgProc into an Internal interop struct (e.g., in
the same Internal/PInvoke namespace used by other native wrappers), replace the
using OpenCvSharp.XImgProc and update all references in
NativeMethods_ximgproc_EdgeDrawing (and any other occurrences in this file) to
the new Internal struct type, and ensure the module-level wrapper continues to
map/translate between the public CvEdgeDrawingParams API type and the new
Internal interop struct so layering is one-directional (module -> Internal).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs`:
- Line 2: The Internal interop file NativeMethods_ximgproc_EdgeDrawing.cs should
not depend on the module namespace: move the CvEdgeDrawingParams definition out
of OpenCvSharp.XImgProc into an Internal interop struct (e.g., in the same
Internal/PInvoke namespace used by other native wrappers), replace the using
OpenCvSharp.XImgProc and update all references in
NativeMethods_ximgproc_EdgeDrawing (and any other occurrences in this file) to
the new Internal struct type, and ensure the module-level wrapper continues to
map/translate between the public CvEdgeDrawingParams API type and the new
Internal interop struct so layering is one-directional (module -> Internal).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 55a00a47-9f43-46f7-ac00-4ace76f3f87b

📥 Commits

Reviewing files that changed from the base of the PR and between 4ce32a0 and 9227eb8.

📒 Files selected for processing (2)
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs
  • test/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ximgproc EdgeDrawing methods

1 participant