Add ximgproc EdgeDrawing#1850
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/OpenCvSharpExtern/aruco.h (1)
135-135: Unrelated formatting change in ArUco file.This indentation adjustment to
cornersVecdeclaration 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 usingGradientOperatorenum type inEdgeDrawingParams.EdgeDetectionOperator.The enum is well-documented, but per the context snippet from
EdgeDrawing.cs,EdgeDrawingParams.EdgeDetectionOperatoris declared asintrather thanGradientOperator. This reduces type safety—users must know to cast the enum or use raw integers.If the
inttype is required for P/Invoke struct layout compatibility, consider adding a strongly-typed convenience property that wraps theintfield, 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: falseandreleaseAction: nulltoOpenCvPtrSafeHandle, but cleanup is handled inDisposeUnmanaged(). 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
CvObjectdisposal pattern, but a brief comment explaining whyownsHandle: falseis 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 castingnuinttoint.The
Sizeproperty castsnuinttoint, which could overflow for vectors larger thanint.MaxValue(2.1 billion elements). However, given that eachVec6dis 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
nuintorlongand 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, andximgproc_EdgeDrawing_Params_defaultnow each spell out the full field copy. Since this wrapper is being used as a reference implementation, centralizing theCvEdgeDrawingParams⇄EdgeDrawing::Paramsprojection 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
📒 Files selected for processing (12)
.github/copilot-instructions.mdsrc/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_stdvector.cssrc/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cssrc/OpenCvSharp/Internal/Vectors/VectorOfVec6d.cssrc/OpenCvSharp/Modules/ximgproc/CvXImgProc.cssrc/OpenCvSharp/Modules/ximgproc/EdgeDrawing.cssrc/OpenCvSharp/Modules/ximgproc/Enum/GradientOperator.cssrc/OpenCvSharpExtern/aruco.hsrc/OpenCvSharpExtern/std_vector.hsrc/OpenCvSharpExtern/ximgproc.cppsrc/OpenCvSharpExtern/ximgproc_EdgeDrawing.htest/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs
There was a problem hiding this comment.
🧹 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 onOpenCvSharp.XImgProcforCvEdgeDrawingParams. Consider movingCvEdgeDrawingParamsinto 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
📒 Files selected for processing (2)
src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cstest/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs
🚧 Files skipped from review as they are similar to previous changes (1)
- test/OpenCvSharp.Tests/ximgproc/EdgeDrawingTest.cs
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
EdgeDrawingclass, parameter handling, and support for theVec6dvector type, following a documented pattern for wrapping OpenCV classes. The changes also provide a detailed checklist for future OpenCV class wrappers.EdgeDrawing wrapper implementation:
EdgeDrawingclass insrc/OpenCvSharp/Modules/ximgproc/EdgeDrawing.csthat exposes the full EdgeDrawing algorithm API, including edge, line, and ellipse detection, as well as parameter management through the newEdgeDrawingParamsclass.src/OpenCvSharp/Internal/PInvoke/NativeMethods/ximgproc/NativeMethods_ximgproc_EdgeDrawing.cs, enabling native interop for all EdgeDrawing features.CreateEdgeDrawing()toCvXImgProcfor convenient creation ofEdgeDrawinginstances.Support for new vector type:
std::vector<cv::Vec6d>(needed for ellipse detection results) by introducing theVectorOfVec6dclass insrc/OpenCvSharp/Internal/Vectors/VectorOfVec6d.csand corresponding P/Invoke bindings inNativeMethods_stdvector.cs. [1] [2]Documentation and guidelines:
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
Tests
Documentation