public ImagePixel GetPSFFit(int x, int y, PSFFittingMethod method, out PSFFit psfFit) { StarMapFeature feature = GetFeatureInRadius(x, y, 5); int dimention = 9; if (CoreAstrometrySettings.Default.SearchAreaAuto) { if (feature != null) { if (feature.PixelCount > 25) { dimention = 9; } if (feature.PixelCount > 40) { dimention = 11; } if (feature.PixelCount > 60) { dimention = 13; } if (feature.PixelCount > 80) { dimention = 15; } } } else { dimention = 2 * ((int)Math.Round(CoreAstrometrySettings.Default.SearchArea) / 2) + 1; } return(GetPSFFit(x, y, dimention, method, out psfFit)); }
public StarMapFeature AppendFeature(int x, int y) { StarMapFeature feature = new StarMapFeature(m_FeatureId, m_Pixelmap.Width); m_FeatureId++; m_Features.Add(feature); return(feature); }
public StarMapFeature AppendFeature(int x, int y) { // When appending a feature, make sure that there will be no gap in the FeatureIds m_FeatureId = FeaturesCount; StarMapFeature feature = new StarMapFeature(m_FeatureId, m_Pixelmap.Width); m_FeatureId++; m_Features.Add(feature); return(feature); }
public override StarMapFeature GetFeatureInRadius(int x0, int y0, int radius) { List <StarMapFeature> candidates = new List <StarMapFeature>(); for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { int y = y0 + i; int x = x0 + j; if (x < 0 || x > m_FullWidth) { continue; } if (y < 0 || y > m_FullHeight) { continue; } ulong key = (ulong)(y * m_Pixelmap.Width + x); foreach (StarMapFeature feature in m_Features) { if (candidates.IndexOf(feature) != -1) { continue; } if (feature.m_Pixels.ContainsKey(key)) { candidates.Add(feature); continue; } } } } StarMapFeature brightestFeature = null; foreach (StarMapFeature feature in candidates) { if (brightestFeature == null || feature.PixelCount > brightestFeature.PixelCount) { brightestFeature = feature; } } return(brightestFeature); }
public object Clone() { StarMapFeature clone = new StarMapFeature(FeatureId, m_Width); clone.m_MaxBrightness = m_MaxBrightness; clone.m_MaxBrightnessFirstKey = m_MaxBrightnessFirstKey; clone.m_MaxBrightnessPixels = m_MaxBrightnessPixels; clone.m_Generation = m_Generation; clone.m_Merges = m_Merges; foreach (ulong key in m_Pixels.Keys) { clone.m_Pixels.Add(key, m_Pixels[key]); } return(clone); }
public static StarMapFeature FromReflectedObject(object refl) { int featureId = StarMap.GetPropValue <int>(refl, "FeatureId"); int width = StarMap.GetPropValue <int>(refl, "Width"); StarMapFeature feature = new StarMapFeature(featureId, width); feature.m_MaxBrightness = StarMap.GetPropValue <byte>(refl, "m_MaxBrightness"); feature.m_MaxBrightnessFirstKey = StarMap.GetPropValue <ulong>(refl, "m_MaxBrightnessFirstKey"); feature.m_MaxBrightnessPixels = StarMap.GetPropValue <int>(refl, "m_MaxBrightnessPixels"); feature.m_Generation = StarMap.GetPropValue <int>(refl, "m_Generation"); feature.m_Merges = StarMap.GetPropValue <int>(refl, "m_Merges"); feature.m_Intencity = StarMap.GetPropValue <uint>(refl, "m_Intencity"); feature.m_Pixels = StarMap.GetPropValue <SortedDictionary <ulong, uint> >(refl, "m_Pixels"); return(feature); }
public void MergePixels(StarMapFeature mergeWith) { bool pixelsMerged = false; foreach (ulong idx in mergeWith.m_Pixels.Keys) { if (!this.m_Pixels.ContainsKey(idx)) { this.m_Pixels.Add(idx, mergeWith.m_Pixels[idx]); pixelsMerged = true; } } if (pixelsMerged) { m_Merges++; } m_Center = null; }
public static StarMapFeature FromReflectedObject(object refl) { int featureId = StarMap.GetPropValue<int>(refl, "FeatureId"); int width = StarMap.GetPropValue<int>(refl, "Width"); StarMapFeature feature = new StarMapFeature(featureId, width); feature.m_MaxBrightness = StarMap.GetPropValue<byte>(refl, "m_MaxBrightness"); feature.m_MaxBrightnessFirstKey = StarMap.GetPropValue<ulong>(refl, "m_MaxBrightnessFirstKey"); feature.m_MaxBrightnessPixels = StarMap.GetPropValue<int>(refl, "m_MaxBrightnessPixels"); feature.m_Generation = StarMap.GetPropValue<int>(refl, "m_Generation"); feature.m_Merges = StarMap.GetPropValue<int>(refl, "m_Merges"); feature.m_Intencity = StarMap.GetPropValue<uint>(refl, "m_Intencity"); feature.m_Pixels = StarMap.GetPropValue<SortedDictionary<ulong, uint>>(refl, "m_Pixels"); return feature; }
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++; } } }
protected void ResetPreviousStar() { m_PreviousStar = null; m_PreviousFeature = null; }
private ImagePixel GetCenterOfFeature(StarMapFeature feature, IStarMap starMap) { ImagePixel center = feature.GetCenter(); if (center == null) return ImagePixel.Unspecified; return starMap.GetCentroid(center.X, center.Y, (int)CoreAstrometrySettings.Default.SearchArea); }
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; }
public object Clone() { StarMapFeature clone = new StarMapFeature(FeatureId, m_Width); clone.m_MaxBrightness = m_MaxBrightness; clone.m_MaxBrightnessFirstKey = m_MaxBrightnessFirstKey; clone.m_MaxBrightnessPixels = m_MaxBrightnessPixels; clone.m_Generation = m_Generation; clone.m_Merges = m_Merges; foreach (ulong key in m_Pixels.Keys) clone.m_Pixels.Add(key, m_Pixels[key]); return clone; }
private bool CheckTriangleWithRatios(IStarMap starMap, CheckTriangleWithRatiosCallback callback, int i, int j, int k, double toleranceInArcSec) { m_Feature_i = starMap.Features[i - 1]; m_Feature_j = starMap.Features[j - 1]; m_Feature_k = starMap.Features[k - 1]; m_FeatureId_i = m_Feature_i.FeatureId; m_FeatureId_j = m_Feature_j.FeatureId; m_FeatureId_k = m_Feature_k.FeatureId; long idx_ij = (m_FeatureId_i << 32) + m_FeatureId_j; long idx_ik = (m_FeatureId_i << 32) + m_FeatureId_k; long idx_jk = (m_FeatureId_j << 32) + m_FeatureId_k; ImagePixel feature_i_Center = null; ImagePixel feature_j_Center = null; ImagePixel feature_k_Center = null; double dist_ij; if (!m_FeaturesDistanceCache.TryGetValue(idx_ij, out dist_ij)) { if (feature_i_Center == null) feature_i_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_i), starMap); if (feature_j_Center == null) feature_j_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_j), starMap); } double dist_ik; if (!m_FeaturesDistanceCache.TryGetValue(idx_ik, out dist_ik)) { if (feature_i_Center == null) feature_i_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_i), starMap); if (feature_k_Center == null) feature_k_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_k), starMap); } double dist_jk; if (!m_FeaturesDistanceCache.TryGetValue(idx_jk, out dist_jk)) { if (feature_j_Center == null) feature_j_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_j), starMap); if (feature_k_Center == null) feature_k_Center = GetCenterOfFeature(starMap.GetFeatureById((int)m_FeatureId_k), starMap); } if (callback(i, j, k, feature_i_Center, feature_j_Center, feature_k_Center, toleranceInArcSec)) // solution found return true; return false; }
public void MergePixels(StarMapFeature mergeWith) { bool pixelsMerged = false; foreach (ulong idx in mergeWith.m_Pixels.Keys) { if (!this.m_Pixels.ContainsKey(idx)) { this.m_Pixels.Add(idx, mergeWith.m_Pixels[idx]); pixelsMerged = true; } } if (pixelsMerged) m_Merges++; m_Center = null; }
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; } }