示例#1
0
        /// <summary>
        /// Creates a mask from an image. All light sources are detected via a hysteresis algorithm and flagged in the mask.
        /// </summary>
        /// <param name="Input">Input image data.</param>
        /// <param name="Position">Data position in the image.</param>
        /// <param name="Properties">Bag of mask data.</param>
        static void GenerateMask(double[,] Input, ImageSegmentPosition Position, MaskProperties Properties)
        {
            int        Width = Input.GetLength(1);
            int        Height = Input.GetLength(0);
            int        i, j;
            PixelPoint pxp = new PixelPoint();

            /* Compute masking thresholds */
            double UpperThreshold = Properties.UTM * Properties.StDev + Properties.Mean;
            double LowerThreshold = Properties.LTM * Properties.StDev + Properties.Mean;

            for (i = 0; i < Height; i++)
            {
                for (j = 0; j < Width; j++)
                {
                    pxp.X = j + Position.Alignment.X;
                    pxp.Y = i + Position.Alignment.Y;

                    if (pxp.Y >= Properties.MaskData.Length)
                    {
                        break;
                    }
                    if (pxp.X >= Properties.MaskData[(int)pxp.Y].Length)
                    {
                        break;
                    }

                    if (Properties.MaskData[(int)pxp.Y][(int)pxp.X])
                    {
                        continue;
                    }

                    if (Input[i, j] > UpperThreshold)
                    {
                        BitmapFill(Properties.MaskData, Input, Position.Alignment, pxp, LowerThreshold, Properties.MaskRadiusMultiplier, Properties.ExtraMaskRadius, out Filtering.Star? Star);
                        if (Star != null)
                        {
                            Filtering.Star S = Star.Value; S.EqCenter = Position.WCS.GetEquatorialPoint(S.PixCenter); lock (Properties.StarList) Properties.StarList.FixedStarList.Add(S);
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Runs the hysteresis connected component detection algorithm for light sources. At the end also applies the extra circular masking.
        /// </summary>
        /// <param name="Mask">Mask array.</param>
        /// <param name="MaskData">Masking image data.</param>
        /// <param name="Alignment">Position of data in the image.</param>
        /// <param name="DPoint">Starting point for the connected component algorithm.</param>
        /// <param name="LowerThreshold">Lower hysteresis threshold.</param>
        /// <param name="RadiusMultiplier">Ratio between extra masking circle radius and light source radius.</param>
        /// <param name="ExtraRadius">Extra radius for the masking circle.</param>
        /// <param name="Star">The potential output star.</param>
        static void BitmapFill(BitArray[] Mask, double[,] MaskData, PixelPoint Alignment, PixelPoint DPoint, double LowerThreshold, double RadiusMultiplier, double ExtraRadius, out Filtering.Star?Star)
        {
            Queue <PixelPoint> PointQ = new Queue <PixelPoint>();

            PointQ.Enqueue(DPoint);

            double XMean = 0, YMean = 0, XSquare = 0, YSquare = 0, XY = 0;
            int    PCount = 0;
            double Flux   = 0;

            while (PointQ.Count > 0)
            {
                PixelPoint pt = PointQ.Dequeue();
                if (pt.X < 0 || pt.X >= Mask[0].Length)
                {
                    continue;
                }
                if (pt.Y < 0 || pt.Y >= Mask.Length)
                {
                    continue;
                }

                if (Mask[(int)pt.Y][(int)pt.X])
                {
                    continue;
                }

                double dX = pt.X - Alignment.X;
                double dY = pt.Y - Alignment.Y;
                dX = Math.Round(dX); dY = Math.Round(dY);
                if (dX < 0 || dX >= MaskData.GetLength(1))
                {
                    continue;
                }
                if (dY < 0 || dY >= MaskData.GetLength(0))
                {
                    continue;
                }

                if (MaskData[(int)dY, (int)dX] > LowerThreshold)
                {
                    Mask[(int)pt.Y][(int)pt.X] = true;
                    PointQ.Enqueue(new PixelPoint()
                    {
                        X = pt.X - 1, Y = pt.Y
                    });
                    PointQ.Enqueue(new PixelPoint()
                    {
                        X = pt.X + 1, Y = pt.Y
                    });
                    PointQ.Enqueue(new PixelPoint()
                    {
                        X = pt.X, Y = pt.Y - 1
                    });
                    PointQ.Enqueue(new PixelPoint()
                    {
                        X = pt.X, Y = pt.Y + 1
                    });
                    XMean   += pt.X; YMean += pt.Y;
                    XSquare += pt.X * pt.X; YSquare += pt.Y * pt.Y;
                    XY      += pt.X * pt.Y;
                    PCount++;
                    Flux += MaskData[(int)dY, (int)dX];
                }
            }

            /* Computes size of and shape of the light source */
            XMean   /= PCount;
            YMean   /= PCount;
            XSquare /= PCount;
            YSquare /= PCount;
            XY      /= PCount;
            XSquare -= XMean * XMean;
            YSquare -= YMean * YMean;
            XY      -= XMean * YMean;

            double        Radius = Math.Sqrt(XSquare + YSquare);
            SourceEllipse Shape  = new SourceEllipse(XSquare, XY, YSquare);

            /* If not to irregular, suppose it is a star and apply extra masking. */
            if (Shape.SemiaxisMajor < 3 * Shape.SemiaxisMinor)
            {
                FillMarginsExtra(Mask, new PixelPoint()
                {
                    X = XMean, Y = YMean
                }, Radius * RadiusMultiplier + ExtraRadius);
                Star = new Filtering.Star()
                {
                    Shape = Shape, PixCenter = new PixelPoint()
                    {
                        X = XMean, Y = YMean
                    }, PixRadius = Radius, Flux = Flux
                };
            }
            else
            {
                Star = null;
            }
        }