Exemplo n.º 1
0
        private void LocateObjectAsGuidingStar(IAstroImage astroImage, TrackedObject trackedObject, bool useLowPassFilter)
        {
            trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);

            int bestMaxFixAreaSize = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM) ? (int)(6 * trackedObject.OriginalObject.RefinedFWHM) : 17;
            if (bestMaxFixAreaSize > 17) bestMaxFixAreaSize = 35; // We only support FSP Fitting of 17 or 35 square matrixes
            if (bestMaxFixAreaSize < 17) bestMaxFixAreaSize = 17;

            // Try all fits from 5 to 15. Find the one with the highest peak, then do a fit around this area with the configured psf matrix size
            uint[,] pixels;
            if (useLowPassFilter)
            {
                pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize + 2);
                pixels = EnhanceByteAreaForSearch(pixels);
            }
            else
            {
                pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize);
            }

            // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size
            PSFFit gaussian = new PSFFit((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY);
            gaussian.Fit(pixels, bestMaxFixAreaSize);

            if (gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty &&
                (trackedObject.LastKnownGoodPsfCertainty > TangraConfig.Settings.Special.GoodGuidingStarCertainty || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars))
            {
                // We have a problem. Try to find the star in the area using other means
                IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue);

                if (centroid != null)
                {
                    double maxAllowedDistance = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM)
                                                    ? 2 * trackedObject.OriginalObject.RefinedFWHM
                                                    : 3 * TangraConfig.Settings.Special.LostTrackingMinDistance;

                    if (LightCurveReductionContext.Instance.WindOrShaking) maxAllowedDistance *= 1.5;

                    if (centroid.DistanceTo(new ImagePixel((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY)) < maxAllowedDistance)
                    {
                        pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, bestMaxFixAreaSize);
                        gaussian = new PSFFit(centroid.X, centroid.Y);
                        gaussian.Fit(pixels, bestMaxFixAreaSize);
                    }
                }
            }

            IImagePixel firstCenter =
                gaussian.IsSolved
                    ? new ImagePixel(gaussian.Brightness, (int)gaussian.XCenter, (int)gaussian.YCenter)
                    : astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue);

            if (!gaussian.IsSolved || gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty)
                firstCenter = null;

            if (firstCenter != null)
            {
                // Do a second fit
                pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, bestMaxFixAreaSize);

                int secondFitAreaSize = Math.Max(trackedObject.PsfFitMatrixSize, (int)Math.Round(gaussian.FWHM * 2.5));
                if (secondFitAreaSize % 2 == 0) secondFitAreaSize++;
                secondFitAreaSize = Math.Min(17, secondFitAreaSize);

                gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
                gaussian.Fit(pixels, secondFitAreaSize);

                if (gaussian.IsSolved)
                {
                    double signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0;
                    double brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel
                                                       ? signal / trackedObject.RefinedOrLastSignalLevel
                                                       : trackedObject.RefinedOrLastSignalLevel / signal;
                    //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    double fluckDiff = Math.Abs(brightnessFluctoation)/m_AllowedSignalFluctoation;

                    //if (trackedObject.LastSignalLevel != 0 &&
                    //    fluckDiff > 1 &&
                    //    LightCurveReductionContext.Instance.WindOrShaking)
                    //{
                    //    // If the located object is not similar brightness as expected, then search for our object in a wider area
                    //    try
                    //    {
                    //        IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, 14, m_MedianValueStart);
                    //        pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, 17);
                    //        gaussian = new PSFFit(centroid.X, centroid.Y);
                    //        gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize);

                    //        if (gaussian.IsSolved)
                    //        {
                    //            signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0;
                    //            brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel
                    //                                   ? signal / trackedObject.RefinedOrLastSignalLevel
                    //                                   : trackedObject.RefinedOrLastSignalLevel / signal;
                    //            //brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    //            fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;
                    //        }
                    //        else
                    //        {
                    //           Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding.WindOrShaking]. Cannot solve third PSF", m_FrameNo, trackedObject.TargetNo));
                    //        }
                    //    }
                    //    catch { }
                    //}

                    if (!trackedObject.HasRefinedPositions || fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars)
                    {
                        trackedObject.PSFFit = gaussian;
                        trackedObject.ThisFrameX = (float)gaussian.XCenter;
                        trackedObject.ThisFrameY = (float)gaussian.YCenter;
                        trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);
                        trackedObject.ThisFrameCertainty = (float) gaussian.Certainty;
                        trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);

                        if (m_Refining)
                        {
                            trackedObject.RegisterRefinedPosition(trackedObject.Center, trackedObject.ThisSignalLevel, gaussian.FWHM);
                        }
                    }
                    else
                    {
                        if (useLowPassFilter)
                        {
                            // Only show the warning the second time around
                            Trace.WriteLine(
                                string.Format(
                                    "Frame {0}: Guiding target #{1} is suspect because the brightness fluctuation is too big: {2}",
                                    m_FrameNo, trackedObject.TargetNo, fluckDiff.ToString("0.00")));

                            trackedObject.SetIsLocated(false, NotMeasuredReasons.GuidingStarBrightnessFluctoationTooHigh);
                        }
                    }
                }
                else
                {
                    Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve second PSF", m_FrameNo, trackedObject.TargetNo));
                    trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }
            }
            else
            {
                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve first PSF", m_FrameNo, trackedObject.TargetNo));
                trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }

            if (!trackedObject.IsLocated)
            {
                // Could not locate the object this time
                trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel;
                if (m_Refining)
                {
                    // Use the last known coordinates for refining frames
                    trackedObject.ThisFrameX = trackedObject.LastFrameX;
                    trackedObject.ThisFrameY = trackedObject.LastFrameY;
                    trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel;
                    trackedObject.ThisFrameCertainty = (float)trackedObject.LastKnownGoodPsfCertainty;
                    trackedObject.RegisterRefinedPosition(ImagePixel.Unspecified, float.NaN, double.NaN);
                }
                else
                {
                    // Make the position invalid, which will cause the distance check for this object to fail
                    // which will trigger another fitting later on. Eventually the previous position may be still used
                    trackedObject.ThisFrameX = float.NaN;
                    trackedObject.ThisFrameY = float.NaN;
                    trackedObject.ThisFrameCertainty = float.NaN;
                }
            }
        }
Exemplo n.º 2
0
        private void LocateNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);

            double averageX = 0;
            double averageY = 0;

            GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY);

            trackedObject.ThisFrameX = (float)averageX;
            trackedObject.ThisFrameY = (float)averageY;
            trackedObject.PSFFit = null;
            trackedObject.ThisSignalLevel = float.NaN;
            trackedObject.ThisFrameCertainty = float.NaN;

            List<TrackedObject> resolvedGuidingStars = LocateFirstObjects.FindAll(o => o.IsLocated);
            if (resolvedGuidingStars.Count == 0)
            {
                if (m_Refining)
                    trackedObject.RegisterRefinedPosition(newStaringPos, float.NaN, double.NaN);
            }
            else
            {
                FitObjectInLimitedArea(trackedObject, astroImage, (float) averageX, (float) averageY);

                if (m_Refining)
                    trackedObject.RegisterRefinedPosition(
                        new ImagePixel((int)trackedObject.ThisSignalLevel, trackedObject.ThisFrameX, trackedObject.ThisFrameY),
                        trackedObject.ThisSignalLevel,
                        trackedObject.PSFFit != null ? trackedObject.PSFFit.FWHM : double.NaN);
            }
        }