public static extern ExceptionStatus stitching_FeaturesMatcher_apply( IntPtr obj, ref WImageFeatures features1, ref WImageFeatures features2, out int outSrcImgIdx, out int outDstImgIdx, IntPtr outMatches, IntPtr outInliersMask, out int outNumInliers, IntPtr outH, out double outConfidence);
/// <summary> /// Converts std::vector to managed array /// </summary> /// <returns></returns> public ImageFeatures[] ToArray() { var size = Size; if (size == 0) { return(Array.Empty <ImageFeatures>()); } VectorOfKeyPoint[]? keypointsVecs = null; Mat[]? descriptors = null; try { var nativeResult = new WImageFeatures[size]; keypointsVecs = new VectorOfKeyPoint[size]; descriptors = new Mat[size]; for (int i = 0; i < size; i++) { keypointsVecs[i] = new VectorOfKeyPoint(); descriptors[i] = new Mat(); nativeResult[i].Keypoints = keypointsVecs[i].CvPtr; nativeResult[i].Descriptors = descriptors[i].CvPtr; } NativeMethods.vector_ImageFeatures_getElements(ptr, nativeResult); var result = new ImageFeatures[size]; for (int i = 0; i < size; i++) { result[i] = new ImageFeatures( imgIdx: nativeResult[i].ImgIdx, imgSize: nativeResult[i].ImgSize, keypoints: keypointsVecs[i].ToArray(), descriptors: descriptors[i]); } // ElemPtr is IntPtr to memory held by this object, so make sure we are not disposed until finished with copy. GC.KeepAlive(this); return(result); } catch { if (descriptors is not null) { foreach (var mat in descriptors) { mat.Dispose(); } } throw; } finally { #pragma warning disable CA1508 // (???) Avoid dead conditional code if (keypointsVecs is not null) { foreach (var vec in keypointsVecs) { vec.Dispose(); } } #pragma warning restore CA1508 } }