// detects Aruco markers in the frame
        unsafe public static UDetectMarkersData UDetectMarkers(Color32[] texture, int width, int height)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();
            VectorIntMarshaller           markerIds = new VectorIntMarshaller();
            DoubleVectorPoint2FMarshaller markerCornerMarshaller      = new DoubleVectorPoint2FMarshaller();
            DoubleVectorPoint2FMarshaller rejectedCandidateMarshaller = new DoubleVectorPoint2FMarshaller();


            fixed(Color32 *texP = texture)
            {
                DetectMarkers(
                    texP,
                    width,
                    height,
                    markerIds.NativeDataPointer,
                    markerCornerMarshaller.NativeDataPointer,
                    rejectedCandidateMarshaller.NativeDataPointer
                    );
            }

            UDetectMarkersData markerData = new UDetectMarkersData(
                (int[])markerIds.GetMangedObject(),
                (List <List <Vector2> >)markerCornerMarshaller.GetMangedObject(),
                (List <List <Vector2> >)rejectedCandidateMarshaller.GetMangedObject(),
                markerIds.NativeDataPointer,
                markerCornerMarshaller.NativeDataPointer,
                rejectedCandidateMarshaller.NativeDataPointer
                );

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            return(markerData);
        }
        public unsafe static (UDetectMarkersData, UBoardMarkerPoseEstimationDataEuler) UEstimateCharucoBoardPose(Color32[] texture, int width, int height, CharucoBoardParameters boardParameters, IntPtr cameraMatrix, IntPtr distCoeffs)
        {
            int   cornersH     = 3;
            int   cornersW     = 4;
            float markerLength = 0.045f;
            float squareLength = 0.06f;
            // marshallers
            Vec3dMarshaller     tvecMarshaller = new Vec3dMarshaller();
            Vec3dMarshaller     rvecMarshaller = new Vec3dMarshaller();
            MatDoubleMarshaller eulerAngles    = new MatDoubleMarshaller();
            // marker pointers
            VectorIntMarshaller           markerIds = new VectorIntMarshaller();
            DoubleVectorPoint2FMarshaller markerCornerMarshaller      = new DoubleVectorPoint2FMarshaller();
            DoubleVectorPoint2FMarshaller rejectedCandidateMarshaller = new DoubleVectorPoint2FMarshaller();

            estimateCharucoBoardPosePerfMarker.Begin();
            fixed(Color32 *texP = texture)
            {
                EstimateCharucoBoardPose(
                    texP,
                    width,
                    height,
                    // markerLength,
                    // squareLength,
                    // cornersW,
                    // cornersH,
                    boardParameters.markerLength,
                    boardParameters.squareLength,
                    boardParameters.squaresW,
                    boardParameters.squaresH,
                    markerIds.NativeDataPointer,
                    markerCornerMarshaller.NativeDataPointer,
                    rejectedCandidateMarshaller.NativeDataPointer,
                    cameraMatrix,
                    distCoeffs,
                    rvecMarshaller.NativeDataPointer,
                    tvecMarshaller.NativeDataPointer,
                    eulerAngles.NativeDataPointer
                    );
            }

            estimateCharucoBoardPosePerfMarker.End();

            UDetectMarkersData markerData = new UDetectMarkersData(
                (int[])markerIds.GetMangedObject(),
                (List <List <Vector2> >)markerCornerMarshaller.GetMangedObject(),
                (List <List <Vector2> >)rejectedCandidateMarshaller.GetMangedObject(),
                markerIds.NativeDataPointer,
                markerCornerMarshaller.NativeDataPointer,
                rejectedCandidateMarshaller.NativeDataPointer
                );

            UBoardMarkerPoseEstimationDataEuler PoseEstimateData = new UBoardMarkerPoseEstimationDataEuler(
                (Vec3d)rvecMarshaller.GetMangedObject(),
                (Vec3d)tvecMarshaller.GetMangedObject(),
                (double[][])eulerAngles.GetMangedObject()
                );

            return(markerData : markerData, PoseEstimateData : PoseEstimateData);
        }