示例#1
0
 internal SpectraReader(AstroImage image, float angleDegrees)
 {
     m_Image = image;
     m_Mapper = new RotationMapper(image.Width, image.Height, angleDegrees);
     m_SourceVideoFrame = new RectangleF(0, 0, image.Width, image.Height);
 }
        internal float LocateSpectraAngle(PSFFit selectedStar, AstroImage image)
        {
            float x0 = (float)selectedStar.XCenter;
            float y0 = (float)selectedStar.YCenter;
            uint brigthness10 = (uint)(0.1 * selectedStar.Brightness);
            uint brigthness20 = (uint)(0.2 * selectedStar.Brightness);
            uint brigthness40 = (uint)(0.4 * selectedStar.Brightness);
            uint bgFromPsf = (uint)(selectedStar.I0);

            int minDistance = (int)(10 * selectedStar.FWHM);
            int clearDist = (int)(2 * selectedStar.FWHM);

            float width = image.Width;
            float height = image.Height;

            uint[] angles = new uint[360];
            uint[] sums = new uint[360];
            uint[] pixAbove10Perc = new uint[360];
            uint[] pixAbove20Perc = new uint[360];
            uint[] pixAbove40Perc = new uint[360];

            int diagonnalPixels = (int)Math.Ceiling(Math.Sqrt(image.Width * image.Width + image.Height * image.Height));

            int iFrom = 0;
            int iTo = 360;

            bool peakFound = false;
            for (int i = iFrom; i < iTo; i++)
            {
                var mapper = new RotationMapper(image.Width, image.Height, i);
                PointF p1 = mapper.GetDestCoords(x0, y0);
                float x1 = p1.X;
                float y1 = p1.Y;

                uint rowSum = 0;
                uint pixAbove10 = 0;
                uint pixAbove10Max = 0;
                bool prevPixAbove10 = false;
                uint pixAbove20 = 0;
                uint pixAbove20Max = 0;
                bool prevPixAbove20 = false;
                uint pixAbove40 = 0;
                uint pixAbove40Max = 0;
                bool prevPixAbove40 = false;

                for (int d = minDistance; d < diagonnalPixels; d++)
                {
                    PointF p = mapper.GetSourceCoords(x1 + d, y1);

                    if (p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height)
                    {
                        uint value = (uint)image.GetPixel((int)p.X, (int)p.Y);
                        rowSum += value;
                        PointF pu = mapper.GetSourceCoords(x1 + d, y1 + clearDist);
                        PointF pd = mapper.GetSourceCoords(x1 + d, y1 - clearDist);
                        if (pu.X >= 0 && pu.X < width && pu.Y >= 0 && pu.Y < height &&
                            pd.X >= 0 && pd.X < width && pd.Y >= 0 && pd.Y < height)
                        {
                            uint value_u = (uint)image.GetPixel((int)pu.X, (int)pu.Y);
                            uint value_d = (uint)image.GetPixel((int)pd.X, (int)pd.Y);
                            if ((value - bgFromPsf) > brigthness10 && value > value_u && value > value_d)
                            {
                                if (prevPixAbove10) pixAbove10++;
                                prevPixAbove10 = true;
                            }
                            else
                            {
                                prevPixAbove10 = false;
                                if (pixAbove10Max < pixAbove10) pixAbove10Max = pixAbove10;
                                pixAbove10 = 0;
                                peakFound = true;
                            }

                            if ((value - bgFromPsf) > brigthness20 && value > value_u && value > value_d)
                            {
                                if (prevPixAbove20) pixAbove20++;
                                prevPixAbove20 = true;
                            }
                            else
                            {
                                prevPixAbove20 = false;
                                if (pixAbove20Max < pixAbove20) pixAbove20Max = pixAbove20;
                                pixAbove20 = 0;
                                peakFound = true;
                            }

                            if ((value - bgFromPsf) > brigthness40 && value > value_u && value > value_d)
                            {
                                if (prevPixAbove40) pixAbove40++;
                                prevPixAbove40 = true;
                            }
                            else
                            {
                                prevPixAbove40 = false;
                                if (pixAbove40Max < pixAbove40) pixAbove40Max = pixAbove40;
                                pixAbove40 = 0;
                                peakFound = true;
                            }
                        }
                        else
                        {
                            prevPixAbove10 = false;
                            if (pixAbove10Max < pixAbove10) pixAbove10Max = pixAbove10;
                            pixAbove10 = 0;

                            prevPixAbove20 = false;
                            if (pixAbove20Max < pixAbove20) pixAbove20Max = pixAbove20;
                            pixAbove20 = 0;

                            prevPixAbove40 = false;
                            if (pixAbove40Max < pixAbove40) pixAbove40Max = pixAbove40;
                            pixAbove40 = 0;

                            peakFound = true;
                        }
                    }
                }

                angles[i] = (uint)i;
                sums[i] = rowSum;
                pixAbove10Perc[i] = pixAbove10Max;
                pixAbove20Perc[i] = pixAbove20Max;
                pixAbove40Perc[i] = pixAbove40Max;
            }

            if (!peakFound)
                return float.NaN;

            var angles10 = new List<uint>(angles).ToArray();
            var angles20 = new List<uint>(angles).ToArray();
            var angles40 = new List<uint>(angles).ToArray();

            Array.Sort(sums, angles);
            Array.Sort(pixAbove10Perc, angles10);
            Array.Sort(pixAbove20Perc, angles20);
            Array.Sort(pixAbove40Perc, angles40);

            uint roughAngle = angles[359];

            if (pixAbove10Perc[358]*2 < pixAbove10Perc[359])
            {
                // If second best at 10% id a lot smaller score than the top 10% scopem then this is it
                roughAngle = angles10[359];
            }
            else
            {
                if (Math.Abs((int)angles[358] - (int)angles[359]) > 3)// or for large stars the two best can be sequential angles
                    return float.NaN;
            }

            uint bestSum = 0;
            float bestAngle = 0f;

            for (float a = roughAngle - 1; a < roughAngle + 1; a += 0.02f)
            {
                var mapper = new RotationMapper(image.Width, image.Height, a);
                PointF p1 = mapper.GetDestCoords(x0, y0);
                float x1 = p1.X;
                float y1 = p1.Y;

                uint rowSum = 0;

                for (int d = minDistance; d < diagonnalPixels; d++)
                {
                    PointF p = mapper.GetSourceCoords(x1 + d, y1);

                    if (p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height)
                    {
                        uint pixVal = (uint)image.GetPixel((int)p.X, (int)p.Y);
                        rowSum += pixVal;
                    }
                }

                if (rowSum > bestSum)
                {
                    bestSum = rowSum;
                    bestAngle = a;
                }
            }

            return bestAngle;
        }
        private bool SelectingStarSpectra(Point location, bool shiftHeld, bool controlHeld)
        {
            IVideoFrame currentVideoFrame = m_VideoRenderingController.GetCurrentFrame();
            if (currentVideoFrame != null)
            {
                var astroImg = new AstroImage(currentVideoFrame, m_VideoRenderingController.Width, m_VideoRenderingController.Height, currentVideoFrame.MaxSignalValue);
                uint[,] areaPixels = astroImg.GetMeasurableAreaPixels(location.X, location.Y);

                PSFFit psfFit = new PSFFit(location.X, location.Y);
                psfFit.Fit(areaPixels);

                if (psfFit.IsSolved && psfFit.Certainty > Settings.Default.TrackingMinGuidingCertainty)
                {
                    float angle = LocateSpectraAngle(psfFit, astroImg);

                    if (!float.IsNaN(angle))
                    {
                        TrackingContext.Current.GuidingStar = new LastTrackedPosition(m_Bpp)
                        {
                            FWHM = (float)psfFit.FWHM,
                            X = (float)psfFit.XCenter,
                            Y = (float)psfFit.YCenter,
                            IsFixed = false
                        };

                        TrackingContext.Current.ReConfigureNativeTracking(m_VideoRenderingController.Width, m_VideoRenderingController.Height);
                        TrackingContext.Current.SpectraAngleDeg = angle;

                        return true;
                    }
                }
            }

            return false;
        }
        private bool SelectingTargetStar(Point location, bool shiftHeld, bool controlHeld)
        {
            IVideoFrame currentVideoFrame = m_VideoRenderingController.GetCurrentFrame();
            if (currentVideoFrame != null)
            {
                var astroImg = new AstroImage(currentVideoFrame, m_VideoRenderingController.Width, m_VideoRenderingController.Height);
                uint[,] areaPixels = astroImg.GetMeasurableAreaPixels(location.X, location.Y);

                PSFFit psfFit = new PSFFit(location.X, location.Y);
                psfFit.Fit(areaPixels);

                TrackingContext.Current.TargetStar = new LastTrackedPosition(m_Bpp)
                {
                    FWHM = (float)psfFit.FWHM,
                    X = (float)psfFit.XCenter,
                    Y = (float)psfFit.YCenter
                };

                TrackingContext.Current.TargetStar.IsFixed = !psfFit.IsSolved || psfFit.Certainty < Settings.Default.TrackingMinForcedFixedObjCertainty || controlHeld;
                TrackingContext.Current.TargetStar.IsFullDisapearance = shiftHeld;
                TrackingContext.Current.ReConfigureNativeTracking(m_VideoRenderingController.Width, m_VideoRenderingController.Height);

                return true;

            }

            return false;
        }
        private bool SelectGuidingStar(Point location, bool shiftHeld, bool controlHeld)
        {
            IVideoFrame currentVideoFrame = m_VideoRenderingController.GetCurrentFrame();
            if (currentVideoFrame != null)
            {
                // Find the object at the location and set it as a guiding star
                var astroImg = new AstroImage(currentVideoFrame, m_VideoRenderingController.Width, m_VideoRenderingController.Height);
                uint[,] areaPixels = astroImg.GetMeasurableAreaPixels(location.X, location.Y);

                PSFFit psfFit = new PSFFit(location.X, location.Y);
                psfFit.Fit(areaPixels);
                if (psfFit.IsSolved && psfFit.Certainty > Settings.Default.TrackingMinGuidingCertainty)
                {
                    TrackingContext.Current.GuidingStar = new LastTrackedPosition(m_Bpp)
                    {
                        FWHM = (float)psfFit.FWHM,
                        X = (float)psfFit.XCenter,
                        Y = (float)psfFit.YCenter,
                        IsFixed = false
                    };

                    TrackingContext.Current.ReConfigureNativeTracking(m_VideoRenderingController.Width, m_VideoRenderingController.Height);
                    TrackingContext.Current.SpectraAngleDeg = float.NaN;

                    return true;
                }
                else
                {
                    // NOTE: Too faint to be used as a guiding star
                    MessageBox.Show(m_MainForm, "This object is not bright enought for a Guiding star.", "OccuRec", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

            return false;
        }