Beispiel #1
0
        /// <summary>
        /// Basic marker detection
        /// </summary>
        /// <param name="image">input image</param>
        /// <param name="dictionary">indicates the type of markers that will be searched</param>
        /// <param name="corners">vector of detected marker corners.
        /// For each marker, its four corners are provided. For N detected markers,
        ///  the dimensions of this array is Nx4.The order of the corners is clockwise.</param>
        /// <param name="ids">vector of identifiers of the detected markers. The identifier is of type int.
        /// For N detected markers, the size of ids is also N. The identifiers have the same order than the markers in the imgPoints array.</param>
        /// <param name="parameters">marker detection parameters</param>
        /// <param name="rejectedImgPoints">contains the imgPoints of those squares whose inner code has not a
        /// correct codification.Useful for debugging purposes.</param>
        public static void DetectMarkers(InputArray image, Dictionary dictionary, out Point2f[][] corners, out int[] ids, DetectorParameters parameters, out Point2f[][] rejectedImgPoints)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (dictionary.ObjectPtr == null)
            {
                throw new ArgumentException($"{nameof(dictionary)} is disposed", nameof(dictionary));
            }
            if (parameters.ObjectPtr == null)
            {
                throw new ArgumentException($"{nameof(parameters)} is disposed", nameof(parameters));
            }

            using (var cornersVec = new VectorOfVectorPoint2f())
                using (var idsVec = new VectorOfInt32())
                    using (var rejectedImgPointsVec = new VectorOfVectorPoint2f())
                    {
                        NativeMethods.aruco_detectMarkers(
                            image.CvPtr, dictionary.ObjectPtr.CvPtr, cornersVec.CvPtr, idsVec.CvPtr, parameters.ObjectPtr.CvPtr, rejectedImgPointsVec.CvPtr);

                        corners           = cornersVec.ToArray();
                        ids               = idsVec.ToArray();
                        rejectedImgPoints = rejectedImgPointsVec.ToArray();
                    }

            GC.KeepAlive(image);
            GC.KeepAlive(dictionary);
            GC.KeepAlive(parameters);
        }
Beispiel #2
0
        /// <summary>
        /// Performs non maximum suppression given boxes and corresponding scores.
        /// </summary>
        /// <param name="bboxes">a set of bounding boxes to apply NMS.</param>
        /// <param name="scores">a set of corresponding confidences.</param>
        /// <param name="scoreThreshold">a threshold used to filter boxes by score.</param>
        /// <param name="nmsThreshold">a threshold used in non maximum suppression.</param>
        /// <param name="indices">the kept indices of bboxes after NMS.</param>
        /// <param name="eta">a coefficient in adaptive threshold formula</param>
        /// <param name="topK">if `&gt;0`, keep at most @p top_k picked indices.</param>
        // ReSharper disable once IdentifierTypo
        public static void NMSBoxes(IEnumerable <RotatedRect> bboxes, IEnumerable <float> scores,
                                    float scoreThreshold, float nmsThreshold,
                                    out int[] indices,
                                    float eta = 1.0f, int topK = 0)
        {
            if (bboxes == null)
            {
                throw new ArgumentNullException(nameof(bboxes));
            }
            if (scores == null)
            {
                throw new ArgumentNullException(nameof(scores));
            }

            // ReSharper disable once IdentifierTypo
            using (var bboxesVec = new VectorOfRotatedRect(bboxes))
                using (var scoresVec = new VectorOfFloat(scores))
                    using (var indicesVec = new VectorOfInt32())
                    {
                        NativeMethods.dnn_NMSBoxes_RotatedRect(
                            bboxesVec.CvPtr, scoresVec.CvPtr, scoreThreshold, nmsThreshold,
                            indicesVec.CvPtr, eta, topK);
                        indices = indicesVec.ToArray();
                    }
        }
Beispiel #3
0
        /// <summary>
        /// Detect ChArUco Diamond markers.
        /// </summary>
        /// <param name="image">input image necessary for corner subpixel.</param>
        /// <param name="markerCorners">list of detected marker corners from detectMarkers function.</param>
        /// <param name="markerIds">list of marker ids in markerCorners.</param>
        /// <param name="squareMarkerLengthRate">rate between square and marker length: squareMarkerLengthRate = squareLength/markerLength. The real units are not necessary.</param>
        /// <param name="diamondCorners">output list of detected diamond corners (4 corners per diamond). The order is the same than in marker corners: top left, top right, bottom right and bottom left. Similar format than the corners returned by detectMarkers (e.g std::vector&lt;std::vector&lt;cv::Point2f&gt;&gt;).</param>
        /// <param name="diamondIds">ids of the diamonds in diamondCorners. The id of each diamond is in fact of type Vec4i, so each diamond has 4 ids, which are the ids of the aruco markers composing the diamond.</param>
        /// <param name="cameraMatrix">Optional camera calibration matrix.</param>
        /// <param name="distCoeffs">Optional camera distortion coefficients.</param>
        public static void DetectCharucoDiamond(InputArray image, Point2f[][] markerCorners, IEnumerable <int> markerIds,
                                                float squareMarkerLengthRate, out Point2f[][] diamondCorners, out Vec4i[] diamondIds,
                                                InputArray?cameraMatrix = null, InputArray?distCoeffs = null)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (markerCorners == null)
            {
                throw new ArgumentNullException(nameof(markerCorners));
            }
            if (markerIds == null)
            {
                throw new ArgumentNullException(nameof(markerIds));
            }

            if (cameraMatrix == null && distCoeffs != null)
            {
                throw new ArgumentNullException(nameof(cameraMatrix));
            }
            if (cameraMatrix != null && distCoeffs == null)
            {
                throw new ArgumentNullException(nameof(distCoeffs));
            }

            image.ThrowIfDisposed();

            cameraMatrix?.ThrowIfDisposed();
            distCoeffs?.ThrowIfDisposed();

            using var markerCornersAddress = new ArrayAddress2 <Point2f>(markerCorners);
            using var markerIdsVec         = new VectorOfInt32(markerIds);

            using var diamondCornersVec = new VectorOfVectorPoint2f();
            using var diamondIdsVec     = new VectorOfVec4i();

            NativeMethods.HandleException(
                NativeMethods.aruco_detectCharucoDiamond(
                    image.CvPtr, markerCornersAddress.GetPointer(), markerCornersAddress.GetDim1Length(), markerCornersAddress.GetDim2Lengths(),
                    markerIdsVec.CvPtr, squareMarkerLengthRate,
                    diamondCornersVec.CvPtr, diamondIdsVec.CvPtr,
                    cameraMatrix?.CvPtr ?? IntPtr.Zero, distCoeffs?.CvPtr ?? IntPtr.Zero));

            diamondCorners = diamondCornersVec.ToArray();
            diamondIds     = diamondIdsVec.ToArray();

            GC.KeepAlive(image);
            if (cameraMatrix != null)
            {
                GC.KeepAlive(cameraMatrix);
            }
            if (distCoeffs != null)
            {
                GC.KeepAlive(distCoeffs);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Returns indexes of layers with unconnected outputs.
        /// </summary>
        /// <returns></returns>
        public int[] GetUnconnectedOutLayers()
        {
            ThrowIfDisposed();

            using var resultVec = new VectorOfInt32();
            NativeMethods.HandleException(
                NativeMethods.dnn_Net_getUnconnectedOutLayers(ptr, resultVec.CvPtr));
            GC.KeepAlive(this);
            return(resultVec.ToArray());
        }
Beispiel #5
0
        /// <summary>
        /// Returns all the bitsets for categorical splits.
        /// Split::subsetOfs is an offset in the returned vector
        /// </summary>
        /// <returns></returns>
        public int[] GetSubsets()
        {
            if (ptr == IntPtr.Zero)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            using var vector = new VectorOfInt32();
            NativeMethods.HandleException(
                NativeMethods.ml_DTrees_getSubsets(ptr, vector.CvPtr));
            GC.KeepAlive(this);
            return(vector.ToArray());
        }
 /// <summary>
 /// Gets vector of labels by string.
 /// The function searches for the labels containing the specified sub-string in the associated string info.
 /// </summary>
 /// <param name="str"></param>
 /// <returns></returns>
 public int[] GetLabelsByString(string str)
 {
     ThrowIfDisposed();
     if (str == null)
     {
         throw new ArgumentNullException(nameof(str));
     }
     using (var resultVector = new VectorOfInt32())
     {
         NativeMethods.face_FaceRecognizer_getLabelsByString(ptr, str, resultVector.CvPtr);
         return(resultVector.ToArray());
     }
 }
Beispiel #7
0
        /// <summary>
        /// Returns indices of root nodes
        /// </summary>
        /// <returns></returns>
        public int[] GetRoots()
        {
            if (ptr == IntPtr.Zero)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            using (var vector = new VectorOfInt32())
            {
                NativeMethods.ml_DTrees_getRoots(ptr, vector.CvPtr);
                return(vector.ToArray());
            }
        }
Beispiel #8
0
        /// <summary>
        /// Returns indexes of layers with unconnected outputs.
        /// </summary>
        /// <returns></returns>
        public int[] GetUnconnectedOutLayers()
        {
            ThrowIfDisposed();

            try
            {
                using (var resultVec = new VectorOfInt32())
                {
                    NativeMethods.dnn_Net_getUnconnectedOutLayers(ptr, resultVec.CvPtr);
                    return(resultVec.ToArray());
                }
            }
            finally
            {
                GC.KeepAlive(this);
            }
        }
Beispiel #9
0
        /// <summary>
        /// select the 512 "best description pairs"
        /// </summary>
        /// <param name="images">grayscale images set</param>
        /// <param name="keypoints">set of detected keypoints</param>
        /// <param name="corrThresh">correlation threshold</param>
        /// <param name="verbose">print construction information</param>
        /// <returns>list of best pair indexes</returns>
        public int[] SelectPairs(IEnumerable<Mat> images, out KeyPoint[][] keypoints,
            double corrThresh = 0.7, bool verbose = true)
        {
            if (images == null)
                throw new ArgumentNullException("images");

            IntPtr[] imagesPtrs = EnumerableEx.SelectPtrs(images);

            using (var outVec = new VectorOfInt32())
            using (var keypointsVec = new VectorOfVectorKeyPoint())
            {
                NativeMethods.features2d_FREAK_selectPairs(ptr, imagesPtrs, imagesPtrs.Length,
                    keypointsVec.CvPtr, corrThresh, verbose ? 1 : 0, outVec.CvPtr);
                keypoints = keypointsVec.ToArray();
                return outVec.ToArray();
            }
        }
Beispiel #10
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 #11
0
        /// <summary>
        /// computes the camera pose from a few 3D points and the corresponding projections. The outliers are possible.
        /// </summary>
        /// <param name="objectPoints">Array of object points in the object coordinate space, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel, 
        /// where N is the number of points. List&lt;Point3f&gt; can be also passed here.</param>
        /// <param name="imagePoints">Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, where N is the number of points. 
        /// List&lt;Point2f&gt; can be also passed here.</param>
        /// <param name="cameraMatrix">Input 3x3 camera matrix</param>
        /// <param name="distCoeffs">Input vector of distortion coefficients (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]]) of 4, 5, or 8 elements. 
        /// If the vector is null, the zero distortion coefficients are assumed.</param>
        /// <param name="rvec">Output rotation vector that, together with tvec , brings points from the model coordinate system 
        /// to the camera coordinate system.</param>
        /// <param name="tvec">Output translation vector.</param>
        /// <param name="useExtrinsicGuess">If true, the function uses the provided rvec and tvec values as initial approximations 
        /// of the rotation and translation vectors, respectively, and further optimizes them.</param>
        /// <param name="iterationsCount">Number of iterations.</param>
        /// <param name="reprojectionError">Inlier threshold value used by the RANSAC procedure. 
        /// The parameter value is the maximum allowed distance between the observed and computed point projections to consider it an inlier.</param>
        /// <param name="minInliersCount">Number of inliers. If the algorithm at some stage finds more inliers than minInliersCount , it finishes.</param>
        /// <param name="inliers">Output vector that contains indices of inliers in objectPoints and imagePoints .</param>
        /// <param name="flags">Method for solving a PnP problem</param>
        public static void SolvePnPRansac(
            IEnumerable<Point3f> objectPoints,
            IEnumerable<Point2f> imagePoints,
            double[,] cameraMatrix,
            IEnumerable<double> distCoeffs,
            out double[] rvec, out double[] tvec,
            out int[] inliers,
            bool useExtrinsicGuess = false,
            int iterationsCount = 100,
            float reprojectionError = 8.0f,
            int minInliersCount = 100,
            SolvePnPFlag flags = SolvePnPFlag.Iterative)
        {
            if (objectPoints == null)
                throw new ArgumentNullException("objectPoints");
            if (imagePoints == null)
                throw new ArgumentNullException("imagePoints");
            if (cameraMatrix == null)
                throw new ArgumentNullException("cameraMatrix");

            if (cameraMatrix.GetLength(0) != 3 || cameraMatrix.GetLength(1) != 3)
                throw new ArgumentException("");

            Point3f[] objectPointsArray = EnumerableEx.ToArray(objectPoints);
            Point2f[] imagePointsArray = EnumerableEx.ToArray(imagePoints);
            double[] distCoeffsArray = EnumerableEx.ToArray(distCoeffs);
            int distCoeffsLength = (distCoeffs == null) ? 0 : distCoeffsArray.Length;
            rvec = new double[3];
            tvec = new double[3];

            using (var inliersVec = new VectorOfInt32())
            {
                NativeMethods.calib3d_solvePnPRansac_vector(
                    objectPointsArray, objectPointsArray.Length,
                    imagePointsArray, imagePointsArray.Length,
                    cameraMatrix, distCoeffsArray, distCoeffsLength,
                    rvec, tvec, useExtrinsicGuess ? 1 : 0, iterationsCount,
                    reprojectionError, minInliersCount, inliersVec.CvPtr, (int)flags);
                inliers = inliersVec.ToArray();
            }
        }
 /// <summary>
 /// Computes convex hull for a set of 2D points.
 /// </summary>
 /// <param name="points">The input 2D point set, represented by CV_32SC2 or CV_32FC2 matrix</param>
 /// <param name="clockwise">If true, the output convex hull will be oriented clockwise, 
 /// otherwise it will be oriented counter-clockwise. Here, the usual screen coordinate 
 /// system is assumed - the origin is at the top-left corner, x axis is oriented to the right, 
 /// and y axis is oriented downwards.</param>
 /// <returns>The output convex hull. It is a vector of 0-based point indices of the 
 /// hull points in the original array (since the set of convex hull points is a subset of the original point set).</returns>
 public static int[] ConvexHullIndices(IEnumerable<Point2f> points, bool clockwise = false)
 {
     if (points == null)
         throw new ArgumentNullException("points");
     Point2f[] pointsArray = EnumerableEx.ToArray(points);
     IntPtr hullPtr;
     NativeMethods.imgproc_convexHull_Point2f_ReturnsIndices(pointsArray, pointsArray.Length, out hullPtr, clockwise ? 1 : 0);
     using (var hullVec = new VectorOfInt32(hullPtr))
     {
         return hullVec.ToArray();
     }
 }
        /// <summary>
        /// Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
        /// </summary>
        /// <param name="image">Matrix of the type CV_8U containing an image where objects are detected.</param>
        /// <param name="rejectLevels"></param>
        /// <param name="levelWeights"></param>
        /// <param name="scaleFactor">Parameter specifying how much the image size is reduced at each image scale.</param>
        /// <param name="minNeighbors">Parameter specifying how many neighbors each candidate rectangle should have to retain it.</param>
        /// <param name="flags">Parameter with the same meaning for an old cascade as in the function cvHaarDetectObjects. 
        /// It is not used for a new cascade.</param>
        /// <param name="minSize">Minimum possible object size. Objects smaller than that are ignored.</param>
        /// <param name="maxSize">Maximum possible object size. Objects larger than that are ignored.</param>
        /// <param name="outputRejectLevels"></param>
        /// <returns>Vector of rectangles where each rectangle contains the detected object.</returns>
        public virtual Rect[] DetectMultiScale(
            Mat image,
            out int[] rejectLevels,
            out double[] levelWeights,
            double scaleFactor = 1.1,
            int minNeighbors = 3,
            HaarDetectionType flags = HaarDetectionType.Zero,
            Size? minSize = null,
            Size? maxSize = null,
            bool outputRejectLevels = false)
        {
            if (disposed)
                throw new ObjectDisposedException("CascadeClassifier");
            if (image == null)
                throw new ArgumentNullException("image");
            image.ThrowIfDisposed();

            Size minSize0 = minSize.GetValueOrDefault(new Size());
            Size maxSize0 = maxSize.GetValueOrDefault(new Size());

            using (var objectsVec = new VectorOfRect())
            using (var rejectLevelsVec = new VectorOfInt32())
            using (var levelWeightsVec = new VectorOfDouble())
            {
                NativeMethods.objdetect_CascadeClassifier_detectMultiScale(
                    ptr, image.CvPtr, objectsVec.CvPtr, rejectLevelsVec.CvPtr, levelWeightsVec.CvPtr,
                    scaleFactor, minNeighbors, (int)flags, minSize0, maxSize0, outputRejectLevels ? 1 : 0);

                rejectLevels = rejectLevelsVec.ToArray();
                levelWeights = levelWeightsVec.ToArray();
                return objectsVec.ToArray();
            }
        }
Beispiel #14
0
 /// <summary>
 /// Returns all the bitsets for categorical splits.
 /// Split::subsetOfs is an offset in the returned vector
 /// </summary>
 /// <returns></returns>
 public int[] GetSubsets()
 {
     if (ptr == IntPtr.Zero)
         throw new ObjectDisposedException(GetType().Name);
     
     using (var vector = new VectorOfInt32())
     {
         NativeMethods.ml_DTrees_getSubsets(ptr, vector.CvPtr);
         return vector.ToArray();
     }
 }