private void FindAndProcessDartContour(CamService cam)
        {
            var dartContour = TryFindDartContour(cam);

            if (dartContour != null)
            {
                var toDartRay = ProcessDartContour(cam, dartContour);
                throwService.SaveRay(toDartRay);
                Application.Current.Dispatcher.Invoke(() => { camsDetectionBoard.DrawRay(toDartRay); });
            }
        }
Exemplo n.º 2
0
        public void ProcessDartContour()
        {
            logger.Debug($"Process dartContour for cam_{camService.camNumber} start");
            // 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)camService.roiPosYSlider + box[0].Y);
            var contourBoxPoint2 = new PointF(box[1].X, (float)camService.roiPosYSlider + box[1].Y);
            var contourBoxPoint3 = new PointF(box[2].X, (float)camService.roiPosYSlider + box[2].Y);
            var contourBoxPoint4 = new PointF(box[3].X, (float)camService.roiPosYSlider + box[3].Y);

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

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

            // Find spikeLine to surface
            var spikeLinePoint1 = contourBoxMiddlePoint1;
            var spikeLinePoint2 = contourBoxMiddlePoint2;
            var spikeLineLength = camService.surfacePoint2.Y - contourBoxMiddlePoint2.Y;
            var spikeAngle      = 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 = FindLinesIntersection(spikeLinePoint1, spikeLinePoint2, camService.surfacePoint1, camService.surfacePoint2);

            // Translate cam surface POI to dartboard projection
            var frameWidth                    = camService.RoiLastThrowFrame.Cols;
            var frameSemiWidth                = frameWidth / 2;
            var camFovSemiAngle               = camFovAngle / 2;
            var projectionToCenter            = new PointF();
            var surfacePoiToCenterDistance    = FindDistance(camService.surfaceCenterPoint1, camPoi.GetValueOrDefault());
            var surfaceLeftToPoiDistance      = FindDistance(camService.surfaceLeftPoint1, camPoi.GetValueOrDefault());
            var surfaceRightToPoiDistance     = FindDistance(camService.surfaceRightPoint1, 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)(camService.setupPoint.X - Math.Cos(camService.toBullAngle) * projectionCamToCenterDistance);
            projectionToCenter.Y = (float)(camService.setupPoint.Y - Math.Sin(camService.toBullAngle) * projectionCamToCenterDistance);

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

            var projectionPoi = new PointF
            {
                X = (float)(camService.setupPoint.X + Math.Cos(camService.toBullAngle + poiCamCenterAngle) * 2000),
                Y = (float)(camService.setupPoint.Y + Math.Sin(camService.toBullAngle + poiCamCenterAngle) * 2000)
            };

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

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

            drawService.ProjectionDrawLine(camService.setupPoint, rayPoint, new Bgr(Color.DodgerBlue).MCvScalar);

            var ray = new Ray(camService.camNumber, camService.setupPoint, rayPoint, dartContour.Arc);

            throwService.SaveRay(ray);

            logger.Debug($"Process dartContour for cam_{camService.camNumber} end. Ray saved:{ray}");
        }