예제 #1
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);
        }