Exemplo n.º 1
0
        /// <summary>
        /// Creates a new ImageDetection from a given image, set of points and values. It also populates it with <see cref="ObjectPhotometry"/>, <see cref="ObjectPoints"/>,
        /// and <see cref="ObjectSize"/> properties.
        /// </summary>
        /// <param name="Image">Image on which the object was detected.</param>
        /// <param name="Points">The set of points on the image where it has been detected.</param>
        /// <param name="Values">The set of pixel intensitities.</param>
        /// <returns>A new instance of ImageDetection with the specified extension properties.</returns>
        public static ImageDetection CreateDetection(Image Image, IEnumerable <PixelPoint> Points, IEnumerable <double> Values)
        {
            IWCSProjection Transform = Image.Transform;

            PixelPoint[]      PixPoints        = Points.ToArray();
            double[]          PixValues        = Values.ToArray();
            EquatorialPoint[] EquatorialPoints = Transform.GetEquatorialPoints(PixPoints);

            double Xmean = 0, Ymean = 0;
            double XXP = 0, XYP = 0, YYP = 0;
            double XXB = 0, XYB = 0, YYB = 0;
            double Flux = 0;
            double XBmean = 0, YBmean = 0;

            for (int i = 0; i < PixPoints.Length; i++)
            {
                PixelPoint pt  = PixPoints[i];
                double     Val = PixValues[i];
                Xmean  += pt.X; Ymean += pt.Y;
                XBmean += Val * pt.X; YBmean += Val * pt.Y;
                XXB    += pt.X * pt.X * Val; XYB += pt.X * pt.Y * Val; YYB += pt.Y * pt.Y * Val;
                XXP    += pt.X * pt.X; XYP += pt.X * pt.Y; YYP += pt.Y * pt.Y;
                Flux   += Val;
            }
            Xmean  /= PixPoints.Length; Ymean /= PixPoints.Length;
            XBmean /= Flux; YBmean /= Flux; XXB /= Flux; XYB /= Flux; YYB /= Flux;
            XXP    /= PixPoints.Length; XYP /= PixPoints.Length; YYP /= PixPoints.Length;
            XXB    -= XBmean * XBmean; XYB -= XBmean * YBmean; YYB -= YBmean * YBmean;
            XXP    -= Xmean * Xmean; XYP -= Xmean * Ymean;     YYP -= Ymean * Ymean;

            PixelPoint BarycenterPP = new PixelPoint()
            {
                X = XBmean, Y = YBmean
            };
            EquatorialPoint BarycenterEP = Transform.GetEquatorialPoint(BarycenterPP);
            Position        Pos          = new Position(BarycenterEP, BarycenterPP);

            SourceEllipse BarycentricEllipse = new SourceEllipse(XXB, XYB, YYB);
            SourceEllipse PixelEllipse       = new SourceEllipse(XXP, XYP, YYP);

            ObjectSize Shape = new ObjectSize()
            {
                BarycentricEllipse = BarycentricEllipse, PixelEllipse = PixelEllipse
            };

            ImageDetection Detection = new ImageDetection(Pos, Image.GetProperty <ObservationTime>(), Image);

            Detection.AppendProperty(Shape);
            Detection.AppendProperty(new ObjectPhotometry()
            {
                Flux = Flux
            });
            Detection.AppendProperty(new ObjectPoints()
            {
                PixelPoints = PixPoints, PixelValues = PixValues, EquatorialPoints = EquatorialPoints
            });
            return(Detection);
        }
Exemplo n.º 2
0
        public bool PairPossible(ImageDetection a, ImageDetection b)
        {
            PairingProperties App = a.FetchOrCreate <PairingProperties>(), Bpp = b.FetchOrCreate <PairingProperties>();

            if (App.IsPaired || Bpp.IsPaired)
            {
                return(false);
            }
            if (App.StarPolluted || Bpp.StarPolluted)
            {
                return(false);
            }
            if (a.Time.Time == b.Time.Time)
            {
                return(false);
            }
            TimeSpan DeltaTime = a.Time.Time - b.Time.Time;
            //if ((a.LargestDistance + b.LargestDistance) * Math.Abs(DeltaTime.TotalSeconds) < (a.Barycenter.EP ^ b.Barycenter.EP) * (a.Time.Exposure.TotalSeconds + b.Time.Exposure.TotalSeconds) / 2) return false;

            SourceEllipse aPel = a.FetchProperty <ObjectSize>().PixelEllipse, bPel = b.FetchProperty <ObjectSize>().PixelEllipse;

            if (aPel.SemiaxisMajor > LongTrailHighThreshold * LongTrailHighThreshold)
            {
                if (bPel.SemiaxisMajor < LongTrailLowThreshold * LongTrailLowThreshold)
                {
                    return(false);
                }
            }
            double DeltaAngle = aPel.SemiaxisMajorAngle - bPel.SemiaxisMajorAngle;
            double Length     = aPel.SemiaxisMajor + bPel.SemiaxisMajor;

            if (DeltaAngle * DeltaAngle * Math.Sqrt(Length) > AngleDistanceDifferenceThreshold)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 3
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;
            }
        }