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 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(); } } } }
public void SetManuallyIdentifiedHints(Dictionary <PSFFit, IStar> manuallyIdentifiedStars) { m_ManualStarMatch = new Dictionary <StarMapFeature, IStar>(); foreach (PSFFit fit in manuallyIdentifiedStars.Keys) { StarMapFeature feature = m_StarMap.GetFeatureInRadius((int)fit.XCenter, (int)fit.YCenter, 2); if (feature != null && !m_ManualStarMatch.ContainsKey(feature)) { m_ManualStarMatch.Add(feature, manuallyIdentifiedStars[fit]); } } }
public override void MouseMove(Point location) { IStarMap map = AstrometryContext.Current.StarMap; if (map == null) { return; } bool nearbyStarFound = false; AstrometricState state = AstrometryContext.Current.AstrometricState; if (state != null) { if (state.AstrometricFit != null) { for (int radius = 1; radius < 8; radius++) { ImagePixel centroid = map.GetCentroid(location.X, location.Y, radius); if (centroid == null) { continue; } foreach (PlateConstStarPair star in state.AstrometricFit.FitInfo.AllStarPairs) { if (Math.Abs(star.x - centroid.XDouble) < radius && Math.Abs(star.y - centroid.YDouble) < radius) { m_Object = star; nearbyStarFound = true; break; } } if (nearbyStarFound) { break; } } if (!nearbyStarFound) { m_State = SelectObjectState.NoObject; } else { m_State = SelectObjectState.ObjectLocked; } if (m_AstrometricState.MeasuringState == AstrometryInFramesState.Ready) { double ra, de; state.AstrometricFit.GetRADEFromImageCoords(location.X, location.Y, out ra, out de); string moreInfo = string.Format("RA={0} DE={1}", AstroConvert.ToStringValue(ra / 15, "HHhMMmSS.Ts"), AstroConvert.ToStringValue(de, "+DD°MM'SS\"")); m_VideoController.DisplayCursorPositionDetails(location, moreInfo); } } else { StarMapFeature nearbyFeature = map.GetFeatureInRadius(location.X, location.Y, 8); nearbyStarFound = nearbyFeature != null && nearbyFeature.PixelCount > 4; } m_VideoController.SetPictureBoxCursor(nearbyStarFound ? Cursors.Hand : (state.ManualStarIdentificationMode ? Cursors.Cross : Cursors.Default)); } }
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); } }
protected void ResetPreviousStar() { m_PreviousStar = null; m_PreviousFeature = null; }
public override void MouseMove(Point location) { bool dirty = false; int posX = location.X < 16 ? 16 : (location.X > TangraContext.Current.FrameWidth - 17 ? TangraContext.Current.FrameWidth - 17 : location.X); int posY = location.Y < 16 ? 16 : (location.Y > TangraContext.Current.FrameHeight - 17 ? TangraContext.Current.FrameHeight - 17 : location.Y); m_VideoController.DisplayCursorPositionDetails(location); m_SelectedCalibrationStar = null; if (!m_Panning) { if (m_Is3StarIdMode) { StarMapFeature closestFeature = AstrometryContext.Current.StarMap.GetFeatureInRadius(posX, posY, 2); if (closestFeature != null) { if (m_Is3StarIdMode) { m_VideoController.SetPictureBoxCursor(Cursors.Hand); PSFFit psfFit; AstrometryContext.Current.StarMap.GetPSFFit(posX, posY, 13, out psfFit); m_SelectedCalibrationStar = psfFit; } } else { m_VideoController.SetPictureBoxCursor(Cursors.Arrow); } } else { m_VideoController.SetPictureBoxCursor(CustomCursors.PanCursor); } } else if (m_Panning && m_StarPoint != Point.Empty) { ResetPreviousStar(); if (m_SolvedPlate != null) { double raDeg1, deDeg1, raDeg2, deDeg2; m_SolvedPlate.GetRADEFromImageCoords(location.X, location.Y, out raDeg1, out deDeg1); m_SolvedPlate.GetRADEFromImageCoords(m_StarPoint.X, m_StarPoint.Y, out raDeg2, out deDeg2); double ra = m_RADegCenter + (raDeg2 - raDeg1); double de = m_DEDegCenter + (deDeg2 - deDeg1); if (m_SolvedPlate is LeastSquareFittedAstrometry) { m_SolvedPlate = new LeastSquareFittedAstrometry(m_Image, ra, de, null /*m_SolvePlateConts*/); } else if (m_SolvedPlate is TangentalTransRotAstrometry) { m_SolvedPlate = new TangentalTransRotAstrometry(m_SolvedPlate as TangentalTransRotAstrometry, m_Image, ra, de, m_Eta); } else { m_SolvedPlate = new DirectTransRotAstrometry(m_Image, ra, de, m_Eta, m_Aspect); } } dirty = true; } if (dirty) { DrawCatalogStarsFit(); } }
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(); }
public PlateConstStarPair AddStar(ImagePixel plateStar, IStar celestialPyramidStarEntry, StarMapFeature feature) { double detectionCertainty = plateStar.SignalNoise; PlateConstStarPair starPair = AddStar( plateStar.XDouble, celestialPyramidStarEntry.RADeg, plateStar.YDouble, celestialPyramidStarEntry.DEDeg, celestialPyramidStarEntry.Mag, plateStar.Brightness, detectionCertainty, plateStar.IsSaturated); #if ASTROMETRY_DEBUG Trace.Assert(m_Pairs.Find((pair) => pair.StarNo == celestialPyramidStarEntry.StarNo) == null); #endif starPair.StarNo = celestialPyramidStarEntry.StarNo; starPair.FeatureId = feature != null ? feature.FeatureId : -1; starPair.RADeg = celestialPyramidStarEntry.RADeg; starPair.DEDeg = celestialPyramidStarEntry.DEDeg; return(starPair); }
/// <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 }