Ejemplo n.º 1
0
        public override bool CheckShape(CalibrationShape shape)
        {
            int cx = shape.GravityCenter.X.Round();
            int cy = shape.GravityCenter.Y.Round();
            int redCount = 0;

            for(int dx = -_r; dx <= _r; ++dx)
            {
                for(int dy= -_r; dy <= _r; ++dy)
                {
                    redCount = Image[cy + dy, cx + dx, (int)RGBChannel.Red] > _minRed ?
                        redCount + 1 : redCount;
                }
            }

            return redCount > _winSize * 0.75;
        }
Ejemplo n.º 2
0
        // 1) Move around the border and FF for each 'Unvisited', fill background ( dark ) with 'Background'
        // 2) During FF mark some white field and now start FF and fill light area with 'WhiteField'
        //    We assume white field is one big connected area ( with 'holes' for calibration shapes )
        // 3) If during WF some unvisited dark area is run into, FF it with 'Shape', create CalibrationShape
        //    for it and add its points, save index in pixel codes
        public override void FindCalibrationPoints()
        {
            //if(UseMedianFilter)
            //{
            //    // Preprocess with median filter to remove some noise (edges should stay in same place )
            //    MedianFilter filter = new MedianFilter();
            //    filter.FilterBorder = false;
            //    filter.Image = Image.ImageMatrix;
            //    filter.WindowRadius = MedianFilterRadius;
            //    ImageGray.ImageMatrix = filter.ApplyFilter();
            //}

            PrimaryShapeChecker.Image = Image;

            _pixelCodes = new DenseMatrix(Image.RowCount, Image.ColumnCount);
            CalibShapes = new List<CalibrationShape>(32);

            _whiteBorder = new List<TPoint2D<int>>();
            // Fill whole background first
            FillBackground();

            _currentShape = null;
            CalibShapes.Add(null); // Reserve slot for primary shape
            if(_whiteBorder.Count == 0)
            {
                // No white field detected -> error
                MessageBox.Show("No white field detected on calibration image: no calibration points can be found");
                return;
            }

            // Fill white field and shapes (inside FillWhiteField)
            FillWhiteField();
            if(CalibShapes[0] == null)
            {
                MessageBox.Show("No primary calibration shape (reddish) detected on calibration image: no calibration points can be found");
                return;
            }

            // Now find main white field ( one with primary shape ) and remove all shapes
            // not from this field
            uint primaryField = CalibShapes[0].Index;
            for(int i = 1; i < CalibShapes.Count;)
            {
                if(CalibShapes[i].Index != primaryField)
                {
                    CalibShapes.RemoveAt(i);
                    continue;
                }
                ++i;
            }

            // At this point CalibrationShapes should be created, so find its centers
            // and sort them to form grid
            FillCalibrationGrid();

            // From each valid shape from grid, create CalibrationPoint
            Points = new List<CalibrationPoint>();
            foreach(var shape in CalibGrid)
            {
                if(shape != null && !shape.IsInvalid)
                    Points.Add(new CalibrationPoint()
                    {
                        Img = shape.GravityCenter,
                        RealGridPos = shape.GridPos
                    });
            }

            ((ShapeGridLinesExtractor)LinesExtractor).CalibGrid = CalibGrid;
        }
Ejemplo n.º 3
0
        private void FindLocalAxes(out CalibrationShape shapeX, out CalibrationShape shapeY)
        {

            // Find calibration grid axes 
            // 1) Sort shapes by distance to primary shape
            CalibShapes.Sort((s1, s2) =>
            {
                // Compares distance of s1 and s2 to primary shape
                return (s1.GravityCenter - CalibShapes[0].GravityCenter).LengthSquared().CompareTo(
                     (s2.GravityCenter - CalibShapes[0].GravityCenter).LengthSquared());
            });

            // 2) Find direction vectors from PS to closest one and then find
            //    closest one with direction rotated by 90deg ( by comparing its dot product ->
            //    for 90deg its 0, having like 10deg tolerance we have :
            //    dot(A,B) / (|A||B|) = cos(a) < 0.17
            // Use 2 next closest ones
            shapeX = null;
            shapeY = null;
            Vector2 direction_1 = (CalibShapes[1].GravityCenter - CalibShapes[0].GravityCenter);
            direction_1.Normalise();
            shapeX = CalibShapes[1];

            //Vector2 direction_2 = direction_1;
            //int pointNum = 2;
            //for(; pointNum < CalibShapes.Count; ++pointNum)
            //{
            //    // Find direction and dot product
            //    direction_2 = (CalibShapes[pointNum].GravityCenter - CalibShapes[0].GravityCenter);
            //    direction_2.Normalise();

            //    if(Math.Abs(direction_1.CosinusTo(direction_2)) < 0.17)
            //    {
            //        // Found prependicular direction
            //        shapeY = CalibShapes[pointNum];
            //        break;
            //    }
            //}
            
            Vector2 direction_2 = (CalibShapes[2].GravityCenter - CalibShapes[0].GravityCenter);
            direction_2.Normalise();
            double cos2 = Math.Abs(direction_1.CosinusTo(direction_2));

            Vector2 direction_3 = (CalibShapes[3].GravityCenter - CalibShapes[0].GravityCenter);
            direction_3.Normalise();
            double cos3 = Math.Abs(direction_1.CosinusTo(direction_3));

            // Choose one with angle closer to 90deg (so cos closer to 0)
            direction_2 = cos2 < cos3 ? direction_2 : direction_3;
            shapeY = cos2 < cos3 ? CalibShapes[2] : CalibShapes[3];

            // Now depending on sign of sin(a), we can determine which axis is X and Y
            // Using cross-product of d1 and d2 ( casting it to 3d with z = 0 ) we have sin(a) = (d1.x * d2.y - d1.y * d2.x)
            // If sin(a) > 0, then d1 is local x axis, d2 is y
            if(direction_1.SinusTo(direction_2) > 0.0)
            {
                AxisX = direction_1;
                AxisY = direction_2;
            }
            else
            {
                AxisX = direction_2;
                AxisY = direction_1;

                var temp = shapeY;
                shapeY = shapeX;
                shapeX = temp;
            }
        }
Ejemplo n.º 4
0
        private void InitCalibrationGrid(CalibrationShape shapeX, CalibrationShape shapeY)
        {
            CalibGrid = new CalibrationGrid(4, 4);
            CalibGrid.Add(0, 0, CalibShapes[0]);
            CalibShapes.RemoveAt(0);

            CalibGrid.Add(0, 1, shapeX);
            CalibShapes.Remove(shapeX);

            CalibGrid.Add(1, 0, shapeY);
            CalibShapes.Remove(shapeY);
        }
Ejemplo n.º 5
0
 private void AddDummyShape(int x, int y, Vector2 eP)
 {
     CalibrationShape dummy = new CalibrationShape();
     dummy.GravityCenter = eP;
     dummy.IsInvalid = true;
     CalibGrid.Add(y, x, dummy);
 }
Ejemplo n.º 6
0
        void FillShape(int y, int x)
        {
            _flood = new IterativeBasicFloodAlgorithm();
            _flood.ImageHeight = Image.RowCount;
            _flood.ImageWidth = Image.ColumnCount;
            _flood.FillCondition = ShapeFillCondition;
            _flood.FillAction = ShapeFillAction;

            // Create new CalibrationShape and set index in pixelcodes
            _currentShape = new CalibrationShape();
            _currentShape.Index = (uint)_currentWhiteField;

            _pixelCodes[y, x] = CellCodeToFloat(CellCode.Unvisited);
            _flood.FloodFill(y, x);

            _currentShape.FindCenter();

            // Check if its primary shape -> should have very high red value
            if(PrimaryShapeChecker.CheckShape(_currentShape))
            {
                CalibShapes[0] = _currentShape;
            }
            else
            {
                CalibShapes.Add(_currentShape);
            }
        }
Ejemplo n.º 7
0
 public abstract bool CheckShape(CalibrationShape shape);