示例#1
0
        private Mat DetectServing(Mat mat)
        {
            mat = mat.ToImage <Bgr, byte>().Rotate(90, new Bgr(0, 0, 0)).Mat;
            Mat result         = mat.Clone();
            var processedImage = PreProcessImage(mat);
            var detectedBall   = DetectBall(processedImage);
            var detectedHand   = DetectHand(processedImage);

            switch (rule)
            {
            case InitiateRule.FirstRule:
                DetectFirstRule(detectedBall, detectedHand, result);
                break;

            case InitiateRule.SecondRule:
                DetectSecondRule(detectedBall, lastFrameBall, lastFrameBallInHand, detectedHand, result);
                break;

            default:
                rule = InitiateRule.FirstRule;

                break;
            }

            /*bool isLegal = DetectFirstRule(detectedBall, detectedHand, result);
             * if (isLegal)
             * {
             *  DetectSecondRule(detectedBall, lastFoundBall, lastFrameBallInHand, detectedHand, result);
             * }*/

            result        = DrawObjects(detectedBall, detectedHand, mat);
            lastFrame     = mat;
            lastFrameBall = detectedBall.Center.X != 0 ? detectedBall : lastFrameBall;
            return(result);
        }
示例#2
0
        private void DetectSecondRule(CircleF currentFrameBall, CircleF lastFrameBall, CircleF lastFrameBallInHand, VectorOfPoint hand, Mat image)
        {
            // compare last frame ball coordinates with current frame ball coordinates

            // if y axis is highier in current frame - loop again
            if (currentFrameBall.Center.Y < lastFrameBall.Center.Y)
            {
                //recordedHeight = ((lastFrameBallInHand.Center.Y - currentFrameBall.Center.Y) * 2) / lastFrameBall.Radius;
                return;
            }

            if (currentFrameBall.Center.Y > lastFrameBall.Center.Y && currentFrameBall.Center.Y > lastFrameBallInHand.Center.Y)
            {
                rule           = InitiateRule.FirstRule;
                recordedHeight = -1;
                //recordedHeight = ((lastFrameBallInHand.Center.Y - currentFrameBall.Center.Y) * 2) / lastFrameBall.Radius;
                return;
            }

            // if y axis is highier than when ball was in hand but lower that last frame - calculate height (last frame - last fame in hand
            if (currentFrameBall.Center.Y > lastFrameBall.Center.Y && currentFrameBall.Center.Y < lastFrameBallInHand.Center.Y)
            {
                float height = lastFrameBallInHand.Center.Y - lastFrameBall.Center.Y;
                if (height >= (lastFrameBall.Radius * 2 * 4))
                {
                    line = new LineSegment2D(new System.Drawing.Point(
                                                 (int)lastFrameBall.Center.X,
                                                 (int)lastFrameBall.Center.Y),
                                             new System.Drawing.Point((int)lastFrameBallInHand.Center.X,
                                                                      (int)lastFrameBallInHand.Center.Y)
                                             );
                }
                recordedHeight = (height * 2) / lastFrameBall.Radius;
                rule           = InitiateRule.FirstRule;
                return;
            }
            // if ball is not recognized for 1 second - count as failed pass - go to first rule.

            // need logging
        }
示例#3
0
        private bool DetectFirstRule(CircleF ball, VectorOfPoint detectedHand, Mat image)
        {
            Mat circle = new Mat(image.Rows, image.Cols, image.Depth, image.NumberOfChannels);
            Mat hand   = new Mat(image.Rows, image.Cols, image.Depth, image.NumberOfChannels);

            circle.SetTo(new MCvScalar(0));
            hand.SetTo(new MCvScalar(0));

            int averageBallRadius = lastHalfSecondRadiuses.Count > 0 ? lastHalfSecondRadiuses.Max() : (int)ball.Radius;

            if (ball.Radius > 0)
            {
                CvInvoke.Circle(circle, System.Drawing.Point.Round(ball.Center), averageBallRadius, new Bgr(System.Drawing.Color.White).MCvScalar, -1);
            }

            if (detectedHand.Size != 0)
            {
                var           cont = new VectorOfVectorOfPoint(detectedHand);
                VectorOfPoint hull = new VectorOfPoint();
                CvInvoke.ConvexHull(detectedHand, hull, false, true);
                cont = new VectorOfVectorOfPoint(hull);
                CvInvoke.DrawContours(hand, cont, 0, new Bgr(System.Drawing.Color.White).MCvScalar, -1);
            }

            Mat res = new Mat(image.Rows, image.Cols, image.Depth, image.NumberOfChannels);

            CvInvoke.BitwiseAnd(circle, hand, res);
            CvInvoke.CvtColor(res, res, ColorConversion.Hsv2Bgr);
            CvInvoke.CvtColor(res, res, ColorConversion.Bgr2Gray);
            bool ballInHand = CvInvoke.CountNonZero(res) > 0;

            /*double isInSideSouth = -1.0;
             * double isInSideNorth = -1.0;
             * double isInSideEast = -1.0;
             * double isInSideWest = -1.0;*/
            /*if (detectedHand.Size != 0 && ball.Radius > 0)
             * {
             *  isInSideSouth = CvInvoke.PointPolygonTest(detectedHand, new PointF(ball.Center.X, ball.Center.Y + ball.Radius), false);
             *  isInSideNorth = CvInvoke.PointPolygonTest(detectedHand, new PointF(ball.Center.X, ball.Center.Y - ball.Radius), false);
             *  isInSideEast = CvInvoke.PointPolygonTest(detectedHand, new PointF(ball.Center.X + ball.Radius, ball.Center.Y), false);
             *  isInSideWest = CvInvoke.PointPolygonTest(detectedHand, new PointF(ball.Center.X - ball.Radius, ball.Center.Y), false);
             * }
             * if (isInSideSouth == 1 || isInSideSouth == 0 || isInSideNorth == 1 || isInSideNorth == 0 || isInSideEast == 1 || isInSideEast == 0 || isInSideWest == 1 || isInSideWest == 0)
             * {
             *  ballInHand = true;
             * }
             * else
             * {
             *  ballInHand = false;
             * }*/
            if (ballInHand == true)
            {
                lastFrameBallInHand = ball;
            }
            if (ballInHand == false && ballIsInHand == true)
            {
                rule = InitiateRule.SecondRule;
            }
            ballIsInHand = ballInHand;
            return(ballInHand);
        }