Пример #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 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);
        }
        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));
        }