Skip to content

Commit 1d8b597

Browse files
authored
Merge pull request #2027 from shimat/feature/opencv5-api-coverage-2008
Fill OpenCV 5.x API gaps in calib/stereo/flann/imgproc/core
2 parents 01de0dc + dfcae82 commit 1d8b597

27 files changed

Lines changed: 1124 additions & 7 deletions

src/OpenCvSharp/Cv2/Cv2_calib.cs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public static double CalibrateCamera(
216216
NativeMethods.HandleException(
217217
NativeMethods.calib_calibrateCamera_InputArray(
218218
objectPointsPtrs, objectPointsPtrs.Length,
219-
imagePointsPtrs, objectPointsPtrs.Length,
219+
imagePointsPtrs, imagePointsPtrs.Length,
220220
imageSize, cameraMatrix.Proxy, distCoeffs.Proxy,
221221
rvecsVec.CvPtr, tvecsVec.CvPtr, (int) flags, criteria0, out var ret));
222222
GC.KeepAlive(cameraMatrix.Source);
@@ -295,6 +295,66 @@ public static double CalibrateCamera(
295295
}
296296
}
297297

298+
/// <summary>
299+
/// Finds intrinsic and extrinsic camera parameters, additionally allowing one point of the
300+
/// calibration pattern object to be optimized ("releasing object" method). Useful when the
301+
/// calibration pattern is not perfectly rigid/planar.
302+
/// </summary>
303+
/// <param name="objectPoints">Vector of vectors of calibration pattern points, as in CalibrateCamera.</param>
304+
/// <param name="imagePoints">Vector of vectors of the projections of calibration pattern points.</param>
305+
/// <param name="imageSize">Size of the image used only to initialize the intrinsic camera matrix.</param>
306+
/// <param name="iFixedPoint">The index of the object point to be fixed. It must be within [1, objectPoints[0].Count - 2].
307+
/// It is ignored with <see cref="CalibrationFlags.FixK3"/> or if the calibration pattern is a non-planar rig.</param>
308+
/// <param name="cameraMatrix">Output 3x3 floating-point camera matrix.</param>
309+
/// <param name="distCoeffs">Output vector of distortion coefficients.</param>
310+
/// <param name="rvecs">Output vector of rotation vectors estimated for each pattern view.</param>
311+
/// <param name="tvecs">Output vector of translation vectors estimated for each pattern view.</param>
312+
/// <param name="newObjPoints">The updated output vector of calibration pattern points, where the coordinates
313+
/// of the fixed point (index iFixedPoint) are unchanged.</param>
314+
/// <param name="flags">Different flags that may be zero or a combination of the CalibrationFlag values</param>
315+
/// <param name="criteria">Termination criteria for the iterative optimization algorithm.</param>
316+
/// <returns>Root mean square (RMS) re-projection error.</returns>
317+
public static double CalibrateCameraRO(
318+
IEnumerable<Mat> objectPoints,
319+
IEnumerable<Mat> imagePoints,
320+
Size imageSize,
321+
int iFixedPoint,
322+
InputOutputArray cameraMatrix,
323+
InputOutputArray distCoeffs,
324+
out Mat[] rvecs,
325+
out Mat[] tvecs,
326+
OutputArray newObjPoints,
327+
CalibrationFlags flags = CalibrationFlags.None,
328+
TermCriteria? criteria = null)
329+
{
330+
ArgumentNullException.ThrowIfNull(objectPoints);
331+
ArgumentNullException.ThrowIfNull(imagePoints);
332+
333+
var criteria0 = criteria.GetValueOrDefault(
334+
new TermCriteria(CriteriaTypes.Count | CriteriaTypes.Eps, 30, Double.Epsilon));
335+
336+
var objectPointsPtrs = objectPoints.Select(x => x.CvPtr).ToArray();
337+
var imagePointsPtrs = imagePoints.Select(x => x.CvPtr).ToArray();
338+
339+
using var rvecsVec = new VectorOfMat();
340+
using var tvecsVec = new VectorOfMat();
341+
NativeMethods.HandleException(
342+
NativeMethods.calib_calibrateCameraRO_InputArray(
343+
objectPointsPtrs, objectPointsPtrs.Length,
344+
imagePointsPtrs, imagePointsPtrs.Length,
345+
imageSize, iFixedPoint, cameraMatrix.Proxy, distCoeffs.Proxy,
346+
rvecsVec.CvPtr, tvecsVec.CvPtr, newObjPoints.Proxy, (int) flags, criteria0, out var ret));
347+
GC.KeepAlive(cameraMatrix.Source);
348+
GC.KeepAlive(distCoeffs.Source);
349+
GC.KeepAlive(newObjPoints.Source);
350+
GC.KeepAlive(objectPoints);
351+
GC.KeepAlive(imagePoints);
352+
rvecs = rvecsVec.ToArray();
353+
tvecs = tvecsVec.ToArray();
354+
355+
return ret;
356+
}
357+
298358
/// <summary>
299359
/// Registers a pair of cameras (OpenCV 5), estimating the relative pose (R, T) between them.
300360
/// The two cameras may use different camera models (pinhole / fisheye).

src/OpenCvSharp/Cv2/Cv2_core.cs

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,21 @@ public static Scalar Sum(InputArray src)
306306
return ret;
307307
}
308308

309+
/// <summary>
310+
/// Checks whether the array contains at least one non-zero element. Faster than
311+
/// <see cref="CountNonZero"/> when only the presence of non-zero elements matters.
312+
/// </summary>
313+
/// <param name="src">Single-channel array</param>
314+
/// <returns>true if src has at least one non-zero element</returns>
315+
public static bool HasNonZero(InputArray src)
316+
{
317+
NativeMethods.HandleException(
318+
NativeMethods.core_hasNonZero(src.Proxy, out var ret));
319+
320+
GC.KeepAlive(src.Source);
321+
return ret != 0;
322+
}
323+
309324
/// <summary>
310325
/// computes the number of nonzero array elements
311326
/// </summary>
@@ -806,6 +821,37 @@ public static void Flip(InputArray src, OutputArray dst, FlipMode flipCode)
806821
GC.KeepAlive(dst.Source);
807822
}
808823

824+
/// <summary>
825+
/// Flips an n-dimensional array along the given axis.
826+
/// </summary>
827+
/// <param name="src">The source array</param>
828+
/// <param name="dst">The destination array; will have the same size and same type as src</param>
829+
/// <param name="axis">Axis to flip along.</param>
830+
public static void FlipND(InputArray src, OutputArray dst, int axis)
831+
{
832+
NativeMethods.HandleException(
833+
NativeMethods.core_flipND(src.Proxy, dst.Proxy, axis));
834+
835+
GC.KeepAlive(src.Source);
836+
GC.KeepAlive(dst.Source);
837+
}
838+
839+
/// <summary>
840+
/// Broadcasts the given array to the given shape.
841+
/// </summary>
842+
/// <param name="src">input array</param>
843+
/// <param name="shape">target shape. Should be a list of CV_32S numbers. Negative values are not supported.</param>
844+
/// <param name="dst">output array that has the given shape</param>
845+
public static void Broadcast(InputArray src, InputArray shape, OutputArray dst)
846+
{
847+
NativeMethods.HandleException(
848+
NativeMethods.core_broadcast(src.Proxy, shape.Proxy, dst.Proxy));
849+
850+
GC.KeepAlive(src.Source);
851+
GC.KeepAlive(shape.Source);
852+
GC.KeepAlive(dst.Source);
853+
}
854+
809855
/// <summary>
810856
/// Rotates a 2D array in multiples of 90 degrees.
811857
/// </summary>
@@ -1398,6 +1444,20 @@ public static void PatchNaNs(InputOutputArray a, double val = 0)
13981444
GC.KeepAlive(a.Source);
13991445
}
14001446

1447+
/// <summary>
1448+
/// Computes a mask of finite (non-NaN, non-Inf) elements, a companion to <see cref="PatchNaNs"/>.
1449+
/// </summary>
1450+
/// <param name="src">input array.</param>
1451+
/// <param name="mask">output mask array of the same size as src, CV_8U type.</param>
1452+
public static void FiniteMask(InputArray src, OutputArray mask)
1453+
{
1454+
NativeMethods.HandleException(
1455+
NativeMethods.core_finiteMask(src.Proxy, mask.Proxy));
1456+
1457+
GC.KeepAlive(src.Source);
1458+
GC.KeepAlive(mask.Source);
1459+
}
1460+
14011461
/// <summary>
14021462
/// implements generalized matrix product algorithm GEMM from BLAS
14031463
/// </summary>
@@ -1461,7 +1521,24 @@ public static void Transpose(InputArray src, OutputArray dst)
14611521
GC.KeepAlive(src.Source);
14621522
GC.KeepAlive(dst.Source);
14631523
}
1464-
1524+
1525+
/// <summary>
1526+
/// Transposes an n-dimensional array by permuting its axes according to the given order.
1527+
/// </summary>
1528+
/// <param name="src">The source array</param>
1529+
/// <param name="order">Permutation of axes, e.g. { 1, 0, 2 } to swap the first two axes.</param>
1530+
/// <param name="dst">The destination array</param>
1531+
public static void TransposeND(InputArray src, int[] order, OutputArray dst)
1532+
{
1533+
ArgumentNullException.ThrowIfNull(order);
1534+
1535+
NativeMethods.HandleException(
1536+
NativeMethods.core_transposeND(src.Proxy, order, order.Length, dst.Proxy));
1537+
1538+
GC.KeepAlive(src.Source);
1539+
GC.KeepAlive(dst.Source);
1540+
}
1541+
14651542
/// <summary>
14661543
/// performs affine transformation of each element of multi-channel input matrix
14671544
/// </summary>
@@ -2646,6 +2723,61 @@ public static bool UseOptimized()
26462723
return ret != 0;
26472724
}
26482725

2726+
/// <summary>
2727+
/// Returns whether IPP is used for acceleration.
2728+
/// </summary>
2729+
/// <returns></returns>
2730+
public static bool UseIPP()
2731+
{
2732+
NativeMethods.HandleException(
2733+
NativeMethods.core_useIPP(out var ret));
2734+
return ret != 0;
2735+
}
2736+
2737+
/// <summary>
2738+
/// Turns on/off IPP-based acceleration.
2739+
/// </summary>
2740+
/// <param name="flag"></param>
2741+
public static void SetUseIPP(bool flag)
2742+
{
2743+
NativeMethods.HandleException(
2744+
NativeMethods.core_setUseIPP(flag ? 1 : 0));
2745+
}
2746+
2747+
/// <summary>
2748+
/// Returns the current IPP library version.
2749+
/// </summary>
2750+
/// <returns></returns>
2751+
public static string GetIppVersion()
2752+
{
2753+
using var buf = new StdString();
2754+
NativeMethods.HandleException(
2755+
NativeMethods.core_getIppVersion(buf.CvPtr));
2756+
return buf.ToString();
2757+
}
2758+
2759+
/// <summary>
2760+
/// Returns whether IPP is used in "not exact" mode. In this mode IPP may be used even where
2761+
/// it and OpenCV have internal accuracy differences that impact accuracy tests.
2762+
/// </summary>
2763+
/// <returns></returns>
2764+
public static bool UseIppNotExact()
2765+
{
2766+
NativeMethods.HandleException(
2767+
NativeMethods.core_useIPP_NotExact(out var ret));
2768+
return ret != 0;
2769+
}
2770+
2771+
/// <summary>
2772+
/// Turns on/off IPP "not exact" mode.
2773+
/// </summary>
2774+
/// <param name="flag"></param>
2775+
public static void SetUseIppNotExact(bool flag)
2776+
{
2777+
NativeMethods.HandleException(
2778+
NativeMethods.core_setUseIPP_NotExact(flag ? 1 : 0));
2779+
}
2780+
26492781
/// <summary>
26502782
/// Aligns buffer size by the certain number of bytes
26512783
/// This small inline function aligns a buffer size by

src/OpenCvSharp/Cv2/Cv2_imgproc.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,21 @@ public static void Blur(
247247
GC.KeepAlive(dst.Source);
248248
}
249249

250+
/// <summary>
251+
/// Blurs an image using the stackBlur algorithm, a fast approximation of a Gaussian blur.
252+
/// </summary>
253+
/// <param name="src">The source image</param>
254+
/// <param name="dst">The destination image; will have the same size and the same type as src</param>
255+
/// <param name="ksize">The smoothing kernel size (must be positive and odd)</param>
256+
public static void StackBlur(InputArray src, OutputArray dst, Size ksize)
257+
{
258+
NativeMethods.HandleException(
259+
NativeMethods.imgproc_stackBlur(src.Proxy, dst.Proxy, ksize));
260+
261+
GC.KeepAlive(src.Source);
262+
GC.KeepAlive(dst.Source);
263+
}
264+
250265
/// <summary>
251266
/// Convolves an image with the kernel
252267
/// </summary>
@@ -1139,6 +1154,25 @@ public static Point2d PhaseCorrelate(InputArray src1, InputArray src2,
11391154
return ret;
11401155
}
11411156

1157+
/// <summary>
1158+
/// Iterative variant of <see cref="PhaseCorrelate"/> that refines the detected shift over
1159+
/// multiple iterations for improved sub-pixel accuracy.
1160+
/// </summary>
1161+
/// <param name="src1">Source floating point array (CV_32FC1 or CV_64FC1)</param>
1162+
/// <param name="src2">Source floating point array (CV_32FC1 or CV_64FC1)</param>
1163+
/// <param name="l2size">Size of the neighborhood used at each iteration.</param>
1164+
/// <param name="maxIters">Maximum number of iterations.</param>
1165+
/// <returns>detected phase shift(sub-pixel) between the two arrays.</returns>
1166+
public static Point2d PhaseCorrelateIterative(InputArray src1, InputArray src2, int l2size = 7, int maxIters = 10)
1167+
{
1168+
NativeMethods.HandleException(
1169+
NativeMethods.imgproc_phaseCorrelateIterative(src1.Proxy, src2.Proxy, l2size, maxIters, out var ret));
1170+
1171+
GC.KeepAlive(src1.Source);
1172+
GC.KeepAlive(src2.Source);
1173+
return ret;
1174+
}
1175+
11421176
/// <summary>
11431177
/// Computes a Hanning window coefficients in two dimensions.
11441178
/// </summary>
@@ -1172,6 +1206,28 @@ public static double Threshold(InputArray src, OutputArray dst, double thresh, d
11721206
return ret;
11731207
}
11741208

1209+
/// <summary>
1210+
/// Applies a fixed-level threshold to each array element, restricted to the pixels selected by mask.
1211+
/// </summary>
1212+
/// <param name="src">input array (single-channel, 8-bit or 32-bit floating point).</param>
1213+
/// <param name="dst">input/output array of the same size and type as src.</param>
1214+
/// <param name="mask">optional mask; pixels outside the mask keep their original value in dst.</param>
1215+
/// <param name="thresh">threshold value.</param>
1216+
/// <param name="maxval">maximum value to use with the THRESH_BINARY and THRESH_BINARY_INV thresholding types.</param>
1217+
/// <param name="type">thresholding type (see the details below).</param>
1218+
/// <returns>the computed threshold value when type == OTSU</returns>
1219+
public static double ThresholdWithMask(
1220+
InputArray src, InputOutputArray dst, InputArray mask, double thresh, double maxval, ThresholdTypes type)
1221+
{
1222+
NativeMethods.HandleException(
1223+
NativeMethods.imgproc_thresholdWithMask(src.Proxy, dst.Proxy, mask.Proxy, thresh, maxval, (int)type, out var ret));
1224+
1225+
GC.KeepAlive(src.Source);
1226+
GC.KeepAlive(dst.Source);
1227+
GC.KeepAlive(mask.Source);
1228+
return ret;
1229+
}
1230+
11751231
/// <summary>
11761232
/// Applies an adaptive threshold to an array.
11771233
/// </summary>

src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_flann.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@ static partial class NativeMethods
1919
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
2020
public static partial ExceptionStatus flann_Index_delete(IntPtr obj);
2121

22+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
23+
public static partial ExceptionStatus flann_Index_new0(out IntPtr returnValue);
24+
25+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
26+
internal static partial ExceptionStatus flann_Index_build(
27+
OpenCvSafeHandle obj, in InputArrayProxy features, IntPtr @params, int distType);
28+
29+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
30+
internal static partial ExceptionStatus flann_Index_load(
31+
OpenCvSafeHandle obj, in InputArrayProxy features, [MarshalAs(UnmanagedType.LPStr)] string filename, out int returnValue);
32+
33+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
34+
public static partial ExceptionStatus flann_Index_release(OpenCvSafeHandle obj);
35+
36+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
37+
public static partial ExceptionStatus flann_Index_getDistance(OpenCvSafeHandle obj, out int returnValue);
38+
39+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
40+
public static partial ExceptionStatus flann_Index_getAlgorithm(OpenCvSafeHandle obj, out int returnValue);
41+
2242
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
2343
public static partial ExceptionStatus flann_Index_knnSearch1(
2444
OpenCvSafeHandle obj, [In] float[] queries, int queriesLength, [Out] int[] indices, [Out] float[] dists, int knn, IntPtr @params);
@@ -119,6 +139,20 @@ public static partial ExceptionStatus flann_Ptr_KMeansIndexParams_new(
119139

120140
#endregion
121141

142+
#region HierarchicalClusteringIndexParams
143+
144+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
145+
public static partial ExceptionStatus flann_Ptr_HierarchicalClusteringIndexParams_new(
146+
int branching, FlannCentersInit centersInit, int trees, int leafSize, out IntPtr returnValue);
147+
148+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
149+
public static partial ExceptionStatus flann_Ptr_HierarchicalClusteringIndexParams_get(IntPtr ptr, out IntPtr returnValue);
150+
151+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
152+
public static partial ExceptionStatus flann_Ptr_HierarchicalClusteringIndexParams_delete(IntPtr obj);
153+
154+
#endregion
155+
122156
#region LshIndexParams
123157

124158
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
@@ -180,6 +214,9 @@ public static partial ExceptionStatus flann_Ptr_SavedIndexParams_new(
180214
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
181215
public static partial ExceptionStatus flann_Ptr_SearchParams_new(int checks, float eps, int sorted, out IntPtr returnValue);
182216

217+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
218+
public static partial ExceptionStatus flann_Ptr_SearchParams_new2(int checks, float eps, int sorted, int exploreAllTrees, out IntPtr returnValue);
219+
183220
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
184221
public static partial ExceptionStatus flann_Ptr_SearchParams_get(IntPtr ptr, out IntPtr returnValue);
185222

src/OpenCvSharp/Internal/PInvoke/NativeMethods/calib/NativeMethods_calib.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,17 @@ internal static partial ExceptionStatus calib_calibrateCamera_InputArray(
5252
int flags, TermCriteria criteria,
5353
out double returnValue);
5454

55+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
56+
internal static partial ExceptionStatus calib_calibrateCameraRO_InputArray(
57+
IntPtr[] objectPoints, int objectPointsSize,
58+
IntPtr[] imagePoints, int imagePointsSize,
59+
Size imageSize, int iFixedPoint,
60+
in InputOutputArrayProxy cameraMatrix, in InputOutputArrayProxy distCoeffs,
61+
IntPtr rvecs, IntPtr tvecs,
62+
in OutputArrayProxy newObjPoints,
63+
int flags, TermCriteria criteria,
64+
out double returnValue);
65+
5566
// OpenCV 5 multi-view calibration
5667
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
5768
internal static partial ExceptionStatus calib_registerCameras(

0 commit comments

Comments
 (0)