Esempio n. 1
0
        /// <summary>
        /// Try to stitch the given images.
        /// </summary>
        /// <param name="images">Input images.</param>
        /// <param name="rois">Region of interest rectangles.</param>
        /// <param name="pano">Final pano.</param>
        /// <returns>Status code.</returns>
        public Status Stitch(IEnumerable <Mat> images, Rect[][] rois, OutputArray pano)
        {
            if (images == null)
            {
                throw new ArgumentNullException(nameof(images));
            }
            if (rois == null)
            {
                throw new ArgumentNullException(nameof(rois));
            }
            if (pano == null)
            {
                throw new ArgumentNullException(nameof(pano));
            }
            pano.ThrowIfNotReady();

            var imagesPtrs = images.Select(x => x.CvPtr).ToArray();

            using var roisPointer = new ArrayAddress2 <Rect>(rois);
            NativeMethods.HandleException(
                NativeMethods.stitching_Stitcher_stitch2_MatArray(
                    ptr, imagesPtrs, imagesPtrs.Length,
                    roisPointer.GetPointer(), roisPointer.GetDim1Length(), roisPointer.GetDim2Lengths(),
                    pano.CvPtr, out var ret));

            pano.Fix();
            GC.KeepAlive(this);
            GC.KeepAlive(images);
            GC.KeepAlive(pano);
            return((Status)ret);
        }
Esempio n. 2
0
        /// <summary>
        /// Try to stitch the given images.
        /// </summary>
        /// <param name="images">Input images.</param>
        /// <param name="rois">Region of interest rectangles.</param>
        /// <param name="pano">Final pano.</param>
        /// <returns>Status code.</returns>
        public Status Stitch(InputArray images, Rect[][] rois, OutputArray pano)
        {
            if (images == null)
            {
                throw new ArgumentNullException(nameof(images));
            }
            if (rois == null)
            {
                throw new ArgumentNullException(nameof(rois));
            }
            if (pano == null)
            {
                throw new ArgumentNullException(nameof(pano));
            }
            images.ThrowIfDisposed();
            pano.ThrowIfNotReady();

            using var roisPointer = new ArrayAddress2 <Rect>(rois);
            NativeMethods.HandleException(
                NativeMethods.stitching_Stitcher_stitch2_InputArray(
                    ptr, images.CvPtr,
                    roisPointer.GetPointer(), roisPointer.GetDim1Length(), roisPointer.GetDim2Lengths(),
                    pano.CvPtr, out var ret));

            pano.Fix();
            GC.KeepAlive(this);
            GC.KeepAlive(images);
            GC.KeepAlive(pano);
            return((Status)ret);
        }
Esempio n. 3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="values"></param>
        public VectorOfVectorKeyPoint(KeyPoint[][] values)
        {
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }

            using var aa = new ArrayAddress2 <KeyPoint>(values);
            ptr          = NativeMethods.vector_vector_KeyPoint_new3(
                aa.GetPointer(), aa.GetDim1Length(), aa.GetDim2Lengths());
        }
Esempio n. 4
0
        /// <summary>
        /// Pose estimation for single markers
        /// </summary>
        /// <param name="corners">corners vector of already detected markers corners.
        /// For each marker, its four corners are provided, (e.g std::vector&lt;std::vector&lt;cv::Point2f&gt;&gt; ).
        /// For N detected markers, the dimensions of this array should be Nx4. The order of the corners should be clockwise.</param>
        /// <param name="markerLength">the length of the markers' side. The returning translation vectors will
        /// be in the same unit.Normally, unit is meters.</param>
        /// <param name="cameraMatrix">input 3x3 floating-point camera matrix
        /// \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$</param>
        /// <param name="distortionCoefficients">vector of distortion coefficients
        /// \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6],[s_1, s_2, s_3, s_4]])\f$ of 4, 5, 8 or 12 elements</param>
        /// <param name="rvec">array of output rotation vectors (@sa Rodrigues) (e.g. std::vector&lt;cv::Vec3d&gt;).
        /// Each element in rvecs corresponds to the specific marker in imgPoints.</param>
        /// <param name="tvec">array of output translation vectors (e.g. std::vector&lt;cv::Vec3d&gt;).
        /// Each element in tvecs corresponds to the specific marker in imgPoints.</param>
        /// <param name="objPoints">array of object points of all the marker corners</param>
        public static void EstimatePoseSingleMarkers(
            Point2f[][] corners,
            float markerLength,
            InputArray cameraMatrix,
            InputArray distortionCoefficients,
            OutputArray rvec,
            OutputArray tvec,
            OutputArray?objPoints = null)
        {
            if (corners == null)
            {
                throw new ArgumentNullException(nameof(corners));
            }
            if (cameraMatrix == null)
            {
                throw new ArgumentNullException(nameof(cameraMatrix));
            }
            if (distortionCoefficients == null)
            {
                throw new ArgumentNullException(nameof(distortionCoefficients));
            }
            if (rvec == null)
            {
                throw new ArgumentNullException(nameof(rvec));
            }
            if (tvec == null)
            {
                throw new ArgumentNullException(nameof(tvec));
            }

            cameraMatrix.ThrowIfDisposed();
            distortionCoefficients.ThrowIfDisposed();
            rvec.ThrowIfNotReady();
            tvec.ThrowIfNotReady();
            objPoints?.ThrowIfNotReady();

            using var cornersAddress = new ArrayAddress2 <Point2f>(corners);

            NativeMethods.HandleException(
                NativeMethods.aruco_estimatePoseSingleMarkers(
                    cornersAddress.GetPointer(), cornersAddress.GetDim1Length(), cornersAddress.GetDim2Lengths(),
                    markerLength, cameraMatrix.CvPtr, distortionCoefficients.CvPtr, rvec.CvPtr, tvec.CvPtr,
                    objPoints?.CvPtr ?? IntPtr.Zero));

            GC.KeepAlive(cameraMatrix);
            GC.KeepAlive(distortionCoefficients);
            rvec.Fix();
            tvec.Fix();
            objPoints?.Fix();
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="matches1to2"></param>
        /// <param name="correctMatches1to2Mask"></param>
        /// <returns>recallPrecisionCurve</returns>
        public static Point2f[] ComputeRecallPrecisionCurve(
            DMatch[][] matches1to2, byte[][] correctMatches1to2Mask)
        {
            if (matches1to2 == null)
            {
                throw new ArgumentNullException(nameof(matches1to2));
            }
            if (correctMatches1to2Mask == null)
            {
                throw new ArgumentNullException(nameof(correctMatches1to2Mask));
            }

            using var dm     = new ArrayAddress2 <DMatch>(matches1to2);
            using var cm     = new ArrayAddress2 <byte>(correctMatches1to2Mask);
            using var recall = new VectorOfPoint2f();
            NativeMethods.HandleException(
                NativeMethods.features2d_computeRecallPrecisionCurve(
                    dm.GetPointer(), dm.GetDim1Length(), dm.GetDim2Lengths(),
                    cm.GetPointer(), cm.GetDim1Length(), cm.GetDim2Lengths(),
                    recall.CvPtr));
            return(recall.ToArray());
        }
Esempio n. 6
0
        public Status EstimateTransform(InputArray images, Rect[][] rois)
        {
            if (images == null)
            {
                throw new ArgumentNullException(nameof(images));
            }
            if (rois == null)
            {
                throw new ArgumentNullException(nameof(rois));
            }
            images.ThrowIfDisposed();

            using var roisPointer = new ArrayAddress2 <Rect>(rois);
            NativeMethods.HandleException(
                NativeMethods.stitching_Stitcher_estimateTransform_InputArray2(
                    ptr, images.CvPtr,
                    roisPointer.GetPointer(), roisPointer.GetDim1Length(), roisPointer.GetDim2Lengths(),
                    out var ret));

            GC.KeepAlive(this);
            GC.KeepAlive(images);
            return((Status)ret);
        }
Esempio n. 7
0
        public Status EstimateTransform(IEnumerable <Mat> images, Rect[][] rois)
        {
            if (images == null)
            {
                throw new ArgumentNullException(nameof(images));
            }
            if (rois == null)
            {
                throw new ArgumentNullException(nameof(rois));
            }

            var imagesPtrs = images.Select(x => x.CvPtr).ToArray();

            using var roisPointer = new ArrayAddress2 <Rect>(rois);
            NativeMethods.HandleException(
                NativeMethods.stitching_Stitcher_estimateTransform_MatArray2(
                    ptr, imagesPtrs, imagesPtrs.Length,
                    roisPointer.GetPointer(), roisPointer.GetDim1Length(), roisPointer.GetDim2Lengths(),
                    out var ret));

            GC.KeepAlive(this);
            GC.KeepAlive(images);
            return((Status)ret);
        }
Esempio n. 8
0
        /// <summary>
        /// Draw a set of detected ChArUco Diamond markers.
        /// </summary>
        /// <param name="image">input/output image. It must have 1 or 3 channels. The number of channels is not altered.</param>
        /// <param name="diamondCorners">positions of diamond corners in the same format returned by detectCharucoDiamond(). (e.g std::vector&lt;std::vector&lt;cv::Point2f&gt;&gt;). For N detected markers, the dimensions of this array should be Nx4. The order of the corners should be clockwise.</param>
        /// <param name="diamondIds">vector of identifiers for diamonds in diamondCorners, in the same format returned by detectCharucoDiamond() (e.g. std::vector&lt;Vec4i&gt;). Optional, if not provided, ids are not painted.</param>
        /// <param name="borderColor">color of marker borders. Rest of colors (text color and first corner color) are calculated based on this one.</param>
        public static void DrawDetectedDiamonds(InputArray image,
                                                Point2f[][] diamondCorners, IEnumerable <Vec4i>?diamondIds, Scalar borderColor)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (diamondCorners == null)
            {
                throw new ArgumentNullException(nameof(diamondCorners));
            }

            using var cornersAddress = new ArrayAddress2 <Point2f>(diamondCorners);

            if (diamondIds == null)
            {
                NativeMethods.HandleException(
                    NativeMethods.aruco_drawDetectedDiamonds(image.CvPtr,
                                                             cornersAddress.GetPointer(), cornersAddress.GetDim1Length(), cornersAddress.GetDim2Lengths(),
                                                             IntPtr.Zero, borderColor));
            }
            else
            {
                using var ids = new VectorOfVec4i(diamondIds);

                NativeMethods.HandleException(
                    NativeMethods.aruco_drawDetectedDiamonds(image.CvPtr,
                                                             cornersAddress.GetPointer(), cornersAddress.GetDim1Length(), cornersAddress.GetDim2Lengths(),
                                                             ids.CvPtr, borderColor));
            }

            GC.KeepAlive(image);
        }
Esempio n. 9
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);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Draw detected markers in image
        /// </summary>
        /// <param name="image">input/output image. It must have 1 or 3 channels. The number of channels is not altered.</param>
        /// <param name="corners">positions of marker corners on input image.
        /// For N detected markers, the dimensions of this array should be Nx4.The order of the corners should be clockwise.</param>
        /// <param name="ids">vector of identifiers for markers in markersCorners. Optional, if not provided, ids are not painted.</param>
        /// <param name="borderColor">color of marker borders. Rest of colors (text color and first corner color)
        ///  are calculated based on this one to improve visualization.</param>
        public static void DrawDetectedMarkers(InputArray image, Point2f[][] corners, IEnumerable <int>?ids, Scalar borderColor)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (corners == null)
            {
                throw new ArgumentNullException(nameof(corners));
            }

            using var cornersAddress = new ArrayAddress2 <Point2f>(corners);
            if (ids == null)
            {
                NativeMethods.HandleException(
                    NativeMethods.aruco_drawDetectedMarkers(
                        image.CvPtr, cornersAddress.GetPointer(), cornersAddress.GetDim1Length(), cornersAddress.GetDim2Lengths(),
                        IntPtr.Zero, 0, borderColor));
            }
            else
            {
                var idxArray = ids.ToArray();
                NativeMethods.HandleException(
                    NativeMethods.aruco_drawDetectedMarkers(
                        image.CvPtr, cornersAddress.GetPointer(), cornersAddress.GetDim1Length(), cornersAddress.GetDim2Lengths(),
                        idxArray, idxArray.Length, borderColor));
            }
            GC.KeepAlive(image);
        }