コード例 #1
0
        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);
        }
コード例 #2
0
        internal void CreateMap(AstroImage image, Rectangle frame, StarMapInternalConfig config)
        {
            m_FullWidth  = image.Width;
            m_FullHeight = image.Height;
            m_Pixelmap   = image.Pixelmap;

            InitCreateMap();
            CreateMap(config);
        }
コード例 #3
0
        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();
            }
        }
コード例 #4
0
ファイル: StarFieldTracker.cs プロジェクト: aschweiz/tangra3
        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);
        }
コード例 #5
0
        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();
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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++;
                }
            }
        }
コード例 #8
0
 private void CreateMap(StarMapInternalConfig config)
 {
     CreateMap(0, config);
 }