public override void MouseClick(ObjectClickEventArgs e) { if (m_State == FittingsState.Configuring) { m_OSDExcluderTool.MouseClick(e); } if (m_State == FittingsState.Solved) { IStarMap starMap = AstrometryContext.Current.StarMap; if (starMap != null) { int x, y; StarMapFeature feature = starMap.GetFeatureInRadius(e.Pixel.X, e.Pixel.Y, 5); if (feature != null) { x = feature.GetCenter().X; y = feature.GetCenter().Y; } else { x = e.Pixel.X; y = e.Pixel.Y; } int searchArea = Control.ModifierKeys == Keys.Shift ? 5 : 10; PSFFit psfFit; ImagePixel pixelCent = starMap.GetPSFFit(x, y, searchArea, out psfFit); if (pixelCent != null && pixelCent != ImagePixel.Unspecified) { PlateConstStarPair selectedPair = null; LeastSquareFittedAstrometry astrometry = FittedAstrometryFromUserSelectedFitGrade(); if (astrometry != null) { foreach (PlateConstStarPair pair in astrometry.FitInfo.AllStarPairs) { if (Math.Abs(pair.x - pixelCent.X) < 2 && Math.Abs(pair.y - pixelCent.Y) < 2) { selectedPair = pair; break; } } } DrawHighResFeature(pixelCent, selectedPair, astrometry); } else { ClearZoomImage(); } } } }
protected virtual void IdentifyStar(StarMapFeature feature, IStar star) { if (m_SolvedPlate != null) { ImagePixel featureCenter = feature.GetCenter(); if (m_PreviousStar == null || m_PreviousStar.StarNo == star.StarNo) { // Translation only double x, y; m_SolvedPlate.GetImageCoordsFromRADE(star.RADeg, star.DEDeg, out x, out y); double newCenterX = m_Image.FullFrame.Width / 2 - featureCenter.X + x; double newCenterY = m_Image.FullFrame.Height / 2 - featureCenter.Y + y; m_SolvedPlate.GetRADEFromImageCoords(newCenterX, newCenterY, out m_RADegCenter, out m_DEDegCenter); m_PreviousFeature = feature; m_PreviousStar = star; } else { // TODO: Rotate and streach until the feature fits } ReinitializePlateConstants(); DrawCatalogStarsFit(); // TODO: For now we only support 1 star centering m_PreviousStar = null; m_PreviousStar = null; } }
public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit) { IsTrackedSuccessfully = false; int searchRadius = (int)Math.Ceiling(Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius)); PSFFit psfFit = null; int startingX = (int)TrackedObject.LastKnownX; int startingY = (int)TrackedObject.LastKnownY; if (m_RepeatedIntergationPositions * 4 < m_PastFrameNos.Count) { var expectedPos = GetExpectedPosition(frameNo); if (expectedPos != null) { startingX = expectedPos.X; startingY = expectedPos.Y; } } var nearbyFeatures = starMap.GetFeaturesInRadius(startingX, startingY, searchRadius).ToArray(); var nonStarNearbyFeature = new List <StarMapFeature>(); foreach (var feature in nearbyFeatures) { var center = feature.GetCenter(); var referenceStarFeatures = astrometricFit.FitInfo.AllStarPairs.Where(x => x.FitInfo.UsedInSolution).ToList(); var refStar = referenceStarFeatures.FirstOrDefault(s => Math.Sqrt((s.x - center.X) * (s.x - center.X) + (s.y - center.Y) * (s.y - center.Y)) < 2); double raf, def; astrometricFit.GetRADEFromImageCoords(center.XDouble, center.YDouble, out raf, out def); var pastKnownStar = m_LastFrameStars.FirstOrDefault(s => AngleUtility.Elongation(s.RADeg, s.DEDeg, raf, def) * 3600.0 < 2); if (refStar == null && pastKnownStar == null) { nonStarNearbyFeature.Add(feature); } } if (nonStarNearbyFeature.Count > 0) { StarMapFeature closestFeature = nonStarNearbyFeature[0]; var lastKnownCenter = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY); var smallestDistance = lastKnownCenter.DistanceTo(closestFeature.GetCenter()); for (int i = 1; i < nonStarNearbyFeature.Count; i++) { var distance = lastKnownCenter.DistanceTo(nonStarNearbyFeature[i].GetCenter()); if (distance < smallestDistance) { smallestDistance = distance; closestFeature = nonStarNearbyFeature[i]; } } if (closestFeature != null) { var center = closestFeature.GetCenter(); AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit); } } if (psfFit == null) { // The expected location cannot be matched with any brighter feature so it is likely a faint object // with no brighter objects around. Lets find the brightest (faint) object in the are and use it ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(startingX, startingY, searchRadius); if (centroid != null) { AstrometryContext.Current.StarMap.GetPSFFit(centroid.X, centroid.Y, PSFFittingMethod.NonLinearFit, out psfFit); } } if (psfFit != null) { double ra, de; astrometricFit.GetRADEFromImageCoords(psfFit.XCenter, psfFit.YCenter, out ra, out de); double maxPosDiffArcSec = astrometricFit.GetDistanceInArcSec(astrometricFit.Image.CenterXImage, astrometricFit.Image.CenterYImage, astrometricFit.Image.CenterXImage + Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.MaxAllowedDefaultMotionInPixels), astrometricFit.Image.CenterYImage); if (!double.IsNaN(TrackedObject.RAHours)) { double posDif = 3600 * AngleUtility.Elongation(15 * TrackedObject.RAHours, TrackedObject.DEDeg, ra, de); if (posDif > maxPosDiffArcSec) { // NOTE: Not a valid measurement Trace.WriteLine(string.Format("The target position is too far from the last measured position", posDif)); return; } } TrackedObject.RAHours = ra / 15.0; TrackedObject.DEDeg = de; if (TrackedObject.PSFFit != null) { m_LastMovementPixels = 1.2 * ImagePixel.ComputeDistance(TrackedObject.LastKnownX, psfFit.XCenter, TrackedObject.LastKnownY, psfFit.YCenter); } TrackedObject.LastKnownX = psfFit.XCenter; TrackedObject.LastKnownY = psfFit.YCenter; TrackedObject.PSFFit = psfFit; var lastKnownCenter = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY); var thisFrameStars = astrometricFit.FitInfo.AllStarPairs.Where(x => lastKnownCenter.DistanceTo(x.x, x.y) > 2 * psfFit.FWHM).ToList(); if (thisFrameStars.Count > 0) { m_LastFrameStars = thisFrameStars.Select(x => new Star(x.StarNo, x.RADeg, x.DEDeg, x.Mag) as IStar).ToList(); } IsTrackedSuccessfully = true; } if (psfFit != null && psfFit.XCenter > 0 && psfFit.YCenter > 0) { m_PastFramePosX.Add(psfFit.XCenter); m_PastFramePosY.Add(psfFit.YCenter); m_PastFrameNos.Add(frameNo); } }
public override void PostDraw(Graphics g) { if (m_CatalogueStars == null) { if (AstrometryContext.Current.StarMap != null) { foreach (StarMapFeature feature in AstrometryContext.Current.StarMap.Features) { ImagePixel center = feature.GetCenter(); g.DrawEllipse(Pens.Red, center.X - 2, center.Y - 2, 5, 5); } } } else if (m_CatalogueStars != null && m_State == FittingsState.Configuring) { if (m_SolvedPlate != null && m_PlateCalibrator.ConstantsSolver != null) { foreach (IStar star in m_CatalogueStars) { if (star.Mag > m_LimitMag) { continue; } double x, y; m_SolvedPlate.GetImageCoordsFromRADE(star.RADeg, star.DEDeg, out x, out y); PlateConstStarPair pair = m_PlateCalibrator.ConstantsSolver.Pairs.FirstOrDefault((p) => p.StarNo == star.StarNo); Pen starPen = catalogStarPen; if (pair == null) { starPen = rejectedStarPen; } else if (!pair.FitInfo.ExcludedForHighResidual) { starPen = referenceStarPen; if (AstrometryContext.Current.StarMap != null) { StarMapFeature feature = AstrometryContext.Current.StarMap.Features.FirstOrDefault((f) => f.FeatureId == pair.FeatureId); if (feature != null) { g.DrawLine(Pens.Beige, (float)x, (float)y, (float)feature.GetCenter().XDouble, (float)feature.GetCenter().YDouble); } } } g.DrawLine(starPen, (float)x - 3, (float)y, (float)x + 3, (float)y); g.DrawLine(starPen, (float)x, (float)y - 3, (float)x, (float)y + 3); } } } else { DrawCatalogStarsFit(g); } g.Save(); }
/// <summary> /// Used to calibrate a plate. Does the more precise astrometric fit /// Precondition: A coarser (m_PreliminaryFit) is required where the user has visually roughly fitted the stars to the plate /// </summary> /// <param name="limitMag">The faintest magnitude of a star to be used for the fit</param> /// <param name="fineFit">Used to determine the search area for the stars. When the fit is not a 'fine' fit then 2.5 times /// larger are is used for the fit</param> public bool SolvePlateConstantsPhase1(double limitMag, bool fineFit) { int searchDistance = 10; IAstrometricFit previousFit; if (!fineFit) { searchDistance = ((int)Math.Ceiling(2.5 * CoreAstrometrySettings.Default.SearchArea) + 1); previousFit = m_Context.PreliminaryFit; } else { searchDistance = (int)Math.Ceiling(CoreAstrometrySettings.Default.SearchArea) + 1; previousFit = m_Context.FirstAstrometricFit; } m_ConstantsSolver = new PlateConstantsSolver(m_Context.PlateConfig); // NOTE: Get the coordinates of the center of the plate. double ra0deg, de0Deg; previousFit.GetRADEFromImageCoords( m_Context.PlateConfig.CenterXImage, m_Context.PlateConfig.CenterYImage, out ra0deg, out de0Deg); m_ConstantsSolver.InitPlateSolution(ra0deg, de0Deg); #region PASS 1 - Only using the stars down to limitMag int idx = -1; foreach (IStar star in m_Context.FieldSolveContext.CatalogueStars) { idx++; double x, y; previousFit.GetImageCoordsFromRADE(star.RADeg, star.DEDeg, out x, out y); if (m_Context.FitExcludeArea.Contains((int)x, (int)y)) { continue; } if (x < 0 || x > m_Context.PlateConfig.ImageWidth || y < 0 || y > m_Context.PlateConfig.ImageHeight) { continue; } if (limitMag < star.Mag) { continue; } StarMapFeature feature = m_Context.StarMap.GetFeatureInRadius((int)x, (int)y, searchDistance); Trace.WriteLine(string.Format("Searching for {0} ({1:0.0} mag) at ({2:0.0},{3:0.0}).{4}Found!", star.GetStarDesignation(0), star.Mag, x, y, feature != null ? "" : "NOT ")); if (fineFit) { ImagePixel centroid = m_Context.StarMap.GetCentroid((int)x, (int)y, searchDistance); if (centroid != null) { if (centroid.SignalNoise >= m_AstrometrySettings.DetectionLimit) { if (!m_Context.FitExcludeArea.Contains(centroid.X, centroid.Y)) { // NOTE: Don't add a star if outside the selected area m_ConstantsSolver.AddStar(centroid, star, feature); } } } else { //Trace.WriteLine("m_SolvePlateConts.NoMatch:" + star.StarNo); } } else if (feature != null) { ImagePixel plateStar = feature.GetCenter(); if (!m_Context.FitExcludeArea.Contains(plateStar.X, plateStar.Y)) { // NOTE: Don't add a star if outside the selected area m_ConstantsSolver.AddStar(plateStar, star, feature); } } else { //Trace.WriteLine("m_SolvePlateConts.NoMatch:" + star.StarNo); } } // TODO: Shouldn't this be comming from the settings?? return(m_ConstantsSolver.Pairs.Count >= 4); #endregion }