Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="featuresFinder"></param>
        /// <param name="image"></param>
        /// <param name="features"></param>
        /// <param name="mask"></param>
        public static void ComputeImageFeatures(
            Feature2D featuresFinder,
            InputArray image,
            out ImageFeatures features,
            InputArray?mask = null)
        {
            if (featuresFinder == null)
            {
                throw new ArgumentNullException(nameof(featuresFinder));
            }
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            featuresFinder.ThrowIfDisposed();
            image.ThrowIfDisposed();

            var descriptorsMat = new Mat();
            var keypointsVec   = new VectorOfKeyPoint();
            var wImageFeatures = new WImageFeatures
            {
                Keypoints   = keypointsVec.CvPtr,
                Descriptors = descriptorsMat.CvPtr
            };

            unsafe
            {
                NativeMethods.HandleException(
                    NativeMethods.stitching_computeImageFeatures2(
                        featuresFinder.CvPtr, image.CvPtr, &wImageFeatures, mask?.CvPtr ?? IntPtr.Zero));
            }

            features = new ImageFeatures(
                wImageFeatures.ImgIdx,
                wImageFeatures.ImgSize,
                keypointsVec.ToArray(),
                descriptorsMat);

            GC.KeepAlive(featuresFinder);
            GC.KeepAlive(image);
            GC.KeepAlive(mask);
            GC.KeepAlive(descriptorsMat);
        }
Beispiel #2
0
        /// <summary>
        /// Performs images matching.
        /// </summary>
        /// <param name="features1">First image features</param>
        /// <param name="features2">Second image features</param>
        /// <returns>Found matches</returns>
        public virtual MatchesInfo Apply(
            ImageFeatures features1, ImageFeatures features2)
        {
            ThrowIfDisposed();

            if (features1 == null)
            {
                throw new ArgumentNullException(nameof(features1));
            }
            if (features2 == null)
            {
                throw new ArgumentNullException(nameof(features2));
            }
            if (features1.Descriptors == null)
            {
                throw new ArgumentException($"{nameof(features1)}.Descriptors == null", nameof(features1));
            }
            if (features2.Descriptors == null)
            {
                throw new ArgumentException($"{nameof(features2)}.Descriptors == null", nameof(features1));
            }
            features1.Descriptors.ThrowIfDisposed();
            features2.Descriptors.ThrowIfDisposed();

            using var keypointsVec1 = new VectorOfKeyPoint(features1.Keypoints);
            using var keypointsVec2 = new VectorOfKeyPoint(features2.Keypoints);
            var features1Cpp = new WImageFeatures
            {
                ImgIdx      = features1.ImgIdx,
                ImgSize     = features1.ImgSize,
                Keypoints   = keypointsVec1.CvPtr,
                Descriptors = features1.Descriptors.CvPtr,
            };
            var features2Cpp = new WImageFeatures
            {
                ImgIdx      = features2.ImgIdx,
                ImgSize     = features2.ImgSize,
                Keypoints   = keypointsVec2.CvPtr,
                Descriptors = features2.Descriptors.CvPtr,
            };

            using var matchesVec     = new VectorOfDMatch();
            using var inliersMaskVec = new VectorOfByte();
            var h = new Mat();

            NativeMethods.HandleException(
                NativeMethods.stitching_FeaturesMatcher_apply(
                    ptr,
                    ref features1Cpp,
                    ref features2Cpp,
                    out var srcImgIdx,
                    out var dstImgIdx,
                    matchesVec.CvPtr,
                    inliersMaskVec.CvPtr,
                    out var numInliers,
                    h.CvPtr,
                    out var confidence));

            GC.KeepAlive(this);

            return(new MatchesInfo(
                       srcImgIdx, dstImgIdx, matchesVec.ToArray(), inliersMaskVec.ToArray(),
                       numInliers, h, confidence));
        }
Beispiel #3
0
        /// <summary>
        /// Performs images matching.
        /// </summary>
        /// <param name="features">Features of the source images</param>
        /// <param name="mask">Mask indicating which image pairs must be matched</param>
        /// <returns>Found pairwise matches</returns>
        public virtual MatchesInfo[] Apply(
            IEnumerable <ImageFeatures> features, Mat?mask = null)
        {
            if (features == null)
            {
                throw new ArgumentNullException(nameof(features));
            }
            ThrowIfDisposed();

            var featuresArray = features.CastOrToArray();

            if (featuresArray.Length == 0)
            {
                throw new ArgumentException("Empty features array", nameof(features));
            }

            var keypointVecs   = new VectorOfKeyPoint?[featuresArray.Length];
            var wImageFeatures = new WImageFeatures[featuresArray.Length];

            try
            {
                for (int i = 0; i < featuresArray.Length; i++)
                {
                    if (featuresArray[i].Descriptors == null)
                    {
                        throw new ArgumentException("features contain null descriptor mat", nameof(features));
                    }
                    featuresArray[i].Descriptors.ThrowIfDisposed();

                    keypointVecs[i]   = new VectorOfKeyPoint();
                    wImageFeatures[i] = new WImageFeatures
                    {
                        ImgIdx      = featuresArray[i].ImgIdx,
                        ImgSize     = featuresArray[i].ImgSize,
                        Keypoints   = keypointVecs[i] !.CvPtr,
                        Descriptors = featuresArray[i].Descriptors.CvPtr,
                    };
                }

                using var srcImgIndexVecs = new VectorOfInt32();
                using var dstImgIndexVecs = new VectorOfInt32();
                using var matchesVec      = new VectorOfVectorDMatch();
                using var inlinersMaskVec = new VectorOfVectorByte();
                using var numInliersVecs  = new VectorOfInt32();
                using var hVecs           = new VectorOfMat();
                using var confidenceVecs  = new VectorOfDouble();
                NativeMethods.HandleException(
                    NativeMethods.stitching_FeaturesMatcher_apply2(
                        ptr,
                        wImageFeatures, wImageFeatures.Length,
                        mask?.CvPtr ?? IntPtr.Zero,
                        srcImgIndexVecs.CvPtr,
                        dstImgIndexVecs.CvPtr,
                        matchesVec.CvPtr,
                        inlinersMaskVec.CvPtr,
                        numInliersVecs.CvPtr,
                        hVecs.CvPtr,
                        confidenceVecs.CvPtr
                        ));

                var srcImgIndices = srcImgIndexVecs.ToArray();
                var dstImgIndices = dstImgIndexVecs.ToArray();
                var matches       = matchesVec.ToArray();
                var inlinersMasks = inlinersMaskVec.ToArray();
                var numInliers    = numInliersVecs.ToArray();
                var hs            = hVecs.ToArray();
                var confidences   = confidenceVecs.ToArray();
                var result        = new MatchesInfo[srcImgIndices.Length];
                for (int i = 0; i < srcImgIndices.Length; i++)
                {
                    result[i] = new MatchesInfo(
                        srcImgIndices[i],
                        dstImgIndices[i],
                        matches[i],
                        inlinersMasks[i],
                        numInliers[i],
                        hs[i],
                        confidences[i]);
                }
                return(result);
            }
            finally
            {
                foreach (var vec in keypointVecs)
                {
                    vec?.Dispose();
                }
                GC.KeepAlive(this);
            }
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="featuresFinder"></param>
        /// <param name="images"></param>
        /// <param name="features"></param>
        /// <param name="masks"></param>
        public static void ComputeImageFeatures(
            Feature2D featuresFinder,
            IEnumerable <Mat> images,
            out ImageFeatures[] features,
            IEnumerable <Mat>?masks = null)
        {
            if (featuresFinder == null)
            {
                throw new ArgumentNullException(nameof(featuresFinder));
            }
            if (images == null)
            {
                throw new ArgumentNullException(nameof(images));
            }
            featuresFinder.ThrowIfDisposed();

            var imagesArray = images as Mat[] ?? images.ToArray();

            if (imagesArray.Length == 0)
            {
                throw new ArgumentException("Empty array", nameof(images));
            }

            var descriptorsMat = new Mat[imagesArray.Length];
            var keypointsVec   = new VectorOfKeyPoint[imagesArray.Length];
            var wImageFeatures = new WImageFeatures[imagesArray.Length];

            for (int i = 0; i < imagesArray.Length; i++)
            {
                descriptorsMat[i] = new Mat();
                keypointsVec[i]   = new VectorOfKeyPoint();
                wImageFeatures[i] = new WImageFeatures
                {
                    Keypoints   = keypointsVec[i].CvPtr,
                    Descriptors = descriptorsMat[i].CvPtr
                };
            }

            var imagesPointers = imagesArray.Select(i => i.CvPtr).ToArray();
            var masksPointers  = masks?.Select(i => i.CvPtr).ToArray();

            if (masksPointers != null && imagesPointers.Length != masksPointers.Length)
            {
                throw new ArgumentException("size of images != size of masks");
            }

            var wImageFeaturesPointers = new GCHandle[wImageFeatures.Length];

            try
            {
                for (int i = 0; i < wImageFeatures.Length; i++)
                {
                    wImageFeaturesPointers[i] = GCHandle.Alloc(wImageFeatures[i], GCHandleType.Pinned);
                }

                if (masksPointers == null)
                {
                    NativeMethods.HandleException(
                        NativeMethods.stitching_computeImageFeatures1_2(
                            featuresFinder.CvPtr,
                            imagesPointers,
                            imagesPointers.Length,
                            wImageFeaturesPointers.Select(gch => gch.AddrOfPinnedObject()).ToArray(),
                            IntPtr.Zero));
                }
                else
                {
                    NativeMethods.HandleException(
                        NativeMethods.stitching_computeImageFeatures1_1(
                            featuresFinder.CvPtr,
                            imagesPointers,
                            imagesPointers.Length,
                            wImageFeaturesPointers.Select(gch => gch.AddrOfPinnedObject()).ToArray(),
                            masksPointers));
                }
            }
            finally
            {
                for (int i = 0; i < wImageFeaturesPointers.Length; i++)
                {
                    wImageFeaturesPointers[i].Free();
                }
            }

            features = new ImageFeatures[wImageFeatures.Length];
            for (int i = 0; i < wImageFeaturesPointers.Length; i++)
            {
                features[i] = new ImageFeatures(
                    wImageFeatures[i].ImgIdx,
                    wImageFeatures[i].ImgSize,
                    keypointsVec[i].ToArray(),
                    descriptorsMat[i]);
            }

            GC.KeepAlive(featuresFinder);
            GC.KeepAlive(images);
            GC.KeepAlive(masks);
            GC.KeepAlive(descriptorsMat);
            GC.KeepAlive(imagesPointers);
        }