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); }
internal void CreateMap(AstroImage image, Rectangle frame, StarMapInternalConfig config) { m_FullWidth = image.Width; m_FullHeight = image.Height; m_Pixelmap = image.Pixelmap; InitCreateMap(); CreateMap(config); }
public void InitializeStarMapButDontProcess(StarMapInternalConfig config, AstroImage image, Rectangle osdFrameToExclude, Rectangle frameToInclude, bool limitByInclusion) { m_FullWidth = image.Width; m_FullHeight = image.Height; m_Pixelmap = image.Pixelmap; m_OSDFrameToExclude = osdFrameToExclude; m_FrameToInclude = frameToInclude; m_LimitByInclusion = limitByInclusion; try { m_AverageBackgroundNoise = 0; InitCreateMap(); } finally { m_PerformanceWatch.Stop(); } }
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 int FindBestMap( StarMapInternalConfig config, AstroImage image, Rectangle osdFrameToExclude, Rectangle frameToInclude, bool limitByInclusion) { m_Config = config; m_PerformanceWatch.Reset(); m_PerformanceWatch.Start(); m_FullWidth = image.Width; m_FullHeight = image.Height; m_Pixelmap = image.Pixelmap; m_OSDFrameToExclude = osdFrameToExclude; m_FrameToInclude = frameToInclude; m_LimitByInclusion = limitByInclusion; int optimumStarsInField = config.OptimumStarsInField ?? (TangraConfig.Settings != null ? (int)TangraConfig.Settings.Astrometry.PyramidOptimumStarsToMatch : 25); uint maxSignalValue = config.CustomMaxSignalValue ?? m_Pixelmap.MaxSignalValue; m_AverageBackgroundNoise = maxSignalValue; int MIN_INTENSITY = config.IsFITSFile ? 1 : 5; int MAX_INTENSITY = config.IsFITSFile ? 1000 : 100; int INTENSITY_LARGE_STEP = config.IsFITSFile ? 50 : 5; int INTENSITY_SMALL_STEP = config.IsFITSFile ? 2 : 5; if (config.CustomOptimumStarsValue.HasValue) { optimumStarsInField = config.CustomOptimumStarsValue.Value; } double snRatio = config.IsFITSFile ? 0.005 : 0.15; try { int featuresThisRun = 0; int featuresLastRun = 0; bool tryForOptimumStars = optimumStarsInField > config.MinStarsInField; List <StarMapFeature> bestMapFeatures = new List <StarMapFeature>(); int intensity = MAX_INTENSITY; int tolerance = config.StarMapperTolerance; InitCreateMap(); do { if (intensity > 2 * INTENSITY_LARGE_STEP) { intensity -= INTENSITY_LARGE_STEP; } else { intensity -= INTENSITY_SMALL_STEP; } uint backgroundThreshold = (uint)Math.Round(maxSignalValue * (intensity * 1.0 / MAX_INTENSITY)); if (backgroundThreshold < config.MinStarMapThreashold) { break; } if (backgroundThreshold < snRatio * (maxSignalValue - m_AverageBackgroundNoise)) { break; } try { CreateMap(backgroundThreshold, config); } catch (StarMapException) { backgroundThreshold = (uint)Math.Round(maxSignalValue * ((intensity + INTENSITY_LARGE_STEP) * 1.0 / MAX_INTENSITY)); snRatio = (double)(backgroundThreshold - 1.0) / (maxSignalValue - m_AverageBackgroundNoise); intensity += 2 * INTENSITY_LARGE_STEP; continue; } if (m_Features.Count > 2.5 * optimumStarsInField) { m_Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); m_Features = m_Features.Take(2 * optimumStarsInField).ToList(); } featuresLastRun = featuresThisRun; featuresThisRun = m_Features.Count; if (tryForOptimumStars) { if ( featuresLastRun <= optimumStarsInField && featuresThisRun >= optimumStarsInField && featuresLastRun > 0.5 * optimumStarsInField && featuresThisRun < 1.5 * optimumStarsInField) { if (optimumStarsInField - featuresLastRun <= featuresThisRun - optimumStarsInField) { break; } else { bestMapFeatures.Clear(); bestMapFeatures.AddRange(m_Features); break; } } else { if (featuresThisRun >= 1.5 * optimumStarsInField) { // We couldn't fit in the optimum star range, so not trying to any more tryForOptimumStars = false; } } } bestMapFeatures.Clear(); bestMapFeatures.AddRange(m_Features); if (featuresThisRun > config.MaxStarsInField) { break; } if (m_Features.Count > config.MinStarsInField && featuresThisRun > featuresLastRun) { bool allNewFeaturesHaveOnePixel = true; foreach (StarMapFeature feature in m_Features) { if (feature.Generation == 1 && feature.m_Pixels.Count > 1) { allNewFeaturesHaveOnePixel = false; break; } } if (allNewFeaturesHaveOnePixel) { tolerance--; if (tolerance <= 0 && !tryForOptimumStars) { break; } } } m_NoiseLevel = backgroundThreshold; }while (intensity > MIN_INTENSITY); if (m_ForceStellarObjectRequirements) { ApplyPSFExclusionRulesToFeatures(); } return(intensity); } finally { m_PerformanceWatch.Stop(); if (TangraConfig.Settings.TraceLevels.PlateSolving.TraceVerbose()) { Trace.WriteLine(string.Format("StarMapGen: {0} ms, {1} features, {2} generations (tolerance = {3})", m_PerformanceWatch.ElapsedMilliseconds, m_Features.Count, m_Features.Count > 0 ? m_Features[0].Generation : 0, config.StarMapperTolerance)); } int lastGenMin = int.MaxValue; int thisGenMin = int.MaxValue; int lastGen = int.MaxValue; for (int i = 0; i < m_Features.Count; i++) { int currMax = int.MinValue; StarMapFeature ftr = m_Features[i]; foreach (int intens in ftr.m_Pixels.Values) { if (intens > currMax) { currMax = intens; } } #if ASTROMETRY_DEBUG Trace.Assert(lastGen >= ftr.Generation); #endif if (lastGen > ftr.Generation) { lastGen = ftr.Generation; lastGenMin = thisGenMin; } #if ASTROMETRY_DEBUG Trace.Assert(currMax < lastGenMin); #endif thisGenMin = currMax; } ReorderFeatureNumbersBasedOnIntensity(); } }
private bool CheckFeature(StarMapFeature feature, StarMapInternalConfig config, int x0, int y0, uint maxIntensity) { // The found pixel is already part of another feature int existingFeatureId; int idx0 = m_Pixelmap.Width * y0 + x0; if (m_IndexToFeatureIdMap.TryGetValue(idx0, out existingFeatureId)) { return(true); } // Find the closest peak pixel FindLocalPeak(ref x0, ref y0); idx0 = m_Pixelmap.Width * y0 + x0; if (m_IndexToFeatureIdMap.TryGetValue(idx0, out existingFeatureId)) { return(true); } m_PointsToCheckFurther.Clear(); m_PointsToCheckFurther.Enqueue(((ulong)x0 << 32) + (ulong)y0); while (m_PointsToCheckFurther.Count > 0) { if (feature.PixelCount > config.MaxPixelsInFeature) { break; } ulong point = m_PointsToCheckFurther.Dequeue(); int x = (int)(point >> 32); int y = (int)(point & 0xFFFFFFFF); if (!PixelIsInProcessArea(x, y)) { continue; } int idx = m_Pixelmap.Width * y + x; if (m_CheckedIndexes.IndexOf(idx) == -1) { m_CheckedIndexes.Add(idx); if (m_IndexToFeatureIdMap.TryGetValue(idx, out existingFeatureId)) { // Existing feature already contains this pixel. } else { uint pixel = m_Pixelmap.Pixels[idx]; feature.AddPixel(x, y, pixel); m_IndexToFeatureIdMap.Add(idx, feature.FeatureId); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (!(i == 0 && j == 0)) { if (Math.Abs(y0 - y - j) <= config.FeatureSearchRadius && Math.Abs(x0 - x - i) <= config.FeatureSearchRadius) { idx = m_Pixelmap.Width * (y + j) + (x + i); if (idx >= 0 && idx < m_Pixelmap.Pixels.Length) { if (m_Pixelmap.Pixels[idx] <= pixel && m_CheckedIndexes.IndexOf(idx) == -1) { m_PointsToCheckFurther.Enqueue(((ulong)(x + i) << 32) + (ulong)(y + j)); } } } } } } } } } return(false); }
private void CreateMap(uint maxIntensity, StarMapInternalConfig config) { m_CheckedIndexes.Clear(); m_AverageBackgroundNoise = 0; int bgCount = 0; try { for (int i = 0; i < m_Pixelmap.Pixels.Length; i++) { if (m_Pixelmap.Pixels[i] < maxIntensity) { m_AverageBackgroundNoise += m_Pixelmap.Pixels[i]; bgCount++; continue; } if (m_CheckedIndexes.IndexOf(i) == -1) { if (m_FeatureId > config.MaxStarsInField) { return; } int y = i / m_FullWidth; int x = (i % m_FullWidth); if (!PixelIsInProcessArea(x, y)) { continue; } StarMapFeature feature = new StarMapFeature(m_FeatureId, m_Pixelmap.Width); if (!CheckFeature(feature, config, x, y, maxIntensity)) { #if ASTROMETRY_DEBUG Trace.Assert(feature.m_Pixels.Count > 0); #endif m_FeatureId++; m_Features.Add(feature); } else { m_AverageBackgroundNoise += m_Pixelmap.Pixels[i]; bgCount++; } } } } finally { // a "Too many features" exception may be thrown if (bgCount != 0) { m_AverageBackgroundNoise /= (uint)bgCount; } #if ASTROMETRY_DEBUG Trace.Assert(m_AverageBackgroundNoise >= 0); Trace.Assert(m_AverageBackgroundNoise <= m_Pixelmap.MaxPixelValue); #endif foreach (StarMapFeature feature in m_Features) { feature.m_Generation++; } } }
private void CreateMap(StarMapInternalConfig config) { CreateMap(0, config); }