/// <summary> /// Draws the found matches of keypoints from two images. /// </summary> /// <param name="img1">First source image.</param> /// <param name="keypoints1">Keypoints from the first source image.</param> /// <param name="img2">Second source image.</param> /// <param name="keypoints2">Keypoints from the second source image.</param> /// <param name="matches1To2">Matches from the first image to the second one, which means that keypoints1[i] /// has a corresponding point in keypoints2[matches[i]] .</param> /// <param name="outImg">Output image. Its content depends on the flags value defining what is drawn in the /// output image. See possible flags bit values below.</param> /// <param name="matchColor">Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1), /// the color is generated randomly.</param> /// <param name="singlePointColor">Color of single keypoints (circles), which means that keypoints do not /// have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly.</param> /// <param name="matchesMask">Mask determining which matches are drawn. If the mask is empty, all matches are drawn.</param> /// <param name="flags">Flags setting drawing features. Possible flags bit values are defined by DrawMatchesFlags.</param> public static void DrawMatches( Mat img1, IEnumerable <KeyPoint> keypoints1, Mat img2, IEnumerable <KeyPoint> keypoints2, IEnumerable <DMatch> matches1To2, Mat outImg, Scalar?matchColor = null, Scalar?singlePointColor = null, IEnumerable <byte>?matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) { throw new ArgumentNullException(nameof(img1)); } if (img2 == null) { throw new ArgumentNullException(nameof(img2)); } if (outImg == null) { throw new ArgumentNullException(nameof(outImg)); } if (keypoints1 == null) { throw new ArgumentNullException(nameof(keypoints1)); } if (keypoints2 == null) { throw new ArgumentNullException(nameof(keypoints2)); } if (matches1To2 == null) { throw new ArgumentNullException(nameof(matches1To2)); } img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); var keypoints1Array = keypoints1 as KeyPoint[] ?? keypoints1.ToArray(); var keypoints2Array = keypoints2 as KeyPoint[] ?? keypoints2.ToArray(); var matches1To2Array = matches1To2 as DMatch[] ?? matches1To2.ToArray(); var matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); var singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); var matchesMaskArray = matchesMask as byte[] ?? matchesMask?.ToArray(); var matchesMaskLength = matchesMaskArray?.Length ?? 0; NativeMethods.HandleException( NativeMethods.features2d_drawMatches( img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Array, matches1To2Array.Length, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskArray, matchesMaskLength, (int)flags)); GC.KeepAlive(img1); GC.KeepAlive(img2); GC.KeepAlive(outImg); }
/// <summary> /// Draw keypoints. /// </summary> /// <param name="image">Source image.</param> /// <param name="keypoints">Keypoints from the source image.</param> /// <param name="outImage">Output image. Its content depends on the flags value defining what is drawn in the output image. See possible flags bit values below.</param> /// <param name="color">Color of keypoints.</param> /// <param name="flags">Flags setting drawing features. Possible flags bit values are defined by DrawMatchesFlags.</param> public static void DrawKeypoints( InputArray image, IEnumerable <KeyPoint> keypoints, InputOutputArray outImage, Scalar?color = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (image == null) { throw new ArgumentNullException(nameof(image)); } if (outImage == null) { throw new ArgumentNullException(nameof(outImage)); } if (keypoints == null) { throw new ArgumentNullException(nameof(keypoints)); } image.ThrowIfDisposed(); outImage.ThrowIfDisposed(); var keypointsArray = keypoints as KeyPoint[] ?? keypoints.ToArray(); var color0 = color.GetValueOrDefault(Scalar.All(-1)); NativeMethods.HandleException( NativeMethods.features2d_drawKeypoints(image.CvPtr, keypointsArray, keypointsArray.Length, outImage.CvPtr, color0, (int)flags)); GC.KeepAlive(image); GC.KeepAlive(outImage); }
internal static extern void cv_features2d_drawMatches( Arr img1, KeyPointCollection keypoints1, Arr img2, KeyPointCollection keypoints2, DMatchCollection matches1to2, Arr outImg, Scalar matchColor, Scalar singlePointColor, ByteCollection matchesMask, DrawMatchesFlags flags);
/// <summary> /// Draws matches of keypoints from two images on output image. /// </summary> /// <param name="img1"></param> /// <param name="keypoints1"></param> /// <param name="img2"></param> /// <param name="keypoints2"></param> /// <param name="matches1To2"></param> /// <param name="outImg"></param> /// <param name="matchColor"></param> /// <param name="singlePointColor"></param> /// <param name="matchesMask"></param> /// <param name="flags"></param> public static void DrawMatches(Mat img1, IEnumerable <KeyPoint> keypoints1, Mat img2, IEnumerable <KeyPoint> keypoints2, IEnumerable <DMatch> matches1To2, Mat outImg, Scalar?matchColor = null, Scalar?singlePointColor = null, IEnumerable <byte> matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) { throw new ArgumentNullException(nameof(img1)); } if (img2 == null) { throw new ArgumentNullException(nameof(img2)); } if (outImg == null) { throw new ArgumentNullException(nameof(outImg)); } if (keypoints1 == null) { throw new ArgumentNullException(nameof(keypoints1)); } if (keypoints2 == null) { throw new ArgumentNullException(nameof(keypoints2)); } if (matches1To2 == null) { throw new ArgumentNullException(nameof(matches1To2)); } img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); KeyPoint[] keypoints1Array = EnumerableEx.ToArray(keypoints1); KeyPoint[] keypoints2Array = EnumerableEx.ToArray(keypoints2); DMatch[] matches1To2Array = EnumerableEx.ToArray(matches1To2); Scalar matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); Scalar singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); byte[] matchesMaskArray = null; int matchesMaskLength = 0; if (matchesMask != null) { matchesMaskArray = EnumerableEx.ToArray(matchesMask); matchesMaskLength = matchesMaskArray.Length; } NativeMethods.features2d_drawMatches1(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Array, matches1To2Array.Length, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskArray, matchesMaskLength, (int)flags); GC.KeepAlive(img1); GC.KeepAlive(img2); GC.KeepAlive(outImg); }
/// <summary> /// Draw keypoint matches from two images on the output image. /// </summary> /// <param name="image1">The first image.</param> /// <param name="keyPoints1">The collection of keypoints from the first image.</param> /// <param name="image2">The second image.</param> /// <param name="keyPoints2">The collection of keypoints from the second image.</param> /// <param name="matches">The matches from the first image to the second image.</param> /// <param name="outImage">The image where the keypoint matches are to be drawn.</param> /// <param name="matchColor">The color used for drawing successful matches.</param> /// <param name="singlePointColor">The color used for drawing unmatched keypoints.</param> /// <param name="matchesMask">The optional mask specifying which matches are drawn.</param> /// <param name="flags">Optional operation flags specifying how the matches are to be drawn.</param> public static void DrawMatches( Arr image1, KeyPointCollection keyPoints1, Arr image2, KeyPointCollection keyPoints2, DMatchCollection matches, Arr outImage, Scalar matchColor, Scalar singlePointColor, ByteCollection matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.None) { NativeMethods.cv_features2d_drawMatches( image1, keyPoints1, image2, keyPoints2, matches, outImage, matchColor, singlePointColor, matchesMask ?? ByteCollection.Null, flags); }
/// <summary> /// Draw keypoints. /// </summary> /// <param name="image"></param> /// <param name="keypoints"></param> /// <param name="outImage"></param> /// <param name="color"></param> /// <param name="flags"></param> public static void DrawKeypoints(Mat image, IEnumerable<KeyPoint> keypoints, Mat outImage, Scalar? color = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (image == null) throw new ArgumentNullException("image"); if (outImage == null) throw new ArgumentNullException("outImage"); if (keypoints == null) throw new ArgumentNullException("keypoints"); image.ThrowIfDisposed(); outImage.ThrowIfDisposed(); KeyPoint[] keypointsArray = EnumerableEx.ToArray(keypoints); Scalar color0 = color.GetValueOrDefault(Scalar.All(-1)); NativeMethods.features2d_drawKeypoints(image.CvPtr, keypointsArray, keypointsArray.Length, outImage.CvPtr, color0, (int)flags); }
/// <summary> /// Draw keypoints. /// </summary> /// <param name="image"></param> /// <param name="keypoints"></param> /// <param name="outImage"></param> /// <param name="color"></param> /// <param name="flags"></param> public static void DrawKeypoints(Mat image, IEnumerable <KeyPoint> keypoints, Mat outImage, Scalar?color = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (image == null) { throw new ArgumentNullException("image"); } if (outImage == null) { throw new ArgumentNullException("outImage"); } if (keypoints == null) { throw new ArgumentNullException("keypoints"); } image.ThrowIfDisposed(); outImage.ThrowIfDisposed(); KeyPoint[] keypointsArray = EnumerableEx.ToArray(keypoints); Scalar color0 = color.GetValueOrDefault(Scalar.All(-1)); NativeMethods.features2d_drawKeypoints(image.CvPtr, keypointsArray, keypointsArray.Length, outImage.CvPtr, color0, (int)flags); }
/// <summary> /// Draws matches of keypints from two images on output image. /// </summary> /// <param name="img1"></param> /// <param name="keypoints1"></param> /// <param name="img2"></param> /// <param name="keypoints2"></param> /// <param name="matches1To2"></param> /// <param name="outImg"></param> /// <param name="matchColor"></param> /// <param name="singlePointColor"></param> /// <param name="matchesMask"></param> /// <param name="flags"></param> public static void DrawMatches(Mat img1, IEnumerable<KeyPoint> keypoints1, Mat img2, IEnumerable<KeyPoint> keypoints2, IEnumerable<IEnumerable<DMatch>> matches1To2, Mat outImg, Scalar? matchColor = null, Scalar? singlePointColor = null, IEnumerable<IEnumerable<byte>> matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) throw new ArgumentNullException(nameof(img1)); if (img2 == null) throw new ArgumentNullException(nameof(img2)); if (outImg == null) throw new ArgumentNullException(nameof(outImg)); if (keypoints1 == null) throw new ArgumentNullException(nameof(keypoints1)); if (keypoints2 == null) throw new ArgumentNullException(nameof(keypoints2)); if (matches1To2 == null) throw new ArgumentNullException(nameof(matches1To2)); img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); KeyPoint[] keypoints1Array = EnumerableEx.ToArray(keypoints1); KeyPoint[] keypoints2Array = EnumerableEx.ToArray(keypoints2); DMatch[][] matches1To2Array = EnumerableEx.SelectToArray(matches1To2, EnumerableEx.ToArray); int matches1To2Size1 = matches1To2Array.Length; int[] matches1To2Size2 = EnumerableEx.SelectToArray(matches1To2Array, dm => dm.Length); Scalar matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); Scalar singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); using (var matches1To2Ptr = new ArrayAddress2<DMatch>(matches1To2Array)) { if (matchesMask == null) { NativeMethods.features2d_drawMatches2(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, null, 0, null, (int)flags); } else { byte[][] matchesMaskArray = EnumerableEx.SelectToArray(matchesMask, EnumerableEx.ToArray); int matchesMaskSize1 = matches1To2Array.Length; int[] matchesMaskSize2 = EnumerableEx.SelectToArray(matchesMaskArray, dm => dm.Length); using (var matchesMaskPtr = new ArrayAddress2<byte>(matchesMaskArray)) { NativeMethods.features2d_drawMatches2(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr.Pointer, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskPtr, matchesMaskSize1, matchesMaskSize2, (int)flags); } } } }
/// <summary> /// Draws matches of keypints from two images on output image. /// </summary> /// <param name="img1"></param> /// <param name="keypoints1"></param> /// <param name="img2"></param> /// <param name="keypoints2"></param> /// <param name="matches1To2"></param> /// <param name="outImg"></param> /// <param name="matchColor"></param> /// <param name="singlePointColor"></param> /// <param name="matchesMask"></param> /// <param name="flags"></param> public static void DrawMatches(Mat img1, IEnumerable<KeyPoint> keypoints1, Mat img2, IEnumerable<KeyPoint> keypoints2, IEnumerable<DMatch> matches1To2, Mat outImg, Scalar? matchColor = null, Scalar? singlePointColor = null, IEnumerable<byte> matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) throw new ArgumentNullException(nameof(img1)); if (img2 == null) throw new ArgumentNullException(nameof(img2)); if (outImg == null) throw new ArgumentNullException(nameof(outImg)); if (keypoints1 == null) throw new ArgumentNullException(nameof(keypoints1)); if (keypoints2 == null) throw new ArgumentNullException(nameof(keypoints2)); if (matches1To2 == null) throw new ArgumentNullException(nameof(matches1To2)); img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); KeyPoint[] keypoints1Array = EnumerableEx.ToArray(keypoints1); KeyPoint[] keypoints2Array = EnumerableEx.ToArray(keypoints2); DMatch[] matches1To2Array = EnumerableEx.ToArray(matches1To2); Scalar matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); Scalar singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); byte[] matchesMaskArray = null; int matchesMaskLength = 0; if (matchesMask != null) { matchesMaskArray = EnumerableEx.ToArray(matchesMask); matchesMaskLength = matchesMaskArray.Length; } NativeMethods.features2d_drawMatches1(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Array, matches1To2Array.Length, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskArray, matchesMaskLength, (int)flags); }
/// <summary> /// Draws the found matches of keypoints from two images. /// </summary> /// <param name="img1">First source image.</param> /// <param name="keypoints1">Keypoints from the first source image.</param> /// <param name="img2">Second source image.</param> /// <param name="keypoints2">Keypoints from the second source image.</param> /// <param name="matches1To2">Matches from the first image to the second one, which means that keypoints1[i] /// has a corresponding point in keypoints2[matches[i]] .</param> /// <param name="outImg">Output image. Its content depends on the flags value defining what is drawn in the /// output image. See possible flags bit values below.</param> /// <param name="matchColor">Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1), /// the color is generated randomly.</param> /// <param name="singlePointColor">Color of single keypoints (circles), which means that keypoints do not /// have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly.</param> /// <param name="matchesMask">Mask determining which matches are drawn. If the mask is empty, all matches are drawn.</param> /// <param name="flags">Flags setting drawing features. Possible flags bit values are defined by DrawMatchesFlags.</param> public static void DrawMatchesKnn( Mat img1, IEnumerable <KeyPoint> keypoints1, Mat img2, IEnumerable <KeyPoint> keypoints2, IEnumerable <IEnumerable <DMatch> > matches1To2, Mat outImg, Scalar?matchColor = null, Scalar?singlePointColor = null, IEnumerable <IEnumerable <byte> >?matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) { throw new ArgumentNullException(nameof(img1)); } if (img2 == null) { throw new ArgumentNullException(nameof(img2)); } if (outImg == null) { throw new ArgumentNullException(nameof(outImg)); } if (keypoints1 == null) { throw new ArgumentNullException(nameof(keypoints1)); } if (keypoints2 == null) { throw new ArgumentNullException(nameof(keypoints2)); } if (matches1To2 == null) { throw new ArgumentNullException(nameof(matches1To2)); } img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); var keypoints1Array = keypoints1 as KeyPoint[] ?? keypoints1.ToArray(); var keypoints2Array = keypoints2 as KeyPoint[] ?? keypoints2.ToArray(); var matches1To2Array = matches1To2.Select(m => m.ToArray()).ToArray(); var matches1To2Size1 = matches1To2Array.Length; var matches1To2Size2 = matches1To2Array.Select(dm => dm.Length).ToArray(); var matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); var singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); using var matches1To2Ptr = new ArrayAddress2 <DMatch>(matches1To2Array); if (matchesMask == null) { NativeMethods.HandleException( NativeMethods.features2d_drawMatchesKnn( img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, null, 0, null, (int)flags)); } else { var matchesMaskArray = matchesMask.Select(m => m.ToArray()).ToArray(); var matchesMaskSize1 = matches1To2Array.Length; var matchesMaskSize2 = matchesMaskArray.Select(dm => dm.Length).ToArray(); using var matchesMaskPtr = new ArrayAddress2 <byte>(matchesMaskArray); NativeMethods.HandleException( NativeMethods.features2d_drawMatchesKnn( img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr.Pointer, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskPtr, matchesMaskSize1, matchesMaskSize2, (int)flags)); } GC.KeepAlive(img1); GC.KeepAlive(img2); GC.KeepAlive(outImg); }
/// <summary> /// Draws matches of keypints from two images on output image. /// </summary> /// <param name="img1"></param> /// <param name="keypoints1"></param> /// <param name="img2"></param> /// <param name="keypoints2"></param> /// <param name="matches1To2"></param> /// <param name="outImg"></param> /// <param name="matchColor"></param> /// <param name="singlePointColor"></param> /// <param name="matchesMask"></param> /// <param name="flags"></param> public static void DrawMatches(Mat img1, IEnumerable <KeyPoint> keypoints1, Mat img2, IEnumerable <KeyPoint> keypoints2, IEnumerable <IEnumerable <DMatch> > matches1To2, Mat outImg, Scalar?matchColor = null, Scalar?singlePointColor = null, IEnumerable <IEnumerable <byte> > matchesMask = null, DrawMatchesFlags flags = DrawMatchesFlags.Default) { if (img1 == null) { throw new ArgumentNullException("img1"); } if (img2 == null) { throw new ArgumentNullException("img2"); } if (outImg == null) { throw new ArgumentNullException("outImg"); } if (keypoints1 == null) { throw new ArgumentNullException("keypoints1"); } if (keypoints2 == null) { throw new ArgumentNullException("keypoints2"); } if (matches1To2 == null) { throw new ArgumentNullException("matches1To2"); } img1.ThrowIfDisposed(); img2.ThrowIfDisposed(); outImg.ThrowIfDisposed(); KeyPoint[] keypoints1Array = EnumerableEx.ToArray(keypoints1); KeyPoint[] keypoints2Array = EnumerableEx.ToArray(keypoints2); DMatch[][] matches1To2Array = EnumerableEx.SelectToArray(matches1To2, EnumerableEx.ToArray); int matches1To2Size1 = matches1To2Array.Length; int[] matches1To2Size2 = EnumerableEx.SelectToArray(matches1To2Array, dm => dm.Length); Scalar matchColor0 = matchColor.GetValueOrDefault(Scalar.All(-1)); Scalar singlePointColor0 = singlePointColor.GetValueOrDefault(Scalar.All(-1)); using (var matches1To2Ptr = new ArrayAddress2 <DMatch>(matches1To2Array)) { if (matchesMask == null) { NativeMethods.features2d_drawMatches2(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, null, 0, null, (int)flags); } else { byte[][] matchesMaskArray = EnumerableEx.SelectToArray(matchesMask, EnumerableEx.ToArray); int matchesMaskSize1 = matches1To2Array.Length; int[] matchesMaskSize2 = EnumerableEx.SelectToArray(matchesMaskArray, dm => dm.Length); using (var matchesMaskPtr = new ArrayAddress2 <byte>(matchesMaskArray)) { NativeMethods.features2d_drawMatches2(img1.CvPtr, keypoints1Array, keypoints1Array.Length, img2.CvPtr, keypoints2Array, keypoints2Array.Length, matches1To2Ptr.Pointer, matches1To2Size1, matches1To2Size2, outImg.CvPtr, matchColor0, singlePointColor0, matchesMaskPtr, matchesMaskSize1, matchesMaskSize2, (int)flags); } } } }
/// <summary> /// Draws a visual representation of detected keypoints in an image. /// </summary> /// <param name="image">The image on which the keypoints were detected.</param> /// <param name="keyPoints">The collection of keypoints to draw.</param> /// <param name="output">The image where the keypoints are to be drawn.</param> /// <param name="color">The color of the keypoints.</param> /// <param name="flags">Optional operation flags specifying how the keypoints are to be drawn.</param> public static void DrawKeypoints(Arr image, KeyPointCollection keyPoints, Arr output, Scalar color, DrawMatchesFlags flags = DrawMatchesFlags.None) { NativeMethods.cv_features2d_drawKeypoints(image, keyPoints, output, color, flags); }
internal static extern void cv_features2d_drawKeypoints(Arr image, KeyPointCollection keypoints, Arr output, Scalar color, DrawMatchesFlags flags);