示例#1
0
        public DetectedThrow GetThrow()
        {
            if (rays.Count < 2)
            {
                rays.Clear();
                return(null);
            }

            var firstBestRay  = rays.OrderByDescending(i => i.ContourArea).ElementAt(0);
            var secondBestRay = rays.OrderByDescending(i => i.ContourArea).ElementAt(1);

            rays.Clear();

            var poi = MeasureService.FindLinesIntersection(firstBestRay.CamPoint,
                                                           firstBestRay.RayPoint,
                                                           secondBestRay.CamPoint,
                                                           secondBestRay.RayPoint);

            if (float.IsNaN(poi.X) || float.IsNaN(poi.Y))
            {
                return(null);
            }

            var thrw = PrepareThrowData(poi, firstBestRay, secondBestRay);

            return(thrw);
        }
示例#2
0
        public CamService(MainWindow mainWindow,
                          string parentGridName,
                          CamServiceWorkingMode mode = CamServiceWorkingMode.Work)
        {
            this.mode           = mode;
            this.mainWindow     = mainWindow;
            this.parentGridName = parentGridName;
            logger         = MainWindow.ServiceContainer.Resolve <Logger>();
            drawService    = MainWindow.ServiceContainer.Resolve <DrawService>();
            configService  = MainWindow.ServiceContainer.Resolve <ConfigService>();
            measureService = new MeasureService(this);

            var camIndex = -1;

            switch (parentGridName)
            {
            case "Cam1Grid":
                camNumber  = 1;
                setupPoint = new PointF(configService.Read <float>(SettingsType.Cam1X),
                                        configService.Read <float>(SettingsType.Cam1Y));
                camIndex = GetCamIndex(SettingsType.Cam1Id);
                break;

            case "Cam2Grid":
                camNumber  = 2;
                setupPoint = new PointF(configService.Read <float>(SettingsType.Cam2X),
                                        configService.Read <float>(SettingsType.Cam2Y));
                camIndex = GetCamIndex(SettingsType.Cam2Id);
                break;

            case "Cam3Grid":
                camNumber  = 3;
                setupPoint = new PointF(configService.Read <float>(SettingsType.Cam3X),
                                        configService.Read <float>(SettingsType.Cam3Y));
                camIndex = GetCamIndex(SettingsType.Cam3Id);
                break;

            case "Cam4Grid":
                camNumber  = 4;
                setupPoint = new PointF(configService.Read <float>(SettingsType.Cam4X),
                                        configService.Read <float>(SettingsType.Cam4Y));
                camIndex = GetCamIndex(SettingsType.Cam4Id);
                break;
            }

            resolutionWidth  = configService.Read <int>(SettingsType.ResolutionWidth);
            resolutionHeight = configService.Read <int>(SettingsType.ResolutionHeight);
            movesExtraction  = configService.Read <int>(SettingsType.MovesExtraction);
            movesDart        = configService.Read <int>(SettingsType.MovesDart);
            movesNoise       = configService.Read <int>(SettingsType.MovesNoise);
            smoothGauss      = configService.Read <int>(SettingsType.SmoothGauss);
            toBullAngle      = MeasureService.FindAngle(setupPoint, DrawService.projectionCenterPoint);
            videoCapture     = new VideoCapture(camIndex, VideoCapture.API.DShow);
            videoCapture.SetCaptureProperty(CapProp.FrameWidth, resolutionWidth);
            videoCapture.SetCaptureProperty(CapProp.FrameHeight, resolutionHeight);
            GetSlidersData();
            RefreshImageBoxes();
        }
        public string FindContourOnRoiFrame(CamService cam)
        {
            var allContours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(cam.RoiFrame,
                                  allContours,
                                  new Mat(),
                                  RetrType.External,
                                  ChainApproxMethod.ChainApproxNone);

            var contour      = new VectorOfPoint();
            var contourArс   = 0.0;
            var contourArea  = 0.0;
            var contourWidth = 0.0;

            for (var i = 0; i < allContours.Size; i++)
            {
                var tempContour    = allContours[i];
                var tempContourArс = CvInvoke.ArcLength(tempContour, true);
                if (tempContourArс > contourArс)
                {
                    contour    = tempContour;
                    contourArс = tempContourArс;
                }
            }

            if (contourArс > 0)
            {
                contourArea = CvInvoke.ContourArea(contour);
                var rect             = CvInvoke.MinAreaRect(contour);
                var box              = CvInvoke.BoxPoints(rect);
                var contourBoxPoint1 = new PointF(box[0].X, (float)cam.roiPosYSlider + box[0].Y);
                var contourBoxPoint2 = new PointF(box[1].X, (float)cam.roiPosYSlider + box[1].Y);
                var contourBoxPoint4 = new PointF(box[3].X, (float)cam.roiPosYSlider + box[3].Y);
                var side1            = MeasureService.FindDistance(contourBoxPoint1, contourBoxPoint2);
                var side2            = MeasureService.FindDistance(contourBoxPoint4, contourBoxPoint1);

                contourWidth = side1 < side2
                                   ? side1
                                   : side2;
            }

            return(Converter.ToString($"Contour\n" +
                                      $"Arc:\n" +
                                      $"{(int) contourArс}\n" +
                                      $"Area:\n" +
                                      $"{(int) contourArea}\n" +
                                      $"Width:\n" +
                                      $"{(int) contourWidth}\n"
                                      ));
        }
示例#4
0
        public DetectedThrow GetThrow()
        {
            logger.Debug($"Calculate throw start");

            if (rays.Count < 2)
            {
                logger.Debug($"Rays count < 2. Calculate throw end.");

                rays.Clear();
                return(null);
            }

            rays.ForEach(r => logger.Info($"Ray:'{r}'"));

            var firstBestRay  = rays.OrderByDescending(i => i.ContourArc).ElementAt(0);
            var secondBestRay = rays.OrderByDescending(i => i.ContourArc).ElementAt(1);

            rays.Clear();

            logger.Info($"Best rays:'{firstBestRay}' and '{secondBestRay}'");

            var poi = MeasureService.FindLinesIntersection(firstBestRay.CamPoint,
                                                           firstBestRay.RayPoint,
                                                           secondBestRay.CamPoint,
                                                           secondBestRay.RayPoint);

            if (float.IsNaN(poi.X) || float.IsNaN(poi.Y))
            {
                logger.Info($"Corrupted poi. Abort");
                return(null);
            }

            var thrw = PrepareThrowData(poi);

            drawService.ProjectionDrawLine(firstBestRay.CamPoint, firstBestRay.RayPoint, new Bgr(Color.Aqua).MCvScalar, true);
            drawService.ProjectionDrawLine(secondBestRay.CamPoint, secondBestRay.RayPoint, new Bgr(Color.Aqua).MCvScalar, false);
            drawService.ProjectionDrawThrow(poi, false);
            drawService.PrintThrow(thrw);


            logger.Info($"Throw:{thrw}");
            logger.Debug($"Calculate throw end.");
            return(thrw);
        }
示例#5
0
        public CamService(CamNumber camNumber,
                          ILogger logger,
                          DrawService drawService,
                          IConfigService configService)
        {
            this.camNumber     = camNumber;
            this.logger        = logger;
            this.drawService   = drawService;
            this.configService = configService;

            var camIndex = -1;

            switch (camNumber)
            {
            case CamNumber._1:
                camIndex            = GetCamIndexById(configService.Cam1Id);
                thresholdSlider     = configService.Cam1ThresholdSliderValue;
                roiPosYSlider       = configService.Cam1RoiPosYSliderValue;
                roiHeightSlider     = configService.Cam1RoiHeightSliderValue;
                surfaceSlider       = configService.Cam1SurfaceSliderValue;
                surfaceCenterSlider = configService.Cam1SurfaceCenterSliderValue;
                camSetupPoint       = new PointF(configService.Cam1XSetupValue,
                                                 configService.Cam1YSetupValue);
                break;

            case CamNumber._2:
                camIndex            = GetCamIndexById(configService.Cam2Id);
                thresholdSlider     = configService.Cam2ThresholdSliderValue;
                roiPosYSlider       = configService.Cam2RoiPosYSliderValue;
                roiHeightSlider     = configService.Cam2RoiHeightSliderValue;
                surfaceSlider       = configService.Cam2SurfaceSliderValue;
                surfaceCenterSlider = configService.Cam2SurfaceCenterSliderValue;
                camSetupPoint       = new PointF(configService.Cam2XSetupValue,
                                                 configService.Cam2YSetupValue);
                break;

            case CamNumber._3:
                camIndex            = GetCamIndexById(configService.Cam3Id);
                thresholdSlider     = configService.Cam3ThresholdSliderValue;
                roiPosYSlider       = configService.Cam3RoiPosYSliderValue;
                roiHeightSlider     = configService.Cam3RoiHeightSliderValue;
                surfaceSlider       = configService.Cam3SurfaceSliderValue;
                surfaceCenterSlider = configService.Cam3SurfaceCenterSliderValue;
                camSetupPoint       = new PointF(configService.Cam3XSetupValue,
                                                 configService.Cam3YSetupValue);

                break;

            case CamNumber._4:
                camIndex            = GetCamIndexById(configService.Cam4Id);
                thresholdSlider     = configService.Cam4ThresholdSliderValue;
                roiPosYSlider       = configService.Cam4RoiPosYSliderValue;
                roiHeightSlider     = configService.Cam4RoiHeightSliderValue;
                surfaceSlider       = configService.Cam4SurfaceSliderValue;
                surfaceCenterSlider = configService.Cam4SurfaceCenterSliderValue;
                camSetupPoint       = new PointF(configService.Cam4XSetupValue,
                                                 configService.Cam4YSetupValue);

                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(camNumber), camNumber, null);
            }

            resolutionWidth  = configService.CamsResolutionWidth;
            resolutionHeight = configService.CamsResolutionHeight;
            smoothGauss      = configService.SmoothGaussValue;
            camFovAngle      = configService.CamsFovAngle;
            videoCapture     = new VideoCapture(camIndex, VideoCapture.API.DShow);
            videoCapture.SetCaptureProperty(CapProp.FrameWidth, resolutionWidth);
            videoCapture.SetCaptureProperty(CapProp.FrameHeight, resolutionHeight);
            var projectionCenterPoint = new PointF((float)DrawService.ProjectionFrameSide / 2,
                                                   (float)DrawService.ProjectionFrameSide / 2);

            toBullAngle = MeasureService.FindAngle(camSetupPoint, projectionCenterPoint);
        }
示例#6
0
        private DetectedThrow PrepareThrowData(PointF poi, Ray firstRay, Ray secondRay)
        {
            var sectors = new List <int>()
            {
                14, 9, 12, 5, 20,
                1, 18, 4, 13, 6,
                10, 15, 2, 17, 3,
                19, 7, 16, 8, 11
            };
            var projectionCenterPoint = new PointF((float)DrawService.ProjectionFrameSide / 2,
                                                   (float)DrawService.ProjectionFrameSide / 2);
            var angle    = MeasureService.FindAngle(projectionCenterPoint, poi);
            var distance = MeasureService.FindDistance(projectionCenterPoint, poi);
            var sector   = 0;
            var type     = ThrowType.Single;

            if (distance >= DrawService.ProjectionCoefficient * 95 &&
                distance <= DrawService.ProjectionCoefficient * 105)
            {
                type = ThrowType.Tremble;
            }
            else if (distance >= DrawService.ProjectionCoefficient * 160 &&
                     distance <= DrawService.ProjectionCoefficient * 170)
            {
                type = ThrowType.Double;
            }

            // Find sector
            if (distance <= DrawService.ProjectionCoefficient * 7)
            {
                sector = 50;
                type   = ThrowType.Bull;
            }
            else if (distance > DrawService.ProjectionCoefficient * 7 &&
                     distance <= DrawService.ProjectionCoefficient * 17)
            {
                sector = 25;
                type   = ThrowType._25;
            }
            else if (distance > DrawService.ProjectionCoefficient * 170)
            {
                sector = 0;
                type   = ThrowType.Zero;
            }
            else
            {
                var startRadSector = MeasureService.StartRadSector_1114;
                var radSector      = startRadSector;
                foreach (var proceedSector in sectors)
                {
                    if (angle >= radSector && angle < radSector + MeasureService.SectorStepRad)
                    {
                        sector = proceedSector;
                        break;
                    }

                    sector = 11; // todo - works, but not looks pretty

                    radSector += MeasureService.SectorStepRad;
                }
            }

            return(new DetectedThrow(poi, firstRay, secondRay, sector, type, DrawService.ProjectionFrameSide));
        }
        private Ray ProcessDartContour(CamService cam, DartContour dartContour)
        {
            // Moments and centerpoint
            // var contourMoments = CvInvoke.Moments(processedContour);
            // var contourCenterPoint = new PointF((float) (contourMoments.M10 / contourMoments.M00),
            //                                     (float) camService.roiPosYSlider + (float) (contourMoments.M01 / contourMoments.M00));

            // Find contour rectangle
            var rect = CvInvoke.MinAreaRect(dartContour.ContourPoints);
            var box  = CvInvoke.BoxPoints(rect);

            var contourBoxPoint1 = new PointF(box[0].X, (float)cam.roiPosYSlider + box[0].Y);
            var contourBoxPoint2 = new PointF(box[1].X, (float)cam.roiPosYSlider + box[1].Y);
            var contourBoxPoint3 = new PointF(box[2].X, (float)cam.roiPosYSlider + box[2].Y);
            var contourBoxPoint4 = new PointF(box[3].X, (float)cam.roiPosYSlider + box[3].Y);

            // Setup vertical contour middlepoints
            var    contourHeight = MeasureService.FindDistance(contourBoxPoint1, contourBoxPoint2);
            var    contourWidth  = MeasureService.FindDistance(contourBoxPoint4, contourBoxPoint1);
            PointF contourBoxMiddlePoint1;
            PointF contourBoxMiddlePoint2;

            if (contourWidth > contourHeight)
            {
                contourBoxMiddlePoint1 = MeasureService.FindMiddle(contourBoxPoint1, contourBoxPoint2);
                contourBoxMiddlePoint2 = MeasureService.FindMiddle(contourBoxPoint4, contourBoxPoint3);
            }
            else
            {
                contourBoxMiddlePoint1 = MeasureService.FindMiddle(contourBoxPoint4, contourBoxPoint1);
                contourBoxMiddlePoint2 = MeasureService.FindMiddle(contourBoxPoint3, contourBoxPoint2);
            }

            // Find spikeLine to surface
            var spikeLinePoint1 = contourBoxMiddlePoint1;
            var spikeLinePoint2 = contourBoxMiddlePoint2;
            var spikeLineLength = cam.surfaceSlider - contourBoxMiddlePoint2.Y;
            var spikeAngle      = MeasureService.FindAngle(contourBoxMiddlePoint2, contourBoxMiddlePoint1);

            spikeLinePoint1.X = (float)(contourBoxMiddlePoint2.X + Math.Cos(spikeAngle) * spikeLineLength);
            spikeLinePoint1.Y = (float)(contourBoxMiddlePoint2.Y + Math.Sin(spikeAngle) * spikeLineLength);

            // Find point of impact with surface
            PointF?camPoi = MeasureService.FindLinesIntersection(spikeLinePoint1,
                                                                 spikeLinePoint2,
                                                                 new PointF(0,
                                                                            (float)cam.surfaceSlider),
                                                                 new PointF(cam.resolutionWidth,
                                                                            (float)cam.surfaceSlider));

            // Translate cam surface POI to dartboard projection
            var frameSemiWidth             = cam.resolutionWidth / 2;
            var camFovSemiAngle            = cam.camFovAngle / 2;
            var projectionToCenter         = new PointF();
            var surfacePoiToCenterDistance = MeasureService.FindDistance(new PointF((float)cam.surfaceCenterSlider,
                                                                                    (float)cam.surfaceSlider),
                                                                         camPoi.GetValueOrDefault());
            var surfaceLeftToPoiDistance = MeasureService.FindDistance(new PointF((float)cam.surfaceCenterSlider - cam.resolutionWidth / 3,
                                                                                  (float)cam.surfaceSlider),
                                                                       camPoi.GetValueOrDefault());
            var surfaceRightToPoiDistance = MeasureService.FindDistance(new PointF((float)cam.surfaceCenterSlider + cam.resolutionWidth / 3,
                                                                                   (float)cam.surfaceSlider),
                                                                        camPoi.GetValueOrDefault());
            var projectionCamToCenterDistance = frameSemiWidth / Math.Sin(Math.PI * camFovSemiAngle / 180.0) * Math.Cos(Math.PI * camFovSemiAngle / 180.0);
            var projectionCamToPoiDistance    = Math.Sqrt(Math.Pow(projectionCamToCenterDistance, 2) + Math.Pow(surfacePoiToCenterDistance, 2));
            var projectionPoiToCenterDistance = Math.Sqrt(Math.Pow(projectionCamToPoiDistance, 2) - Math.Pow(projectionCamToCenterDistance, 2));
            var poiCamCenterAngle             = Math.Asin(projectionPoiToCenterDistance / projectionCamToPoiDistance);

            projectionToCenter.X = (float)(cam.camSetupPoint.X - Math.Cos(cam.toBullAngle) * projectionCamToCenterDistance);
            projectionToCenter.Y = (float)(cam.camSetupPoint.Y - Math.Sin(cam.toBullAngle) * projectionCamToCenterDistance);

            if (surfaceLeftToPoiDistance < surfaceRightToPoiDistance)
            {
                poiCamCenterAngle *= -1;
            }

            var projectionPoi = new PointF((float)(cam.camSetupPoint.X + Math.Cos(cam.toBullAngle + poiCamCenterAngle) * 2000),
                                           (float)(cam.camSetupPoint.Y + Math.Sin(cam.toBullAngle + poiCamCenterAngle) * 2000));

            // Draw line from cam through projection POI
            var rayPoint = projectionPoi;
            var angle    = MeasureService.FindAngle(cam.camSetupPoint, rayPoint);

            rayPoint.X = (float)(cam.camSetupPoint.X + Math.Cos(angle) * 2000);
            rayPoint.Y = (float)(cam.camSetupPoint.Y + Math.Sin(angle) * 2000);

            return(new Ray(cam.camNumber, cam.camSetupPoint, rayPoint, dartContour.Area));
        }
        private MovesDetectionResult DetectMoves(CamService cam)
        {
            var maxDartContourArc   = configService.MaxContourArcValue * 1.5;
            var maxDartContourArea  = configService.MaxContourAreaValue * 1.5;
            var maxDartContourWidth = configService.MaxContourWidthValue * 1.5;

            var minDartContourArc   = configService.MinContourArcValue;
            var minDartContourArea  = configService.MinContourAreaValue;
            var minDartContourWidth = configService.MinContourWidthValue;

            var allContours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(cam.ThrowExtractedRoiFrame,
                                  allContours,
                                  new Mat(),
                                  RetrType.External,
                                  ChainApproxMethod.ChainApproxNone);

            if (!detectionEnabled || allContours.Size == 0)
            {
                return(MovesDetectionResult.Nothing);
            }

            var contourWithMaxArc   = new VectorOfPoint();
            var contourWithMaxArea  = new VectorOfPoint();
            var contourWithMaxWidth = new VectorOfPoint();

            var maxArс   = 0.0;
            var maxArea  = 0.0;
            var maxWidth = 0.0;

            for (var i = 0; i < allContours.Size; i++)
            {
                var tempContour = allContours[i];

                var tempContourArс = CvInvoke.ArcLength(tempContour, true);
                if (tempContourArс > maxArс)
                {
                    maxArс            = tempContourArс;
                    contourWithMaxArc = tempContour;
                }

                var tempContourArea = CvInvoke.ContourArea(tempContour);
                if (tempContourArea > maxArea)
                {
                    maxArea            = tempContourArea;
                    contourWithMaxArea = tempContour;
                }

                var rect             = CvInvoke.MinAreaRect(tempContour);
                var box              = CvInvoke.BoxPoints(rect);
                var contourBoxPoint1 = new PointF(box[0].X, (float)cam.roiPosYSlider + box[0].Y);
                var contourBoxPoint2 = new PointF(box[1].X, (float)cam.roiPosYSlider + box[1].Y);
                var contourBoxPoint4 = new PointF(box[3].X, (float)cam.roiPosYSlider + box[3].Y);
                var side1            = MeasureService.FindDistance(contourBoxPoint1, contourBoxPoint2);
                var side2            = MeasureService.FindDistance(contourBoxPoint4, contourBoxPoint1);
                var tempContourWidth = side1 < side2
                                           ? side1
                                           : side2;
                if (tempContourWidth > maxWidth)
                {
                    maxWidth            = tempContourWidth;
                    contourWithMaxWidth = tempContour;
                }
            }

            if (workingMode == DetectionServiceWorkingMode.Crossing ||
                maxArс >= minDartContourArc &&
                maxArс <= maxDartContourArc &&
                maxArea >= minDartContourArea &&
                maxArea <= maxDartContourArea &&
                maxWidth >= minDartContourWidth &&
                maxWidth <= maxDartContourWidth &&
                contourWithMaxArc.Equals(contourWithMaxArea) &&
                contourWithMaxArea.Equals(contourWithMaxWidth) &&
                contourWithMaxWidth.Equals(contourWithMaxArc)
                )
            {
                return(MovesDetectionResult.Throw);
            }

            if (maxArс > maxDartContourArc ||
                maxArea > maxDartContourArea ||
                maxWidth > maxDartContourWidth)
            {
                return(MovesDetectionResult.Extraction);
            }

            return(MovesDetectionResult.Nothing);
        }