Beispiel #1
0
        public ChessboardTrackingCompleteData Calibrate(PlaneTrackingCompleteData planeData, BlockingCollection <Message> outputQueue)
        {
            var chessboardData = new ChessboardTrackingCompleteData(planeData);

            SceneCalibrationSnapshot snapshot;

            (BoardReprezentation, snapshot) = ChessboardAlgorithm.LocateChessboard(chessboardData);
            outputQueue.Add(new SceneCalibrationSnapshotMessage(snapshot));

            RotationAlgorithm.Rotate(BoardReprezentation, chessboardData.KinectData.CameraSpacePointsFromDepthData);

            return(chessboardData);
        }
Beispiel #2
0
        public ChessboardTrackingCompleteData Track(PlaneTrackingCompleteData planeData)
        {
            var chessboardData = new ChessboardTrackingCompleteData(planeData);

            RotationAlgorithm.Rotate(BoardReprezentation, chessboardData.KinectData.CameraSpacePointsFromDepthData);

            chessboardData.ChessboardData.FieldSize = BoardReprezentation.FieldVector1.Magnitude();

            if (chessboardData.UserParameters.VisualisationType == VisualisationType.HighlightedChessboard)
            {
                chessboardData.ResultData.VisualisationBitmap =
                    Renderer.ReturnLocalizedChessboardWithTable(
                        chessboardData.PlaneData.MaskedColorImageOfTable.Bitmap,
                        chessboardData.PlaneData.MaskOfTable,
                        chessboardData.KinectData.PointsFromColorToDepth,
                        chessboardData.KinectData.CameraSpacePointsFromDepthData,
                        BoardReprezentation.FieldVector1.Magnitude());
            }

            return(chessboardData);
        }
Beispiel #3
0
        public FiguresTrackingCompleteData Track(ChessboardTrackingCompleteData chessboardData)
        {
            var figuresData = new FiguresTrackingCompleteData(chessboardData);

            (figuresData.ResultData.TrackingState, figuresData.ResultData.PointCountsOverFields) =
                FiguresLocalizationAlgorithm.LocateFigures(
                    figuresData.KinectData,
                    figuresData.ChessboardData.FieldSize,
                    figuresData.PlaneData.CannyDepthData,
                    figuresData.UserParameters,
                    figuresData.ResultData,
                    figuresData.PlaneData.ColorBitmap,
                    chessboardData.TrackingStateOfGame);

            var handDetected =
                HandDetectionAlgorithm.HandDetected(
                    figuresData.KinectData.CameraSpacePointsFromDepthData,
                    figuresData.ChessboardData.FieldSize
                    );

            figuresData.ResultData.SceneDisrupted = handDetected || figuresData.ResultData.SceneDisrupted;

            return(figuresData);
        }
        public (Chessboard3DReprezentation boardReprezentation, SceneCalibrationSnapshot snapshot) LocateChessboard(ChessboardTrackingCompleteData chessboardData)
        {
            var grayImage          = GetGrayImage(chessboardData.PlaneData.MaskedColorImageOfTable);
            var binarizedImage     = GetBinarizedImage(grayImage, chessboardData.UserParameters.OtzuActiveInBinarization, chessboardData.UserParameters.BinarizationThreshold);
            var cannyDetectorImage = ApplyCannyDetector(binarizedImage);

            var linesTuple = GetFilteredHoughLines(cannyDetectorImage);

            var snapshot = new SceneCalibrationSnapshot()
            {
                BinarizationImage = ((Bitmap)binarizedImage.Convert <Rgb, byte>().Bitmap.Clone()).HorizontalFlip(),
                CannyImage        = ((Bitmap)cannyDetectorImage.Convert <Rgb, byte>().Bitmap.Clone()).HorizontalFlip(),
                GrayImage         = ((Bitmap)grayImage.Convert <Rgb, byte>().Bitmap.Clone()).HorizontalFlip(),
                MaskedColorImage  = ((Bitmap)chessboardData.PlaneData.MaskedColorImageOfTable.Convert <Rgb, byte>().Bitmap.Clone()).HorizontalFlip()
            };

            var contractedPoints = LinesIntersections.GetIntersectionPointsOfTwoGroupsOfLines(linesTuple);

            var boardRepresentation = ChessboardFitting.ChessboardFittingAlgorithm(contractedPoints, chessboardData);

            return(boardRepresentation, snapshot);
        }
Beispiel #5
0
        public FiguresTrackingCompleteData Calibrate(ChessboardTrackingCompleteData chessboardData)
        {
            var figuresData = new FiguresTrackingCompleteData(chessboardData);

            return(figuresData);
        }
Beispiel #6
0
        /// <summary>
        /// Finds most suitable chessboard fitting real points
        /// </summary>
        public static Chessboard3DReprezentation ChessboardFittingAlgorithm(List <Point2D> contractedPoints, ChessboardTrackingCompleteData chessboardData)
        {
            const int takeXNearestNeighbors = 7;

            var contractedPoints3D = ConvertIntersectionsTo3D(contractedPoints, chessboardData);

            var contractedPoints3DasStruct = contractedPoints3D.Select(x => new MyVector3DStruct(x.X, x.Y, x.Z)).ToArray();

            double lowestError = double.MaxValue;
            Chessboard3DReprezentation boardRepresentation = null;

            Parallel.ForEach(contractedPoints3DasStruct, csp =>
            {
                // take _ nearest neighbors
                var neighbors = contractedPoints3DasStruct.OrderBy((MyVector3DStruct x) => MyVector3DStruct.Distance(ref x, ref csp)).Take(takeXNearestNeighbors).ToArray();

                // take all pairs of neighbors
                for (int i = 0; i < neighbors.Length; i++)
                {
                    for (int j = i + 1; j < neighbors.Length; j++)
                    {
                        var first  = neighbors[i];
                        var second = neighbors[j];

                        var firstPoint  = new MyVector3DStruct(first.x, first.y, first.z);
                        var secondPoint = new MyVector3DStruct(second.x, second.y, second.z);

                        // st. point + 2 vectors
                        var initialPoint = new MyVector3DStruct(csp.x, csp.y, csp.z);
                        var firstVector  = MyVector3DStruct.Difference(ref firstPoint, ref initialPoint);
                        var secondVector = MyVector3DStruct.Difference(ref secondPoint, ref initialPoint);

                        // perpendicularity check
                        double angleBetweenVectors = MyVector3DStruct.AngleInDeg(ref firstVector, ref secondVector);
                        if (!(angleBetweenVectors < 91.4 && angleBetweenVectors > 88.6))
                        {
                            break;
                        }

                        // length check
                        double ratio = firstVector.Magnitude() / secondVector.Magnitude();
                        if (!(ratio > 0.85f && ratio < 1.15f))
                        {
                            break;
                        }

                        // ensure right mutual position of first and second vector - otherwise switch them
                        if (MyVector3DStruct.CrossProduct(ref firstVector, ref secondVector).z < 0)
                        {
                            var temp     = firstVector;
                            firstVector  = secondVector;
                            secondVector = temp;
                        }

                        // length normalization of vectors
                        double averageLength = (firstVector.Magnitude() + secondVector.Magnitude()) / 2;

                        firstVector  = MyVector3DStruct.MultiplyByNumber(MyVector3DStruct.Normalize(ref firstVector), averageLength);
                        secondVector = MyVector3DStruct.MultiplyByNumber(MyVector3DStruct.Normalize(ref secondVector), averageLength);

                        var negatedFirstVector  = MyVector3DStruct.Negate(ref firstVector);
                        var negatedSecondVector = MyVector3DStruct.Negate(ref secondVector);

                        // locate all possible starting points
                        for (int f = 0; f < 9; f++)
                        {
                            for (int s = 0; s < 9; s++)
                            {
                                var startingPoint =
                                    MyVector3DStruct.Addition(
                                        MyVector3DStruct.Addition(
                                            MyVector3DStruct.MultiplyByNumber(negatedFirstVector, f),
                                            MyVector3DStruct.MultiplyByNumber(negatedSecondVector, s)
                                            )
                                        , initialPoint
                                        );
                                // generate all possible chessboards for given starting point and compute their error
                                double currentError = 0;

                                for (int ff = 0; ff < 9; ff++)
                                {
                                    for (int ss = 0; ss < 9; ss++)
                                    {
                                        var currentPoint = MyVector3DStruct.Addition(
                                            startingPoint,
                                            MyVector3DStruct.Addition(
                                                MyVector3DStruct.MultiplyByNumber(firstVector, ff),
                                                MyVector3DStruct.MultiplyByNumber(secondVector, ss)
                                                )
                                            );

                                        var closestPointDistance = contractedPoints3DasStruct.Min(x =>
                                                                                                  MyVector3DStruct.Distance(ref currentPoint,
                                                                                                                            new MyVector3DStruct(x.x, x.y, x.z)));

                                        // clipping of max error per point
                                        var clippingDistance = chessboardData.UserParameters.ClippedDistanecInChessboardFittingMetric / 1000f;
                                        closestPointDistance = closestPointDistance > clippingDistance ? clippingDistance : closestPointDistance;

                                        if (chessboardData.UserParameters.IsDistanceMetricInChessboardFittingExperimental)
                                        {
                                            closestPointDistance = closestPointDistance * closestPointDistance;
                                        }

                                        currentError += closestPointDistance;
                                    }
                                }

                                if (currentError < lowestError)
                                {
                                    lowestError         = currentError;
                                    boardRepresentation = new Chessboard3DReprezentation(startingPoint, firstVector, secondVector);
                                }
                            }
                        }
                    }
                }
            });

            return(boardRepresentation);
        }
Beispiel #7
0
        /// <summary>
        /// Converts points from color bitmap to 3D coordintes using kinect defined mapping
        /// </summary>
        private static List <CameraSpacePoint> ConvertIntersectionsTo3D(List <Point2D> contractedPoints, ChessboardTrackingCompleteData chessboardData)
        {
            var contractedPoints3D = new List <CameraSpacePoint>();

            foreach (var contractedPoint in contractedPoints)
            {
                var depthReference = chessboardData.KinectData.PointsFromColorToDepth[(int)contractedPoint.X + (int)contractedPoint.Y * 1920];
                if (!float.IsInfinity(depthReference.X))
                {
                    var csp = chessboardData.KinectData.CameraSpacePointsFromDepthData[(int)depthReference.X + (int)depthReference.Y * 512];
                    contractedPoints3D.Add(csp);
                }
            }

            return(contractedPoints3D);
        }