Esempio n. 1
0
        public void Detect()
        {
            _progressFactor = 0.5f;
            _progressOffset = 0f;
            Helpers.FillOutsideBlack(_bmpWhite, _fullSurface);

            var corners = Recognition.DetectSurface(_bmpWhite);

            if (corners == null)
            {
                throw new Exception("Corner detection failed.");
            }
            corners = Calculations.SortCorners(corners);
            Helpers.SaveImageWithMarkers(_bmpWhite, corners, Path.Combine(Helpers.TempDir, $"detect_white{Index}.png"), 5);

            Helpers.FillOutsideBlack(_bmpPattern, corners);

            _progressOffset = 0.5f;
            _detectedCorner = corners.Select(p => new PointF(p.X, p.Y)).ToArray();
            var eckenSoll = new[] {
                new PointF(0, 0),
                new PointF(_resolution.Width - 1, 0),
                new PointF(_resolution.Width - 1, _resolution.Height - 1),
                new PointF(0, _resolution.Height - 1)
            };
            var transformationMatrix = Tools.Homography(_detectedCorner, eckenSoll);

            var shapes = DetectShapes(ControlPoints.Count, _bmpPattern, 5, _patternSize);

            if (shapes.Count != ControlPoints.Count)
            {
                throw new Exception("Not all shapes detected");
            }
            var pointsF = shapes.Select(s => new PointF(s.Blob.CenterOfGravity.X, s.Blob.CenterOfGravity.Y)).ToArray();

            //var pointsF = points.Select(p => new PointF(p.X, p.Y)).ToArray();
            Helpers.SaveImageWithMarkers(_bmpPattern, pointsF.Select(p => new IntPoint((int)p.X, (int)p.Y)).ToArray(), Path.Combine(Helpers.TempDir, $"detect_pattern{Index}.png"), 2);
            var transformedPoints = transformationMatrix.TransformPoints(pointsF);

            for (var i = 0; i < shapes.Count; i++)
            {
                shapes[i].TransformedPoint = transformedPoints[i];
            }

            MapDetectedPointsToControlPoints(shapes);
        }
Esempio n. 2
0
        private List <Shape> DetectShapes(int count, Bitmap image, int minSize, int maxSize)
        {
            var blobCounter = new AForge.Imaging.BlobCounter();

            AForge.Imaging.Blob[] blobs;
            blobCounter.FilterBlobs = true;
            blobCounter.MaxHeight   = maxSize;
            blobCounter.MaxWidth    = maxSize;
            blobCounter.MinHeight   = minSize;
            blobCounter.MinWidth    = minSize;
            var threshold = Recognition.GetThreshold(image);

            blobCounter.BackgroundThreshold = Color.FromArgb(255, threshold, threshold, threshold);
            blobCounter.ProcessImage(image);
            blobs = blobCounter.GetObjectsInformation();

            if (blobs.Length == count)
            {
                DetectShapesProgress?.Invoke(1f);
            }
            else
            {
                threshold = GetOptimizedThreshold(count, image, minSize, maxSize);
                blobCounter.BackgroundThreshold = Color.FromArgb(255, threshold, threshold, threshold);
                blobCounter.ProcessImage(image);
                blobs = blobCounter.GetObjectsInformation();
            }

            var shapes = new List <Shape>();

            foreach (var blob in blobs)
            {
                var edgePoints = blobCounter.GetBlobsEdgePoints(blob);
                // FindQuadrilateralCorners:
                // The first point in the list is the point with lowest X coordinate
                // (and with lowest Y if there are several points with the same X value).
                // The corners are provided in counter clockwise order
                var corners = PointsCloud.FindQuadrilateralCorners(edgePoints);

                shapes.Add(new Shape(corners.ToArray(), blob));
            }

            return(shapes);
        }
Esempio n. 3
0
        public void Detect(Rectangle clippingRectangle, bool keepCorners)
        {
            var clippingRectangleCorners = new[]
            {
                new IntPoint(clippingRectangle.X, clippingRectangle.Y),
                new IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y),
                new IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y + clippingRectangle.Height),
                new IntPoint(clippingRectangle.X, clippingRectangle.Y + clippingRectangle.Height)
            };

            Helpers.FillOutsideBlack(_bmpWhite, clippingRectangleCorners);
            var corners = Recognition.DetectSurface(_bmpWhite);

            if (corners == null)
            {
                throw new Exception("Corner detection failed.");
            }
            corners = Calculations.SortCorners(corners);
            Helpers.SaveImageWithMarkers(_bmpWhite, corners, Path.Combine(Helpers.TempDir, "detect_white.png"), 5);

            tasks.Parallel.ForEach(_projectors, p => {
                p.ClippingRectangle = clippingRectangle;
                p.SetFullSurface(corners);
                p.Detect();
                foreach (var cp in p.ControlPoints.Where(
                             point => point.ControlPointType != ControlPointType.IsEcke && point.AssociatedPoint != null))
                {
                    cp.ControlPointType = ControlPointType.IsFix;
                }
            });

            var scaleX0 = _projectors[0].Resolution.Width /
                          ((_projectors[0].DetectedCorners[1].X - _projectors[0].DetectedCorners[0].X +
                            _projectors[0].DetectedCorners[2].X - _projectors[0].DetectedCorners[3].X) / 2f);
            var scaleX1 = _projectors[1].Resolution.Width /
                          ((_projectors[1].DetectedCorners[1].X - _projectors[1].DetectedCorners[0].X +
                            _projectors[1].DetectedCorners[2].X - _projectors[1].DetectedCorners[3].X) / 2f);
            var scaleY0 = _projectors[0].Resolution.Height /
                          ((_projectors[0].DetectedCorners[3].Y - _projectors[0].DetectedCorners[0].Y +
                            _projectors[0].DetectedCorners[2].Y - _projectors[0].DetectedCorners[1].Y) / 2f);
            var scaleY1 = _projectors[1].Resolution.Height /
                          ((_projectors[1].DetectedCorners[3].Y - _projectors[1].DetectedCorners[0].Y +
                            _projectors[1].DetectedCorners[2].Y - _projectors[1].DetectedCorners[1].Y) / 2f);

            var scaleX = (scaleX0 + scaleX1) / 2f;
            var scaleY = (scaleY0 + scaleY1) / 2f;

            CalculateAdjustments(scaleX, scaleY);
            if (!keepCorners)
            {
                CalibrateCorners(scaleX, scaleY);
            }
            // TODO Marco: müssen Kontrollpunkte in einer Linie ausgerichtet werden? Wie?
            CalculateBlackLevelRegion();

            tasks.Parallel.ForEach(_projectors, p => {
                p.InterpolateControlPoints();
                p.InterpolateBlacklevelControlPoints();
            });

            var bmp = new Bitmap(_bmpWhite.Height * 3, _bmpWhite.Height);

            using (var g = Graphics.FromImage(bmp))
            {
                g.Clear(Color.Black);
                foreach (var cp in _projectors[0].ControlPoints)
                {
                    if (cp.AssociatedPoint == null)
                    {
                        continue;
                    }
                    g.FillCircle(Brushes.Red, cp.X, cp.Y, 10);
                    g.FillCircle(Brushes.Orange, cp.X, cp.Y, 10);
                }
            }
            bmp.Save(Path.Combine(Helpers.TempDir, "calib.png"));
        }