private void timer1_Tick(object sender, EventArgs e) { timer1.Enabled = false; StarMapInternalConfig starMapConfig = StarMapInternalConfig.Default; if (rbAuto.Checked) { starMapConfig.OptimumStarsInField = (int)TangraConfig.Settings.Astrometry.PyramidOptimumStarsToMatch; starMapConfig.StarMapperTolerance = 2; } else { starMapConfig.OptimumStarsInField = -1; starMapConfig.StarMapperTolerance = trbarDepth.Value; } var starMap = new StarMap(); var image = new AstroImage(m_InitialPixelmap); starMap.FindBestMap( starMapConfig, image, AstrometryContext.Current.OSDRectToExclude, AstrometryContext.Current.RectToInclude, AstrometryContext.Current.LimitByInclusion); AstrometryContext.Current.StarMap = starMap; AstrometryContext.Current.StarMapConfig = starMapConfig; m_VideoController.RedrawCurrentFrame(false, true, false); }
public void PlateSolve(PlateSolveTesterConfig config) { var pixelMap = new Pixelmap(config.Width, config.Height, config.BitPix, config.Pixels, null, null); var image = new AstroImage(pixelMap); StarMap starMap = new StarMap( TangraConfig.Settings.Astrometry.PyramidRemoveNonStellarObject, TangraConfig.Settings.Astrometry.MinReferenceStarFWHM, TangraConfig.Settings.Astrometry.MaxReferenceStarFWHM, TangraConfig.Settings.Astrometry.MaximumPSFElongation, TangraConfig.Settings.Astrometry.LimitReferenceStarDetection); Rectangle excludeRect = new Rectangle(config.OSDRectToExclude.X, config.OSDRectToExclude.Y, config.OSDRectToExclude.Width, config.OSDRectToExclude.Height); Rectangle includeRect = new Rectangle(config.RectToInclude.X, config.RectToInclude.Y, config.RectToInclude.Width, config.RectToInclude.Height); starMap.FindBestMap( StarMapInternalConfig.Default, image, excludeRect, includeRect, config.LimitByInclusion); var facade = new StarCatalogueFacade(TangraConfig.Settings.StarCatalogue); var catalogueStars = facade.GetStarsInRegion( config.RADeg, config.DEDeg, (config.ErrFoVs + 1.0) * config.PlateConfig.GetMaxFOVInArcSec() / 3600.0, config.LimitMagn, config.Epoch); var distBasedMatcher = new DistanceBasedAstrometrySolver( new MockedOperationNotifier(), config.PlateConfig, TangraConfig.Settings.Astrometry, catalogueStars, config.RADeg, config.DEDeg, config.DetermineAutoLimitMagnitude); distBasedMatcher.SetMinMaxMagOfStarsForAstrometry(config.PyramidMinMag, config.LimitMagn); distBasedMatcher.SetMinMaxMagOfStarsForPyramidAlignment(config.PyramidMinMag, config.PyramidMaxMag); distBasedMatcher.InitNewMatch(starMap, PyramidMatchType.PlateSolve, null); distBasedMatcher.InitNewFrame(starMap); distBasedMatcher.SetManuallyIdentifiedHints(new Dictionary <PSFFit, IStar>()); LeastSquareFittedAstrometry astrometricFit; PerformMatchResult result = distBasedMatcher.PerformMatch(out astrometricFit); }
public void PlateSolve(PlateSolveTesterConfig config) { var pixelMap = new Pixelmap(config.Width, config.Height, config.BitPix, config.Pixels, null, null); var image = new AstroImage(pixelMap); StarMap starMap = new StarMap( TangraConfig.Settings.Astrometry.PyramidRemoveNonStellarObject, TangraConfig.Settings.Astrometry.MinReferenceStarFWHM, TangraConfig.Settings.Astrometry.MaxReferenceStarFWHM, TangraConfig.Settings.Astrometry.MaximumPSFElongation, TangraConfig.Settings.Astrometry.LimitReferenceStarDetection); Rectangle excludeRect = new Rectangle(config.OSDRectToExclude.X, config.OSDRectToExclude.Y, config.OSDRectToExclude.Width, config.OSDRectToExclude.Height); Rectangle includeRect = new Rectangle(config.RectToInclude.X, config.RectToInclude.Y, config.RectToInclude.Width, config.RectToInclude.Height); starMap.FindBestMap( StarMapInternalConfig.Default, image, excludeRect, includeRect, config.LimitByInclusion); var facade = new StarCatalogueFacade(TangraConfig.Settings.StarCatalogue); var catalogueStars = facade.GetStarsInRegion( config.RADeg, config.DEDeg, (config.ErrFoVs + 1.0) * config.PlateConfig.GetMaxFOVInArcSec() / 3600.0, config.LimitMagn, config.Epoch); var distBasedMatcher = new DistanceBasedAstrometrySolver( new MockedOperationNotifier(), config.PlateConfig, TangraConfig.Settings.Astrometry, catalogueStars, config.DetermineAutoLimitMagnitude); distBasedMatcher.SetMinMaxMagOfStarsForAstrometry(config.PyramidMinMag, config.LimitMagn); distBasedMatcher.SetMinMaxMagOfStarsForPyramidAlignment(config.PyramidMinMag, config.PyramidMaxMag); distBasedMatcher.InitNewMatch(starMap, PyramidMatchType.PlateSolve, null); distBasedMatcher.InitNewFrame(starMap); distBasedMatcher.SetManuallyIdentifiedHints(new Dictionary<PSFFit, IStar>()); LeastSquareFittedAstrometry astrometricFit; PerformMatchResult result = distBasedMatcher.PerformMatch(out astrometricFit); }
protected void InitStarMap() { var starMap = new StarMap(); AstroImage image = m_VideoController.GetCurrentAstroImage(false); starMap.FindBestMap( AstrometryContext.Current.StarMapConfig, image, AstrometryContext.Current.OSDRectToExclude, AstrometryContext.Current.RectToInclude, AstrometryContext.Current.LimitByInclusion); AstrometryContext.Current.StarMap = starMap; #if ASTROMETRY_DEBUG Trace.Assert(AstrometryContext.Current.StarMap != null); Trace.Assert(AstrometryContext.Current.StarMap.Features.Count > 0); #endif }
public bool InitializeNewTracking(IAstroImage astroImage) { m_StarMapConfig = new StarMapInternalConfig(StarMapInternalConfig.Default); m_StarMapConfig.CustomMaxSignalValue = astroImage.GetPixelmapPixels().Max(); m_StarMapConfig.CustomOptimumStarsValue = 25; m_StarMapConfig.IsFITSFile = true; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count < 10) { MessageBox.Show("Cannot initialize object tracking as less than 10 stars can be identified in the field"); return(false); } // Build a signature of the largest 10 features (pivots) m_PivotDistances.Clear(); for (int i = 0; i < 10; i++) { m_PivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES)); } double fwhmSum = 0; int fwhmCount = 0; starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); for (int i = 0; i < 10; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < 10; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); m_PivotDistances[i][j] = distance; m_PivotDistances[j][i] = distance; } int x0 = feature_i.GetCenter().X; int y0 = feature_i.GetCenter().Y; PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { fwhmSum += fit.FWHM; fwhmCount++; } } m_FWHMAverage = (float)(fwhmSum / fwhmCount); for (int i = 0; i < m_TrackedObjects.Count; i++) { m_TrackedObjectsPivotDistancesX[i] = new List <double>(); m_TrackedObjectsPivotDistancesY[i] = new List <double>(); for (int j = 0; j < 10; j++) { m_TrackedObjectsPivotDistancesX[i].Add(m_TrackedObjects[i].Center.XDouble - starMap.Features[j].GetCenter().XDouble); m_TrackedObjectsPivotDistancesY[i].Add(m_TrackedObjects[i].Center.YDouble - starMap.Features[j].GetCenter().YDouble); } int x0 = m_TrackedObjects[i].Center.X; int y0 = m_TrackedObjects[i].Center.Y; PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { SetTargetFWHM(i, (float)fit.FWHM); } } m_TargetPivotDistancesListX.Clear(); m_TargetPivotDistancesListY.Clear(); return(true); }
public void NextFrame(int frameNo, IAstroImage astroImage) { m_IsTrackedSuccessfully = false; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count >= 5) { starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); int featuresToConsider = Math.Min(10, starMap.Features.Count); var featureDistances = new List <List <double> >(); for (int i = 0; i < featuresToConsider; i++) { var dist = new List <double>(); for (int j = 0; j < featuresToConsider; j++) { dist.Add(double.NaN); } featureDistances.Add(dist); } var pivotDistances = new List <List <double> >(); for (int i = 0; i < featuresToConsider; i++) { pivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES)); } for (int i = 0; i < featuresToConsider; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < featuresToConsider; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); pivotDistances[i][j] = distance; pivotDistances[j][i] = distance; } } Dictionary <int, int> pivotMap = IdentifyPivots(pivotDistances); int identifiedObjects = 0; for (int i = 0; i < m_TrackedObjects.Count; i++) { ((TrackedObject)m_TrackedObjects[i]).NewFrame(); var xVals = new List <double>(); var yVals = new List <double>(); foreach (int key in pivotMap.Keys) { int mapsToSourceFeatureId = pivotMap[key]; xVals.Add(starMap.Features[key].GetCenter().XDouble + m_TrackedObjectsPivotDistancesX[i][mapsToSourceFeatureId]); yVals.Add(starMap.Features[key].GetCenter().YDouble + m_TrackedObjectsPivotDistancesY[i][mapsToSourceFeatureId]); } double x0 = xVals.Median(); double y0 = yVals.Median(); double sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1); double sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1); if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // Some of the pivots may have been misidentified. Remove all entries with too large residuals and try again xVals.RemoveAll(x => Math.Abs(x - x0) > sigmaX); yVals.RemoveAll(y => Math.Abs(y - y0) > sigmaY); if (xVals.Count > 1) { x0 = xVals.Median(); y0 = yVals.Median(); sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1); sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1); } } if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // There is something really wrong about this. Reject the position and fail the frame m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance, null, null); } else { PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { m_TrackedObjects[i].SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully, new ImagePixel(fit.XCenter, fit.YCenter), fit.Certainty); ((TrackedObject)m_TrackedObjects[i]).ThisFrameX = (float)fit.XCenter; ((TrackedObject)m_TrackedObjects[i]).ThisFrameY = (float)fit.YCenter; ((TrackedObjectBase)m_TrackedObjects[i]).PSFFit = fit; identifiedObjects++; } else { m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed, null, null); } } } m_IsTrackedSuccessfully = identifiedObjects == m_TrackedObjects.Count; if (m_IsTrackedSuccessfully) { UpdatePivotDistances(starMap, pivotMap); } } }
public void NextFrame(int frameNo, IAstroImage astroImage) { m_IsTrackedSuccessfully = false; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count >= 5) { starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); int featuresToConsider = Math.Min(10, starMap.Features.Count); var featureDistances = new List<List<double>>(); for (int i = 0; i < featuresToConsider; i++) { var dist = new List<double>(); for (int j = 0; j < featuresToConsider; j++) dist.Add(double.NaN); featureDistances.Add(dist); } var pivotDistances = new List<List<double>>(); for (int i = 0; i < featuresToConsider; i++) pivotDistances.Add(new List<double>(UNINITIALIZED_DISTANCES)); for (int i = 0; i < featuresToConsider; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < featuresToConsider; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); pivotDistances[i][j] = distance; pivotDistances[j][i] = distance; } } Dictionary<int, int> pivotMap = IdentifyPivots(pivotDistances); int identifiedObjects = 0; for (int i = 0; i < m_TrackedObjects.Count; i++) { ((TrackedObject)m_TrackedObjects[i]).NewFrame(); var xVals = new List<double>(); var yVals = new List<double>(); foreach (int key in pivotMap.Keys) { int mapsToSourceFeatureId = pivotMap[key]; xVals.Add(starMap.Features[key].GetCenter().XDouble + m_TrackedObjectsPivotDistancesX[i][mapsToSourceFeatureId]); yVals.Add(starMap.Features[key].GetCenter().YDouble + m_TrackedObjectsPivotDistancesY[i][mapsToSourceFeatureId]); } double x0 = xVals.Median(); double y0 = yVals.Median(); double sigmaX = Math.Sqrt(xVals.Select(x => (x - x0)*(x - x0)).Sum()) / (xVals.Count - 1); double sigmaY = Math.Sqrt(yVals.Select(y => (y - y0)*(y - y0)).Sum()) / (yVals.Count - 1); if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // Some of the pivots may have been misidentified. Remove all entries with too large residuals and try again xVals.RemoveAll(x => Math.Abs(x - x0) > sigmaX); yVals.RemoveAll(y => Math.Abs(y - y0) > sigmaY); if (xVals.Count > 1) { x0 = xVals.Median(); y0 = yVals.Median(); sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1); sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1); } } if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // There is something really wrong about this. Reject the position and fail the frame m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance, null, null); } else { PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { m_TrackedObjects[i].SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully, new ImagePixel(fit.XCenter, fit.YCenter), fit.Certainty); ((TrackedObject)m_TrackedObjects[i]).ThisFrameX = (float)fit.XCenter; ((TrackedObject)m_TrackedObjects[i]).ThisFrameY = (float)fit.YCenter; ((TrackedObjectBase)m_TrackedObjects[i]).PSFFit = fit; identifiedObjects++; } else { m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed, null, null); } } } m_IsTrackedSuccessfully = identifiedObjects == m_TrackedObjects.Count; if (m_IsTrackedSuccessfully) UpdatePivotDistances(starMap, pivotMap); } }
public bool InitializeNewTracking(IAstroImage astroImage) { m_StarMapConfig = new StarMapInternalConfig(StarMapInternalConfig.Default); m_StarMapConfig.CustomMaxSignalValue = astroImage.GetPixelmapPixels().Max(); m_StarMapConfig.CustomOptimumStarsValue = 25; m_StarMapConfig.IsFITSFile = true; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count < 10) { MessageBox.Show("Cannot initialize object tracking as less than 10 stars can be identified in the field"); return false; } // Build a signature of the largest 10 features (pivots) m_PivotDistances.Clear(); for (int i = 0; i < 10; i++) m_PivotDistances.Add(new List<double>(UNINITIALIZED_DISTANCES)); double fwhmSum = 0; int fwhmCount = 0; starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); for (int i = 0; i < 10; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < 10; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); m_PivotDistances[i][j] = distance; m_PivotDistances[j][i] = distance; } int x0 = feature_i.GetCenter().X; int y0 = feature_i.GetCenter().Y; PSFFit fit = new PSFFit((int) x0, (int) y0); uint[,] data = ((AstroImage) astroImage).GetMeasurableAreaPixels((int) x0, (int) y0); fit.Fit(data); if (fit.IsSolved) { fwhmSum += fit.FWHM; fwhmCount++; } } m_FWHMAverage = (float)(fwhmSum / fwhmCount); for (int i = 0; i < m_TrackedObjects.Count; i++) { m_TrackedObjectsPivotDistancesX[i] = new List<double>(); m_TrackedObjectsPivotDistancesY[i] = new List<double>(); for (int j = 0; j < 10; j++) { m_TrackedObjectsPivotDistancesX[i].Add(m_TrackedObjects[i].Center.XDouble - starMap.Features[j].GetCenter().XDouble); m_TrackedObjectsPivotDistancesY[i].Add(m_TrackedObjects[i].Center.YDouble - starMap.Features[j].GetCenter().YDouble); } int x0 = m_TrackedObjects[i].Center.X; int y0 = m_TrackedObjects[i].Center.Y; PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { SetTargetFWHM(i, (float)fit.FWHM); } } m_TargetPivotDistancesListX.Clear(); m_TargetPivotDistancesListY.Clear(); return true; }
private void timer1_Tick(object sender, EventArgs e) { timer1.Enabled = false; StarMapInternalConfig starMapConfig = StarMapInternalConfig.Default; if (rbAuto.Checked) { starMapConfig.OptimumStarsInField = (int) TangraConfig.Settings.Astrometry.PyramidOptimumStarsToMatch; starMapConfig.StarMapperTolerance = 2; } else { starMapConfig.OptimumStarsInField = -1; starMapConfig.StarMapperTolerance = trbarDepth.Value; } var starMap = new StarMap(); var image = new AstroImage(m_InitialPixelmap); starMap.FindBestMap( starMapConfig, image, AstrometryContext.Current.OSDRectToExclude, AstrometryContext.Current.RectToInclude, AstrometryContext.Current.LimitByInclusion); AstrometryContext.Current.StarMap = starMap; AstrometryContext.Current.StarMapConfig = starMapConfig; m_VideoController.RedrawCurrentFrame(false, true); }
public Bitmap ResolveObjects( TangraConfig.PhotometryReductionMethod photometryReductionMethod, TangraConfig.PsfQuadrature psfQuadrature, TangraConfig.PsfFittingMethod psfFittingMethod, TangraConfig.BackgroundMethod backgroundMethod, TangraConfig.PreProcessingFilter filter, Guid magnitudeBandId, Rectangle osdRectangleToExclude, Rectangle rectToInclude, bool limitByInclusion, IAstrometrySettings astrometrySettings, ObjectResolverSettings objectResolverSettings) { m_AstrometrySettings = astrometrySettings; StarMap starMap = new StarMap( astrometrySettings.PyramidRemoveNonStellarObject, astrometrySettings.MinReferenceStarFWHM, astrometrySettings.MaxReferenceStarFWHM, astrometrySettings.MaximumPSFElongation, astrometrySettings.LimitReferenceStarDetection); starMap.FindBestMap(StarMapInternalConfig.Default, m_Image, osdRectangleToExclude, rectToInclude, limitByInclusion); float r0 = 0; m_MagnitudeFit = StarMagnitudeFit.PerformFit( m_AstrometryController, m_VideoController, m_Image.Pixelmap.BitPixCamera, m_Image.Pixelmap.MaxSignalValue, m_Astrometry.FitInfo, photometryReductionMethod, psfQuadrature, psfFittingMethod, backgroundMethod, filter, m_Stars, magnitudeBandId, 1.0f, TangraConfig.KnownCameraResponse.Undefined, null, null, null, ref r0); m_BackgroundFlux = m_MagnitudeFit.GetBackgroundIntencity(); m_BackgroundMag = m_MagnitudeFit.GetMagnitudeForIntencity(m_BackgroundFlux); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("Plate FWHM: {0}", 2 * Math.Sqrt(Math.Log(2)) * r0)); } PeakPixelResolver resolver = new PeakPixelResolver(m_Image); resolver.ResolvePeakPixels(osdRectangleToExclude, rectToInclude, limitByInclusion, objectResolverSettings.ExcludeEdgeAreaPixels, objectResolverSettings.MinDistanceBetweenPeakPixels); List <double> identifiedMagnitudes = new List <double>(); List <double> identifiedR0s = new List <double>(); m_IdentifiedObjects.Clear(); m_UidentifiedObjects.Clear(); foreach (KeyValuePair <int, int> peakPixel in resolver.PeakPixels.Keys) { int x = peakPixel.Key; int y = peakPixel.Value; bool isSaturated; double intencity = m_MagnitudeFit.GetIntencity(new ImagePixel(255, x, y), out isSaturated); double magnitude = m_MagnitudeFit.GetMagnitudeForIntencity(intencity); if (magnitude < m_MaxMagForAstrometry) { double RADeg, DEDeg; PSFFit fit; starMap.GetPSFFit(x, y, PSFFittingMethod.NonLinearFit, out fit); if (fit.IMax < 0) { continue; } if (fit.IMax < fit.I0) { continue; } if (fit.Certainty < objectResolverSettings.MinCertainty) { continue; } if (fit.FWHM < objectResolverSettings.MinFWHM) { continue; } if (fit.IMax - fit.I0 < objectResolverSettings.MinAmplitude) { continue; } m_Astrometry.GetRADEFromImageCoords(fit.XCenter, fit.YCenter, out RADeg, out DEDeg); // All stars closer than 2 arcsec to this position List <IStar> matchingStars = m_Stars.Where(s => Math.Abs(AngleUtility.Elongation(s.RADeg, s.DEDeg, RADeg, DEDeg) * 3600.0) < objectResolverSettings.MaxStarMatchMagDif).ToList(); bool identified = false; if (matchingStars.Count >= 1) { foreach (IStar star in matchingStars) { if (objectResolverSettings.MaxStarMatchMagDif >= Math.Abs(magnitude - star.Mag)) { // The star is identified. Do we care more? if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("STAR ({0}, {1}) No -> {2}; Mag -> {3} (Expected: {4}); R0 = {5}", x, y, star.StarNo, magnitude.ToString("0.00"), star.Mag.ToString("0.00"), fit.R0.ToString("0.0"))); } identifiedMagnitudes.Add(magnitude); identifiedR0s.Add(fit.R0); m_IdentifiedObjects.Add(fit, star); identified = true; break; } } } if (matchingStars.Count == 0 || !identified) { // The object is not in the star database // TODO: Test for hot pixel. Match to hot pixel profile from the brightest pixel in the area m_UidentifiedObjects.Add(fit, magnitude); } } else { // Don't bother with too faint objects } } if (m_IdentifiedObjects.Count > 0) { double mean = identifiedR0s.Average(); double variance = 0; foreach (double rr0 in identifiedR0s) { variance += (rr0 - mean) * (rr0 - mean); } variance = Math.Sqrt(variance / (m_IdentifiedObjects.Count - 1)); double minR0 = mean - variance; double maxR0 = mean + variance; identifiedMagnitudes.Sort(); double maxStarMag = identifiedMagnitudes[Math.Max(0, (int)Math.Truncate(0.9 * identifiedMagnitudes.Count))]; if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("Max Star Mag: {0}; R0 ({1}, {2})", maxStarMag.ToString("0.00"), minR0.ToString("0.0"), maxR0.ToString("0.0"))); } // NOTE: The R0 exclusion may ignore bright comets ! m_UnknownObjects = m_UidentifiedObjects .Where(p => p.Value < maxStarMag && p.Key.R0 >= minR0 && p.Key.R0 <= maxR0) .ToDictionary(p => p.Key, p => p.Value); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { foreach (PSFFit obj in m_UnknownObjects.Keys) { Trace.WriteLine(string.Format("UNK: ({0}, {1}) Mag -> {2}; R0 = {3}", obj.XCenter.ToString("0.0"), obj.YCenter.ToString("0.0"), m_UnknownObjects[obj].ToString("0.00"), obj.R0.ToString("0.0"))); } } } Bitmap bitmap = m_Image.Pixelmap.CreateDisplayBitmapDoNotDispose(); using (Graphics g = Graphics.FromImage(bitmap)) { foreach (PSFFit star in m_IdentifiedObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.GreenYellow, x - 5, y - 5, 10, 10); } foreach (PSFFit star in m_UnknownObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.Tomato, x - 8, y - 8, 16, 16); } g.Save(); } return(bitmap); }
public Bitmap ResolveObjects( TangraConfig.PhotometryReductionMethod photometryReductionMethod, TangraConfig.PsfQuadrature psfQuadrature, TangraConfig.PsfFittingMethod psfFittingMethod, TangraConfig.BackgroundMethod backgroundMethod, TangraConfig.PreProcessingFilter filter, Guid magnitudeBandId, Rectangle osdRectangleToExclude, Rectangle rectToInclude, bool limitByInclusion, IAstrometrySettings astrometrySettings, ObjectResolverSettings objectResolverSettings) { m_AstrometrySettings = astrometrySettings; StarMap starMap = new StarMap( astrometrySettings.PyramidRemoveNonStellarObject, astrometrySettings.MinReferenceStarFWHM, astrometrySettings.MaxReferenceStarFWHM, astrometrySettings.MaximumPSFElongation, astrometrySettings.LimitReferenceStarDetection); starMap.FindBestMap(StarMapInternalConfig.Default, m_Image, osdRectangleToExclude, rectToInclude, limitByInclusion); float r0 = 0; m_MagnitudeFit = StarMagnitudeFit.PerformFit( m_AstrometryController, m_VideoController, m_Image.Pixelmap.BitPixCamera, m_Image.Pixelmap.MaxSignalValue, m_Astrometry.FitInfo, photometryReductionMethod, psfQuadrature, psfFittingMethod, backgroundMethod, filter, m_Stars, magnitudeBandId, 1.0f, TangraConfig.KnownCameraResponse.Undefined, null, null, null, ref r0); m_BackgroundFlux = m_MagnitudeFit.GetBackgroundIntencity(); m_BackgroundMag = m_MagnitudeFit.GetMagnitudeForIntencity(m_BackgroundFlux); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("Plate FWHM: {0}", 2 * Math.Sqrt(Math.Log(2)) * r0)); PeakPixelResolver resolver = new PeakPixelResolver(m_Image); resolver.ResolvePeakPixels(osdRectangleToExclude, rectToInclude, limitByInclusion, objectResolverSettings.ExcludeEdgeAreaPixels, objectResolverSettings.MinDistanceBetweenPeakPixels); List<double> identifiedMagnitudes = new List<double>(); List<double> identifiedR0s = new List<double>(); m_IdentifiedObjects.Clear(); m_UidentifiedObjects.Clear(); foreach(KeyValuePair<int, int> peakPixel in resolver.PeakPixels.Keys) { int x = peakPixel.Key; int y = peakPixel.Value; bool isSaturated; double intencity = m_MagnitudeFit.GetIntencity(new ImagePixel(255, x, y), out isSaturated); double magnitude = m_MagnitudeFit.GetMagnitudeForIntencity(intencity); if (magnitude < m_MaxMagForAstrometry) { double RADeg, DEDeg; PSFFit fit; starMap.GetPSFFit(x, y, PSFFittingMethod.NonLinearFit, out fit); if (fit.IMax < 0) continue; if (fit.IMax < fit.I0) continue; if (fit.Certainty < objectResolverSettings.MinCertainty) continue; if (fit.FWHM < objectResolverSettings.MinFWHM) continue; if (fit.IMax - fit.I0 < objectResolverSettings.MinAmplitude) continue; m_Astrometry.GetRADEFromImageCoords(fit.XCenter, fit.YCenter, out RADeg, out DEDeg); // All stars closer than 2 arcsec to this position List<IStar> matchingStars = m_Stars.Where(s => Math.Abs(AngleUtility.Elongation(s.RADeg, s.DEDeg, RADeg, DEDeg) * 3600.0) < objectResolverSettings.MaxStarMatchMagDif).ToList(); bool identified = false; if (matchingStars.Count >= 1) { foreach(IStar star in matchingStars) { if (objectResolverSettings.MaxStarMatchMagDif >= Math.Abs(magnitude - star.Mag)) { // The star is identified. Do we care more? if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("STAR ({0}, {1}) No -> {2}; Mag -> {3} (Expected: {4}); R0 = {5}", x, y, star.StarNo, magnitude.ToString("0.00"), star.Mag.ToString("0.00"), fit.R0.ToString("0.0"))); identifiedMagnitudes.Add(magnitude); identifiedR0s.Add(fit.R0); m_IdentifiedObjects.Add(fit, star); identified = true; break; } } } if (matchingStars.Count == 0 || !identified) { // The object is not in the star database // TODO: Test for hot pixel. Match to hot pixel profile from the brightest pixel in the area m_UidentifiedObjects.Add(fit, magnitude); } } else { // Don't bother with too faint objects } } if (m_IdentifiedObjects.Count > 0) { double mean = identifiedR0s.Average(); double variance = 0; foreach (double rr0 in identifiedR0s) { variance += (rr0 - mean) * (rr0 - mean); } variance = Math.Sqrt(variance / (m_IdentifiedObjects.Count - 1)); double minR0 = mean - variance; double maxR0 = mean + variance; identifiedMagnitudes.Sort(); double maxStarMag = identifiedMagnitudes[Math.Max(0, (int)Math.Truncate(0.9 * identifiedMagnitudes.Count))]; if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) Trace.WriteLine(string.Format("Max Star Mag: {0}; R0 ({1}, {2})", maxStarMag.ToString("0.00"), minR0.ToString("0.0"), maxR0.ToString("0.0"))); // NOTE: The R0 exclusion may ignore bright comets ! m_UnknownObjects = m_UidentifiedObjects .Where(p => p.Value < maxStarMag && p.Key.R0 >= minR0 && p.Key.R0 <= maxR0) .ToDictionary(p => p.Key, p => p.Value); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { foreach (PSFFit obj in m_UnknownObjects.Keys) { Trace.WriteLine(string.Format("UNK: ({0}, {1}) Mag -> {2}; R0 = {3}", obj.XCenter.ToString("0.0"), obj.YCenter.ToString("0.0"), m_UnknownObjects[obj].ToString("0.00"), obj.R0.ToString("0.0"))); } } } Bitmap bitmap = m_Image.Pixelmap.CreateDisplayBitmapDoNotDispose(); using (Graphics g = Graphics.FromImage(bitmap)) { foreach (PSFFit star in m_IdentifiedObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.GreenYellow, x - 5, y - 5, 10, 10); } foreach (PSFFit star in m_UnknownObjects.Keys) { float x = (float)star.XCenter; float y = (float)star.YCenter; g.DrawEllipse(Pens.Tomato, x - 8, y - 8, 16, 16); } g.Save(); } return bitmap; }