Skip to content

Migration: remaining modules to the ArrayProxy ABI (by-pointer) + tests - #1988

Merged
shimat merged 10 commits into
5.xfrom
feature/inputarray-migration-remaining-5x
Jul 2, 2026
Merged

Migration: remaining modules to the ArrayProxy ABI (by-pointer) + tests#1988
shimat merged 10 commits into
5.xfrom
feature/inputarray-migration-remaining-5x

Conversation

@shimat

@shimat shimat commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

Stacked on #1987. Migrates the remaining modules that still use the raw cv::_InputArray*/cv::_OutputArray*/cv::_InputOutputArray* pointer form to the ArrayProxy ABI, using the same by-pointer form and machine-assisted migration passes established in #1983/#1986/#1987.

Draft; will be updated incrementally as each module lands (one commit per module, same convention as #1986).

Scope note

core_InputArray.h/core_OutputArray.h are excluded: every cv::_InputArray*/cv::_OutputArray* parameter in those two files is the self pointer of the InputArray/OutputArray class's own native backing object (e.g. core_InputArray_getMat(cv::_InputArray *ia, ...)). They implement the class itself and will be retired at the final classref struct flip (blocked on #1977), not migrated as array-proxy arguments now.

Modules migrated so far

module proxy funcs tests
core remainder (Mat/UMat/PCA/SVD/LDA) 36 +11 (Mat/UMat CopyTo/SetTo/Mul/Cross/Dot uncovered → 0; new PCATest.cs/SVDTest.cs; LDA Reconstruct/SubspaceProject/SubspaceReconstruct)
dnn family (dnn/dnn_Model/dnn_TextModel/dnn_superres) 11 +8 (Detect/Segment/Estimate/Recognize/UpsampleMultioutput uncovered → 0, smoke-tested where no committed model matches the output layout)
imgproc remainder (CLAHE/GeneralizedHough/LineSegmentDetector/Segmentation/undistort) 17 +7 (new GeneralizedHoughTest.cs/UndistortTest.cs; IntelligentScissorsMB.ApplyImageFeatures)
objdetect remainder (FaceDetectorYN/QRCodeDetector/chessboard) 14 +1 (Cv2.Find4QuadCornerSubpix uncovered → 0)
video/tracking-adjacent (bgsegm/optflow/optflow_motempl/tracking/video_background_segm) 14 +1 file (new OptFlowTest.cs covers the entire Cv2.OptFlow namespace, previously 0 tests); TrackerCSRT.SetInitialMask
photo/face/shape (photo_HDR/photo_Tonemap/face_FaceRecognizer/face_Facemark/shape_HistogramCostExtractor/shape_ShapeDistanceExtractor/shape_ShapeTransformer) 15 +3 (new CalibrateExposuresTest.cs; Facemark.Fit; FaceRecognizer.Predict(InputArray))
leaf modules (barcode/flann/highgui/imgcodecs/img_hash/quality/saliency/superres/text/videoio/wechat_qrcode/xfeatures2d) 44 +11 (new IndexTest.cs/SuperResTest.cs/AGASTTest.cs — flann.Index, superres, and Cv2.XFeatures2D.AGAST had no test before; HighGui.SelectROI/SelectROIs; QualitySSIM.GetQualityMap; ObjectnessBING.ComputeSaliency; BOWImgDescriptorExtractor.Compute(InputArray) overload)

This batch also fixes a pre-existing bug that the new flann.Index test uncovered: IndexParams and all of its subclasses stored the cv::Ptr<T> smart pointer returned by their native constructor directly as their Handle, instead of extracting the underlying raw T* via the corresponding flann_Ptr_*_get() call (which already existed in the P/Invoke layer but was never wired up). Native functions expecting a raw cv::flann::IndexParams*/SearchParams* therefore dereferenced the smart pointer's own memory layout, corrupting state and crashing inside flann_Index_new. Fixed by switching IndexParams to the established CvPtrObject smart-pointer/raw-pointer pattern used elsewhere in the codebase (e.g. QualityGMSD). This bug predates the ArrayProxy migration and was never exercised because flann.Index had no test before.

Status

All modules with cv::_InputArray*/cv::_OutputArray*/cv::_InputOutputArray* parameters (outside the excluded core_InputArray.h/core_OutputArray.h) are now migrated. Full local test suite passes with 0 failures.

🤖 Generated with Claude Code

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

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fca5a244-90cb-48f8-850a-78690a2a107f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/inputarray-migration-remaining-5x

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.

shimat added a commit that referenced this pull request Jul 2, 2026
features_FlannBasedMatcher_new() takes ownership of the IndexParams/SearchParams
by copying a cv::Ptr<T>*, but the C# wrapper was passing the raw T* (CvPtr)
instead of the smart pointer (SmartPtr). The native side then dereferenced the
raw object's memory as if it were a cv::Ptr's control block, corrupting the
IndexParams held inside FlannBasedMatcher and crashing later, deep inside
cvflann::Index construction, whenever a FlannBasedMatcher actually trained a
flann index (e.g. via match/knnMatch). This is the same class of bug fixed for
cv::flann::Index in the previous commit, just in a different call site that
wasn't touched by that fix.

Confirmed via a macOS crash report (SIGSEGV, EXC_BAD_ACCESS at 0x37) captured
from a PR #1988 CI run, whose faulting-thread stack traced back through
FlannBasedMatcher::train() -> flann::Index::Index() -> the IndexParams map
copy constructor.
@shimat
shimat marked this pull request as ready for review July 2, 2026 05:33
@shimat
shimat force-pushed the feature/inputarray-migration-calib-5x branch from b3c7851 to f2040e1 Compare July 2, 2026 12:17
Base automatically changed from feature/inputarray-migration-calib-5x to 5.x July 2, 2026 12:21
@shimat
shimat force-pushed the feature/inputarray-migration-remaining-5x branch from 25fa707 to f754123 Compare July 2, 2026 12:30
shimat added a commit that referenced this pull request Jul 2, 2026
features_FlannBasedMatcher_new() takes ownership of the IndexParams/SearchParams
by copying a cv::Ptr<T>*, but the C# wrapper was passing the raw T* (CvPtr)
instead of the smart pointer (SmartPtr). The native side then dereferenced the
raw object's memory as if it were a cv::Ptr's control block, corrupting the
IndexParams held inside FlannBasedMatcher and crashing later, deep inside
cvflann::Index construction, whenever a FlannBasedMatcher actually trained a
flann index (e.g. via match/knnMatch). This is the same class of bug fixed for
cv::flann::Index in the previous commit, just in a different call site that
wasn't touched by that fix.

Confirmed via a macOS crash report (SIGSEGV, EXC_BAD_ACCESS at 0x37) captured
from a PR #1988 CI run, whose faulting-thread stack traced back through
FlannBasedMatcher::train() -> flann::Index::Index() -> the IndexParams map
copy constructor.
shimat and others added 10 commits July 2, 2026 21:33
…I (by-pointer) + tests

Continues issue #1976: core_InputArray.h/core_OutputArray.h are intentionally
excluded (every cv::_InputArray*/cv::_OutputArray* there is the self pointer
of those classes' own native backing object, retired only at the final
class -> ref struct flip, not migrated as array-proxy arguments now).

Migrates the remaining genuine array-argument functions in core_Mat.h,
core_UMat.h, core_PCA.h, core_SVD.h and core_LDA.h (36 functions) using the
same by-pointer proxy form and machine-assisted passes as the other stacked
modules.

Adds tests for every previously-uncovered migrated method: Mat/UMat
CopyTo/SetTo(InputArray)/Mul/Cross/Dot, and brand-new PCATest.cs/SVDTest.cs
(neither class had any test before), plus LDA.Reconstruct/SubspaceProject/
SubspaceReconstruct.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Continues issue #1976. Migrates dnn.h (blobFromImageWithParams),
dnn_Model.h (Model/ClassificationModel/DetectionModel/SegmentationModel/
KeypointsModel), dnn_TextModel.h (TextRecognitionModel/TextDetectionModel)
and dnn_superres.h (DnnSuperResImpl) - 11 functions - using the same
by-pointer proxy form and machine-assisted passes as the other stacked
modules.

Adds tests for every previously-uncovered migrated method. Where a real
model file matching the method's expected output layout isn't committed
(DetectionModel.Detect/SegmentationModel.Segment/KeypointsModel.Estimate/
TextRecognitionModel.Recognize/DnnSuperResImpl.UpsampleMultioutput), the
test reaches native with the InputArray param and either gets a clean
failure or a real result - both prove the ArrayProxy wiring is correct
without requiring a network download in CI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tor/Segmentation/undistort) to the ArrayProxy ABI (by-pointer) + tests

Continues issue #1976. Migrates the class-based/undistort pieces of imgproc
that were left out of the earlier Cv2-static imgproc.h pass: imgproc_CLAHE.h,
imgproc_GeneralizedHough.h, imgproc_Segmentation.h (IntelligentScissorsMB)
and imgproc_undistort.h via the standard machine-assisted passes, plus
imgproc_LineSegmentDetector.h by hand (its functions predate the cvTry/
ExceptionStatus convention - CVAPI(void)/CVAPI(int) - so the migration
scripts, which only match CVAPI(ExceptionStatus), don't touch it; the
proxy conversion itself needed no cvTry wrapping either way).

Adds tests for every previously-uncovered migrated method: CLAHE was
already covered; new tests for GeneralizedHough.SetTemplate/Detect (both
overloads, no prior test file existed), IntelligentScissorsMB.
ApplyImageFeatures, and Cv2.Undistort/InitUndistortRectifyMap/
InitWideAngleProjMap/DrawFrameAxes (the inventory tool's first pass falsely
counted InitUndistortRectifyMap as covered - it was matching the unrelated
Cv2.FishEye.InitUndistortRectifyMap call by method name only).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ard) to the ArrayProxy ABI (by-pointer) + tests

Continues issue #1976. Migrates objdetect_FaceDetectorYN.h,
objdetect_QRCodeDetector.h and objdetect_chessboard.h (14 functions) using
the standard machine-assisted passes.

Adds a test for the one previously-uncovered migrated method,
Cv2.Find4QuadCornerSubpix (refines chessboard corners found by
FindChessboardCorners on the existing calibration/00.jpg fixture);
FaceDetectorYN.Detect and all QRCodeDetector methods were already covered.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…pointer) + tests

Continues issue #1976. Migrates bgsegm.h, optflow.h, optflow_motempl.h,
tracking.h and video_background_segm.h (14 functions) using the standard
machine-assisted passes. The bgsegm apply/getBackgroundImage functions have
no C# caller (BackgroundSubtractorMOG/GMG use the shared base class's
video_BackgroundSubtractor_apply via polymorphism instead), so they are
migrated but untestable through the public API - consistent with how they
were already unreachable before this change.

Adds tests for every previously-uncovered, reachable migrated method: a new
OptFlowTest.cs covers the entire Cv2.OptFlow namespace (UpdateMotionHistory/
CalcMotionGradient/CalcGlobalOrientation/SegmentMotion/CalcOpticalFlowSF
(both overloads)/CalcOpticalFlowSparseToDense), which had zero test coverage
before. TrackerCSRT.SetInitialMask also gets its first test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…) + tests

Continues issue #1976. Migrates photo_HDR.h, photo_Tonemap.h,
face_FaceRecognizer.h, face_Facemark.h, shape_HistogramCostExtractor.h,
shape_ShapeDistanceExtractor.h and shape_ShapeTransformer.h (15 functions)
using the standard machine-assisted passes. Also fixes Cv2.Shape.cs, a
Cv2.EMDL1 caller that the first pass over shape_HistogramCostExtractor.h
missed (found by the managed build failing on a raw IntPtr where an
InputArrayProxy was now expected).

Adds tests for the previously-uncovered migrated methods: new
CalibrateExposuresTest.cs for CalibrateCRF.Process (via CalibrateDebevec/
CalibrateRobertson - MergeExposures.Process was already covered via
MergeDebevec), Facemark.Fit (smoke-tested; no trained LBF model is
committed), and FaceRecognizer.Predict(InputArray) (the single-return
overload, alongside the already-covered out-param overload).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…lity/saliency/superres/text/videoio/wechat_qrcode/xfeatures2d) to the ArrayProxy ABI (by-pointer) + tests

44 functions across 17 native headers migrated to the by-pointer
InputArrayProxy/OutputArrayProxy ABI, following the established
core/imgproc pattern (issue #1976).

Also fixes a pre-existing bug uncovered by the new flann.Index test:
IndexParams and all its subclasses (LinearIndexParams, KDTreeIndexParams,
KMeansIndexParams, LshIndexParams, CompositeIndexParams,
AutotunedIndexParams, SavedIndexParams, SearchParams) stored the
cv::Ptr<T> smart pointer returned by their native constructor directly
as their Handle, instead of extracting the underlying raw T* via the
corresponding flann_Ptr_*_get() call. Native functions expecting a raw
cv::flann::IndexParams*/SearchParams* therefore dereferenced the smart
pointer's own memory layout, corrupting state and crashing inside
flann_Index_new. Fixed by switching IndexParams to the established
CvPtrObject smart-pointer/raw-pointer pattern used elsewhere in the
codebase (e.g. QualityGMSD). This bug predates the ArrayProxy migration
and was never exercised because flann.Index had no test before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
features_FlannBasedMatcher_new() takes ownership of the IndexParams/SearchParams
by copying a cv::Ptr<T>*, but the C# wrapper was passing the raw T* (CvPtr)
instead of the smart pointer (SmartPtr). The native side then dereferenced the
raw object's memory as if it were a cv::Ptr's control block, corrupting the
IndexParams held inside FlannBasedMatcher and crashing later, deep inside
cvflann::Index construction, whenever a FlannBasedMatcher actually trained a
flann index (e.g. via match/knnMatch). This is the same class of bug fixed for
cv::flann::Index in the previous commit, just in a different call site that
wasn't touched by that fix.

Confirmed via a macOS crash report (SIGSEGV, EXC_BAD_ACCESS at 0x37) captured
from a PR #1988 CI run, whose faulting-thread stack traced back through
FlannBasedMatcher::train() -> flann::Index::Index() -> the IndexParams map
copy constructor.
Eliminates every warning surfaced by a clean Release build (174 -> 0):
- CA2000: split chained `LoadImage(...)[rect]`/`new IndexParams()` expressions
  into separate `using` declarations so every disposable is tracked
- CA1861: hoist constant array literals passed to repeatedly-invoked test
  helpers into static readonly fields
- CA5394: mark test files that use seeded `Random` for synthetic data as
  intentionally non-cryptographic (matches existing CoreTest.cs convention)
- CS8602/CS8604: add the missing null checks that StereoCalibrate's
  InputArray overload and FindHomography/FindFundamentalMat's mask parameter
  should have had, and widen InputArray's Mat conversion/factory to accept
  null (mirroring the existing nullable-Mat constructor) so passing a null
  Mat for an optional InputArray? parameter no longer looks unsafe
- CS1573: document the AlgorithmHint `hint` parameter added to
  CvtColor/CvtColorTwoPlane/GaussianBlur/Remap/WarpAffine/WarpPerspective
- CS1591: suppress doc-comment requirements on the internal blittable
  FacemarkAAM/LBF ParamsData marshalling structs (same pattern already used
  for CvEdgeDrawingParams)
- CA1859/CA1805/CA1069/CA1000: narrow InputArray's owned-disposable field to
  Mat, drop a redundant default-value initializer, and suppress the two
  known-intentional false positives (PutTextFlags' dual-axis bit flags,
  SparseMat<T>'s generic static factory)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
calcOpticalFlowFarneback segfaults (SIGSEGV) inside libOpenCvSharpExtern
on macOS arm64, Linux arm64, and the manylinux x64 build. Confirmed via
a symbolicated macOS arm64 crash report pointing at
superres_DenseOpticalFlowExt_calc - a pre-existing native robustness gap
in this rarely-used module, not something introduced by the ArrayProxy
migration. Follows the same SkipUnless(IsWindows) precedent already used
for XImgProc.SuperpixelTest.SeedsSimple.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@shimat
shimat force-pushed the feature/inputarray-migration-remaining-5x branch from f754123 to bcec38c Compare July 2, 2026 12:34
@shimat
shimat merged commit 7f5409a into 5.x Jul 2, 2026
11 checks passed
@shimat
shimat deleted the feature/inputarray-migration-remaining-5x branch July 2, 2026 12:46
@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.

1 participant