/// <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); }
/// <summary> /// Creates a tracklet from a set of detections. /// </summary> /// <param name="Detections">Input detections; one per image.</param> /// <returns>A new Tracklet instance.</returns> public static Tracklet CreateTracklet(ImageDetection[] Detections) { long[] Ticks = Detections.Select((x) => x.Time.Time.Ticks).ToArray(); Array.Sort(Ticks, Detections); EquatorialPoint[] ValidEP = new EquatorialPoint[Detections.Length]; double[] ValidTimes = new double[Detections.Length]; DateTime ZeroTime = Detections[0].Time.Time; WCS.IWCSProjection Projection = Detections[0].ParentImage.Transform; for (int i = 0; i < Detections.Length; i++) { ValidEP[i] = Detections[i].Barycenter.EP; ValidTimes[i] = (Detections[i].Time.Time - ZeroTime).TotalSeconds; } var XRA = ValidEP.Select((x) => x.RA).ToArray(); var XDec = ValidEP.Select((x) => x.Dec).ToArray(); var RAreg = LinearRegression.ComputeLinearRegression(ValidTimes, XRA); var Decreg = LinearRegression.ComputeLinearRegression(ValidTimes, XDec); var RADecreg = LinearRegression.ComputeLinearRegression(XRA, XDec); double ResRA = LineFit.ComputeResidualSqSum(RAreg, ValidTimes, XRA); double ResDec = LineFit.ComputeResidualSqSum(Decreg, ValidTimes, XDec); EquatorialVelocity ev = new EquatorialVelocity() { RAvel = RAreg.Slope, Decvel = Decreg.Slope }; TrackletVelocityRegression tvr = new TrackletVelocityRegression() { R_TR = RAreg.PearsonR, R_TD = Decreg.PearsonR, R_RD = RADecreg.PearsonR, S_TR = ResRA, S_TD = ResDec, ZeroTime = ZeroTime, P_TD = Decreg, P_TR = RAreg }; TrackletVelocity tvel = new TrackletVelocity() { EquatorialVelocity = ev, PixelVelocity = Projection.GetPixelVelocity(ev), SphericalVelocity = Math.Sqrt(ev.Decvel * ev.Decvel + ev.RAvel * ev.RAvel * Math.Cos(XRA[0]) * Math.Cos(XRA[0])) }; return(new Tracklet(Detections, tvel, tvr)); }
/// <summary>Creates a new instance of given equatorial coordinates and image coordinates.</summary> /// <param name="EqPoint">Equatorial coordinates.</param> /// <param name="PixPoint">Image coordinates.</param> public Position(EquatorialPoint EqPoint, PixelPoint PixPoint) { EP = EqPoint; PP = PixPoint; }