Esempio n. 1
0
        private void ProcessSingleUnitSet(
            List <LCMeasurement> units,
            bool useLowPass,
            bool useLowPassDiff,
            MeasurementsHelper measurer)
        {
            for (int i = 0; i < units.Count; i++)
            {
                LCMeasurement reading          = units[i];
                IImagePixel[] groupCenters     = new IImagePixel[0];
                float[]       aperturesInGroup = new float[0];

                TrackedObjectConfig        objConfig     = Footer.TrackedObjects[reading.TargetNo];
                List <TrackedObjectConfig> gropedObjects = Footer.TrackedObjects.Where(x => objConfig.GroupId >= 0 && x.GroupId == objConfig.GroupId).ToList();
                if (gropedObjects.Count > 1)
                {
                    groupCenters     = new IImagePixel[gropedObjects.Count];
                    aperturesInGroup = new float[gropedObjects.Count];

                    for (int j = 0; j < gropedObjects.Count; j++)
                    {
                        LCMeasurement mea = units[Footer.TrackedObjects.IndexOf(gropedObjects[j])];
                        groupCenters[j]     = new ImagePixel(mea.X0, mea.Y0);
                        aperturesInGroup[j] = gropedObjects[j].ApertureInPixels;
                    }
                }

                units[i] = ProcessSingleUnit(
                    reading, useLowPass, useLowPassDiff,
                    Context.ReProcessFitAreas[i], Context.ReProcessApertures[i], Header.FixedApertureFlags[i],
                    measurer, groupCenters, aperturesInGroup);
            }
        }
Esempio n. 2
0
 public static double DistanceTo(this IImagePixel pixel1, IImagePixel pixel2)
 {
     if (pixel2 == null)
     {
         return(double.NaN);
     }
     else
     {
         return(Math.Sqrt(Math.Pow(pixel1.XDouble - pixel2.XDouble, 2) + Math.Pow(pixel1.YDouble - pixel2.YDouble, 2)));
     }
 }
Esempio n. 3
0
        public double ComputeRefinedDistances(TrackedObject obj2, out double vectorX, out double vectorY)
        {
            double refinedDistance = double.NaN;

            if (this.OriginalObject.IsFixedAperture ||
                obj2.OriginalObject.IsFixedAperture)
            {
                // For manually placed apertures, return the initial distances

                vectorX = obj2.OriginalObject.ApertureStartingX - this.OriginalObject.ApertureStartingX;
                vectorY = obj2.OriginalObject.ApertureStartingY - this.OriginalObject.ApertureStartingY;

                return(Math.Sqrt(vectorX * vectorX + vectorY * vectorY));
            }

            List <double> distances = new List <double>();

            double xVector = 0;
            double yVector = 0;

            for (int k = 0; k < RefiningPositions.Count; k++)
            {
                IImagePixel pos1 = RefiningPositions[k];
                IImagePixel pos2 = obj2.RefiningPositions[k];

                if (pos1.IsSpecified &&
                    pos2.IsSpecified)
                {
                    // Compute and average the distance
                    double dist = Math.Sqrt((pos1.XDouble - pos2.XDouble) * (pos1.XDouble - pos2.XDouble) + (pos1.YDouble - pos2.YDouble) * (pos1.YDouble - pos2.YDouble));
                    distances.Add(dist);

                    xVector += (pos2.XDouble - pos1.XDouble);
                    yVector += (pos2.YDouble - pos1.YDouble);
                }
            }

            // Get the median and add in the final dict
            distances.Sort();
            if (distances.Count % 2 == 1)
            {
                refinedDistance = distances[distances.Count / 2];
            }
            else if (distances.Count > 0)
            {
                refinedDistance = 0.5 * (distances[(distances.Count / 2) - 1] + distances[distances.Count / 2]);
            }

            vectorX = xVector / distances.Count;
            vectorY = yVector / distances.Count;
            return(refinedDistance);
        }
Esempio n. 4
0
        public void RegisterRefinedPosition(IImagePixel position, float signalLevel, double fwhm)
        {
            RefiningPositions.Add(position);

            if (!float.IsNaN(signalLevel))
            {
                RefiningSignalLevels.Add(signalLevel);
            }
            if (!double.IsNaN(fwhm))
            {
                RefiningFWHMs.Add(fwhm);
            }
        }
Esempio n. 5
0
        public void GetPositionShift(out double deltaX, out double deltaY)
        {
            int         refinedPositions = RefiningPositions.Count;
            IImagePixel lastCenter       = RefiningPositions[refinedPositions - 1];
            IImagePixel prevCenter;

            if (refinedPositions > 1)
            {
                prevCenter = RefiningPositions[refinedPositions - 2];
            }
            else
            {
                prevCenter = OriginalObject.AsImagePixel;
            }

            deltaX = lastCenter.XDouble - prevCenter.XDouble;
            deltaY = lastCenter.YDouble - prevCenter.YDouble;
        }
Esempio n. 6
0
        public virtual void SetIsTracked(bool isMeasured, NotMeasuredReasons reason, IImagePixel estimatedCenter, double?psfCertainty)
        {
            IsLocated = isMeasured;

            // Remove the Tracked Successfully flag if set
            NotMeasuredReasons = (NotMeasuredReasons)((int)NotMeasuredReasons & ~(int)NotMeasuredReasons.TrackedSuccessfully);

            NotMeasuredReasons = (NotMeasuredReasons)((int)NotMeasuredReasons & 0x00FFFF) | reason;
            if (estimatedCenter != null)
            {
                Center = estimatedCenter;
                LastKnownGoodPosition = estimatedCenter;
            }

            if (psfCertainty != null)
            {
                LastKnownGoodPsfCertainty = psfCertainty.Value;
            }
        }
Esempio n. 7
0
        private void frmRunMultiFrameSpectroscopy_Load(object sender, EventArgs e)
        {
            IImagePixel starCenter = m_VideoOperation.SelectedStar;

            m_SpectraReader = new SpectraReader(m_AstroImage, m_VideoOperation.SelectedStarBestAngle, 1);
            m_Spectra       = m_SpectraReader.ReadSpectra((float)starCenter.XDouble, (float)starCenter.YDouble, (int)nudAreaWing.Value, (int)nudBackgroundWing.Value, (int)nudBackgroundGap.Value, PixelCombineMethod.Average);

            m_Mapper = new RotationMapper(m_AstroImage.Width, m_AstroImage.Height, m_VideoOperation.SelectedStarBestAngle);

            uint[,] pixels = m_AstroImage.GetMeasurableAreaPixels(starCenter.X, starCenter.Y, 35);
            m_ZeroOrderPsf = new PSFFit(starCenter.X, starCenter.Y);
            m_ZeroOrderPsf.Fit(pixels);
            m_Spectra.ZeroOrderFWHM = (float)m_ZeroOrderPsf.FWHM;

            PlotMeasurementAreas();
            PlotAlignTarget();

            nudDivisor.SetNUDValue((decimal)m_AstroImage.Pixelmap.MaxSignalValue);
            nudMultiplier.Value = 1024;
        }
Esempio n. 8
0
 private NotMeasuredReasons MeasureObject(
     IImagePixel center,
     uint[,] data,
     uint[,] backgroundPixels,
     int bpp,
     MeasurementsHelper measurer,
     TangraConfig.PreProcessingFilter filter,
     TangraConfig.PhotometryReductionMethod reductionMethod,
     TangraConfig.PsfQuadrature psfQuadrature,
     TangraConfig.PsfFittingMethod psfFittngMethod,
     float aperture,
     double refinedFWHM,
     float refinedAverageFWHM,
     IMeasurableObject measurableObject,
     IImagePixel[] groupCenters,
     float[] aperturesInGroup,
     bool fullDisappearance
     )
 {
     return(measurer.MeasureObject(
                center, data, backgroundPixels, bpp, filter, reductionMethod, psfQuadrature, psfFittngMethod,
                aperture, refinedFWHM, refinedAverageFWHM, measurableObject, groupCenters, aperturesInGroup, fullDisappearance));
 }
Esempio n. 9
0
        internal bool IdentifyBrightObject(PSFFit fit1, PSFFit fit2, float minStarCertainty, out TrackedObjectLight obj1, out TrackedObjectLight obj2, out IImagePixel center1, out IImagePixel center2)
        {
            double brightness1 = (fit1.Certainty > minStarCertainty ? fit1.Brightness : 1);
            double brightness2 = (fit2.Certainty > minStarCertainty ? fit2.Brightness : 1);
            double bDiff       = Math.Abs(brightness1 - brightness2);
            double bRatio      = bDiff / Math.Max(brightness1, brightness2);

            if (bRatio > 0.5)
            {
                bool   fit1Brighter         = brightness1 > brightness2;
                bool   oldFit1Brighter      = LastCenterObject1.Brightness > LastCenterObject2.Brightness;
                double oldDeltaXBrightFaint = oldFit1Brighter ? LastCenterObject1.XDouble - LastCenterObject2.XDouble : LastCenterObject2.XDouble - LastCenterObject1.XDouble;
                double oldDeltaYBrightFaint = oldFit1Brighter ? LastCenterObject1.YDouble - LastCenterObject2.YDouble : LastCenterObject2.YDouble - LastCenterObject1.YDouble;

                if (!(fit1Brighter ^ oldFit1Brighter))
                {
                    // 1 == 1; 2 == 2
                    if (fit1Brighter)
                    {
                        center1 = new ImagePixel((int)brightness1, fit1.XCenter, fit1.YCenter);
                        center2 = new ImagePixel((int)brightness2, fit1.XCenter - oldDeltaXBrightFaint, fit1.YCenter - oldDeltaYBrightFaint);
                        return(Match1122(out obj1, out obj2));
                    }
                    else
                    {
                        center1 = new ImagePixel((int)brightness2, fit2.XCenter, fit2.YCenter);
                        center2 = new ImagePixel((int)brightness1, fit2.XCenter - oldDeltaXBrightFaint, fit2.YCenter - oldDeltaYBrightFaint);
                        return(Match1122(out obj1, out obj2));
                    }
                }
                else
                {
                    // 1 == 2; 2 == 1
                    if (fit1Brighter)
                    {
                        center2 = new ImagePixel((int)brightness1, fit1.XCenter, fit1.YCenter);
                        center1 = new ImagePixel((int)brightness2, fit1.XCenter - oldDeltaXBrightFaint, fit1.YCenter - oldDeltaYBrightFaint);
                        return(Match1212(out obj1, out obj2));
                    }
                    else
                    {
                        center2 = new ImagePixel((int)brightness2, fit2.XCenter, fit2.YCenter);
                        center1 = new ImagePixel((int)brightness1, fit2.XCenter - oldDeltaXBrightFaint, fit2.YCenter - oldDeltaYBrightFaint);
                        return(Match1212(out obj1, out obj2));
                    }
                }
            }

            center1 = null;
            center2 = null;
            return(NoMatch(out obj1, out obj2));
        }
Esempio n. 10
0
 public ImagePixel(IImagePixel clone)
     : this(clone.Brightness, clone.XDouble, clone.YDouble)
 {
 }
Esempio n. 11
0
 public void SetIsTracked(bool isMeasured, NotMeasuredReasons reason, IImagePixel estimatedCenter, double?certainty)
 {
     Center    = estimatedCenter;
     IsLocated = isMeasured;
 }
Esempio n. 12
0
        public void RegisterRefinedPosition(IImagePixel position, float signalLevel, double fwhm)
        {
            RefiningPositions.Add(position);

            if (!float.IsNaN(signalLevel)) RefiningSignalLevels.Add(signalLevel);
            if (!double.IsNaN(fwhm)) RefiningFWHMs.Add(fwhm);
        }
Esempio n. 13
0
        private void GetAverageObjectPositionsFromGuidingStars(TrackedObject trackedObject, IImagePixel newStaringPos, out double averageX, out double averageY)
        {
            List<TrackedObject> resolvedGuidingStars = LocateFirstObjects.FindAll(o => o.IsLocated);
            if (resolvedGuidingStars.Count == 0)
            {
                averageX = newStaringPos.XDouble;
                averageY = newStaringPos.YDouble;
            }
            else
            {
                averageX = 0;
                averageY = 0;

                foreach (TrackedObject resolvedGuidingStar in resolvedGuidingStars)
                {
                    if (m_Refining)
                    {
                        averageX += (resolvedGuidingStar.ThisFrameX + trackedObject.OriginalObject.ApertureStartingX -
                                     resolvedGuidingStar.OriginalObject.ApertureStartingX);
                        averageY += (resolvedGuidingStar.ThisFrameY + trackedObject.OriginalObject.ApertureStartingY -
                                     resolvedGuidingStar.OriginalObject.ApertureStartingY);
                    }
                    else
                    {
                        LocationVector vec =
                            resolvedGuidingStar.OtherGuidingStarsLocationVectors[trackedObject.TargetNo];
                        averageX += (resolvedGuidingStar.ThisFrameX + vec.DeltaXToAdd);
                        averageY += (resolvedGuidingStar.ThisFrameY + vec.DeltaYToAdd);
                    }
                }

                averageX /= resolvedGuidingStars.Count;
                averageY /= resolvedGuidingStars.Count;
            }
        }
Esempio n. 14
0
        private void LocateFullDisappearingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            if (m_Refining)
                // Full disapearance is not expected during refining
                LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
            else
            {
                double averageX, averageY;
                GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY);

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

                int x0 = (int) Math.Round(averageX);
                int y0 = (int) Math.Round(averageY);

                trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason);
                PSFFit gaussian = null;

                int smallestMatrixSize = (int)Math.Round(trackedObject.OriginalObject.ApertureInPixels * 2);
                if (smallestMatrixSize % 2 == 0) smallestMatrixSize++;

                // If this is not an aperture photometry we still derive a PSF
                uint[,] pixels = astroImage.GetPixelsArea(x0, y0, 17);

                for (int i = trackedObject.PsfFitMatrixSize; i >= smallestMatrixSize; i -= 2)
                {
                    int borderZeroes = (trackedObject.PsfFitMatrixSize - i) / 2;
                    for (int x = 0; x < pixels.GetLength(0); x++)
                    {
                        for (int y = 0; y < borderZeroes; y++)
                        {
                            pixels[x, y] = 0;
                            pixels[x, pixels.GetLength(1) - y - 1] = 0;
                        }
                    }
                    for (int y = 0; y < pixels.GetLength(1); y++)
                    {
                        for (int x = 0; x < borderZeroes; x++)
                        {
                            pixels[x, y] = 0;
                            pixels[pixels.GetLength(0) - x - 1, y] = 0;
                        }
                    }

                    gaussian = new PSFFit(x0, y0);
                    gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize);
                    if (gaussian.IsSolved)
                    {
                        double dist = ImagePixel.ComputeDistance((float)gaussian.XCenter, (float)averageX, (float)gaussian.YCenter, (float)averageY);
                        if (dist <= PositionTolerance)
                        {
                            trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                            break;
                        }
                        else
                            trackedObject.SetIsLocated(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance);
                    }
                    else
                        trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }

                if (gaussian != null)
                {
                    if (!trackedObject.IsLocated)
                        trackedObject.SetIsLocated(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);

                    trackedObject.PSFFit = gaussian;
                    trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0);

                    trackedObject.ThisFrameX = (float)gaussian.XCenter;
                    trackedObject.ThisFrameY = (float)gaussian.YCenter;
                    trackedObject.ThisFrameCertainty = (float)gaussian.Certainty;
                }
            }
        }
Esempio n. 15
0
 public void SetIsTracked(bool isMeasured, NotMeasuredReasons reason, IImagePixel estimatedCenter, double? certainty)
 {
     Center = estimatedCenter;
     IsLocated = isMeasured;
 }
Esempio n. 16
0
        private void MeasureTrackedObject2(
			ITrackedObject trackedObject,
			MeasurementsHelper measurer,
			TangraConfig.PreProcessingFilter filter,
			bool synchronise,
			List<ITrackedObject> objectsInGroup,
			float refinedFWHM,
			float averageFWHM)
        {
            IImagePixel center = trackedObject.Center;
            int areaSize = 17;
            if ((objectsInGroup != null && objectsInGroup.Count > 1) || LightCurveReductionContext.Instance.NoiseMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                // for double PSF fits and/or 3d polynomial background fits we need the largest area
                areaSize = 35;

            IImagePixel[] groupCenters = new IImagePixel[0];
            float[] aperturesInGroup = new float[0];

            if (objectsInGroup != null && objectsInGroup.Count > 1)
            {
                groupCenters = new IImagePixel[objectsInGroup.Count];
                aperturesInGroup = new float[objectsInGroup.Count];

                for (int i = 0; i < objectsInGroup.Count; i++)
                {
                    groupCenters[i] = objectsInGroup[i].Center;
                    aperturesInGroup[i] = objectsInGroup[i].OriginalObject.ApertureInPixels;
                }
            }

            int areaDigitalFilterEdge = 0;
            if (LightCurveReductionContext.Instance.DigitalFilter != TangraConfig.PreProcessingFilter.NoFilter)
                areaDigitalFilterEdge = 2; // The extra 2 pixels will be cut after the filter is applied before the measurement

            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            uint[,] data = m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, areaSize + areaDigitalFilterEdge);
            uint[,] backgroundPixels = m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, 35 + areaDigitalFilterEdge);

            float msrX0 = (float)trackedObject.Center.XDouble;
            float msrY0 = (float)trackedObject.Center.YDouble;

            var measuredObject = new LCMeasurement()
            {
                CurrFrameNo = (uint) m_CurrFrameNo,
                CurrFileName = m_CurrFileName,
                TargetNo = (byte) trackedObject.TargetNo,
                X0 = msrX0,
                Y0 = msrY0,
                PixelDataX0 = centerX,
                PixelDataY0 = centerY,
                OSDTimeStamp = m_OCRedTimeStamp,
                FlagsDWORD = trackedObject.GetTrackingFlags()
            };

            IMeasurableObject measurableObject = (IMeasurableObject)trackedObject;

            NotMeasuredReasons rv = MeasureObject(
                center,
                data,
                backgroundPixels,
                m_VideoController.VideoBitPix,
                measurer,
                filter,
                LightCurveReductionContext.Instance.ReductionMethod,
                LightCurveReductionContext.Instance.PsfQuadratureMethod,
                TangraConfig.Settings.Photometry.PsfFittingMethod,
                trackedObject.OriginalObject.ApertureInPixels,
                refinedFWHM,
                averageFWHM,
                measurableObject,
                groupCenters,
                aperturesInGroup,
                LightCurveReductionContext.Instance.FullDisappearance);

            measuredObject.SetIsMeasured(rv);

            uint[,] pixelsToSave = trackedObject.IsOffScreen
                                       ? new uint[35, 35]
                                       // As the background may have been pre-processed for measuring, we need to take another copy for saving in the file
                                       : m_VideoController.GetCurrentAstroImage(false).GetMeasurableAreaPixels(centerX, centerY, 35);

            bool lockTaken = false;

            if (synchronise)
                m_WriterLock.TryEnter(ref lockTaken);

            try
            {
                uint flags = trackedObject.GetTrackingFlags();

                measuredObject.TotalReading = (uint)Math.Round(measurer.TotalReading);
                measuredObject.TotalBackground = (uint)Math.Round(measurer.TotalBackground);
                measuredObject.PixelData = pixelsToSave; /* save the original non filtered data */
                measuredObject.FlagsDWORD |= flags;
                measuredObject.ApertureX = measurer.XCenter;
                measuredObject.ApertureY = measurer.YCenter;
                measuredObject.ApertureSize = measurer.Aperture;

                m_LastTotalReading[trackedObject.TargetNo] = measuredObject.TotalReading;
                m_LastTotalBackground[trackedObject.TargetNo] = measuredObject.TotalBackground;
                m_LastApertureX[trackedObject.TargetNo] = measuredObject.ApertureX;
                m_LastApertureY[trackedObject.TargetNo] = measuredObject.ApertureY;
                m_LastApertureSize[trackedObject.TargetNo] = measuredObject.ApertureSize;
                m_LastOCRedTimeStamp[trackedObject.TargetNo] = measuredObject.OSDTimeStamp;

                LCFile.SaveOnTheFlyMeasurement(measuredObject);
            }
            finally
            {
                if (synchronise && lockTaken)
                    m_WriterLock.Exit();
            }
        }
Esempio n. 17
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

            // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location
            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup objectGroup = m_TrackedObjectGroups[i];
                objectGroup.NextFrame();

                if (objectGroup.TrackLater)
                {
                    // Group position will be determined after the rest of the stars are found
                }
                else
                {
                    if (objectGroup.IsSingleObject)
                    {
                        TrackedObjectLight trackedObject = (TrackedObjectLight)objectGroup.SingleObject;
                        uint[,] pixels = astroImage.GetPixelsArea(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y, 17);
                        var fit = new PSFFit(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y);
                        fit.FittingMethod = PSFFittingMethod.NonLinearFit;
                        fit.Fit(pixels);

                        if (fit.IsSolved)
                        {
                            if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                            }
                            else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                            }
                            else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                            }
                            else
                            {
                                trackedObject.SetTrackedObjectMatch(fit);
                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            }
                        }
                    }
                    else
                    {
                        string dbg = "";

                        int areaCenterX = (objectGroup.LastCenterObject1.X + objectGroup.LastCenterObject2.X) / 2;
                        int areaCenterY = (objectGroup.LastCenterObject1.Y + objectGroup.LastCenterObject2.Y) / 2;

                        uint[,] pixels = astroImage.GetPixelsArea(areaCenterX, areaCenterY, 35);
                        var doubleFit = new DoublePSFFit(areaCenterX, areaCenterY);

                        int x1 = objectGroup.LastCenterObject1.X - areaCenterX + 17;
                        int y1 = objectGroup.LastCenterObject1.Y - areaCenterY + 17;
                        int x2 = objectGroup.LastCenterObject2.X - areaCenterX + 17;
                        int y2 = objectGroup.LastCenterObject2.Y - areaCenterY + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                        {
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                        }
                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit fit1 = doubleFit.GetGaussian1();
                            PSFFit fit2 = doubleFit.GetGaussian2();

                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool groupIdentified = objectGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified)
                            {
                                dbg += "Ni-";
                                objectGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);

                                //Bitmap bmp = new Bitmap(100, 200);
                                //using (Graphics g = Graphics.FromImage(bmp))
                                //{
                                //	doubleFit.DrawInternalPoints(g, new Rectangle(0, 0, 100, 200), 5, 5, Brushes.Lime, Brushes.Yellow, 8);
                                //	g.Save();
                                //}
                                //bmp.Save(@"D:\Hristo\mutual_double_fit.bmp");
                                m_FailedGroupFits++;
                            }
                            else
                            {
                                PSFFit[]             fits           = new PSFFit[] { fit1, fit2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                int tooSmallCertainties = 0;
                                int errors = 0;

                                for (int j = 0; j < 2; j++)
                                {
                                    PSFFit             fit           = fits[j];
                                    TrackedObjectLight trackedObject = trackedObjects[j];

                                    if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                                    {
                                        tooSmallCertainties++;
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "TsGs-";
                                    }
                                    else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                                        dbg += "Fw-";
                                        errors++;
                                    }
                                    else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                                        dbg += "Elo-";
                                        errors++;
                                    }
                                    else
                                    {
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "Ts-";
                                    }
                                }

                                if (tooSmallCertainties == 2)
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    errors++;
                                    m_FailedGroupFits++;
                                    dbg += "Uncer-";
                                }

                                if (errors == 0)
                                {
                                    if (objectGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter))
                                    {
                                        trackedObjects[0].SetTrackedObjectMatch(fits[0]);
                                        trackedObjects[1].SetTrackedObjectMatch(fits[1]);
                                        m_FailedGroupFits = 0;
                                        dbg += "Id-";

                                        double dist = ImagePixel.ComputeDistance(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);
                                        if (dist < 2)
                                        {
                                            Trace.WriteLine("TOO CLOSE");
                                        }

                                        if (dist > 16)
                                        {
                                            Trace.WriteLine("TOO FAR");
                                        }
                                    }
                                    else
                                    {
                                        dbg += "NoId-";
                                    }
                                }
                            }
                        }
                        else
                        {
                            dbg += "NoSlv-";
                        }

                        objectGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            bool atLeastOneGroupLocated = false;

            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup trackedGroup = m_TrackedObjectGroups[i];

                if (!trackedGroup.IsSingleObject && trackedGroup.LastCenterObject1 != null && trackedGroup.LastCenterObject2 != null)
                {
                    Trace.WriteLine(string.Format("({0}, {1}, {2}) ({3},{4},{5}) [{6},{7}]",
                                                  trackedGroup.LastCenterObject1.XDouble, trackedGroup.LastCenterObject1.YDouble, trackedGroup.LastCenterObject1.Brightness,
                                                  trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject2.YDouble, trackedGroup.LastCenterObject2.Brightness,
                                                  trackedGroup.LastCenterObject1.XDouble - trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject1.YDouble - trackedGroup.LastCenterObject2.YDouble));
                }

                bool containsFullyDisappearingTarget = trackedGroup.ContainsOcultedStar && m_IsFullDisappearance;

                if (!containsFullyDisappearingTarget && trackedGroup.IsLocated)
                {
                    atLeastOneGroupLocated = true;
                }

                if (!containsFullyDisappearingTarget)
                {
                    continue;
                }

                int    numReferences = 0;
                double x_double;
                double y_double;

                if (trackedGroup.IsSingleObject && m_IsFullDisappearance)
                {
                    // This is the case for single fully disappearing targets
                    double totalX = 0;
                    double totalY = 0;
                    numReferences = 0;

                    for (int j = 0; j < m_TrackedObjectGroups.Count; j++)
                    {
                        TrackedObjectGroup referenceGroup = (TrackedObjectGroup)m_TrackedObjectGroups[j];
                        if (referenceGroup.IsLocated)
                        {
                            totalX += (trackedGroup.BrigherOriginalObject.ApertureStartingX - referenceGroup.BrigherOriginalObject.ApertureStartingX) + referenceGroup.BrigherObjectLastCenter.XDouble;
                            totalY += (trackedGroup.BrigherOriginalObject.ApertureStartingY - referenceGroup.BrigherOriginalObject.ApertureStartingY) + referenceGroup.BrigherObjectLastCenter.YDouble;
                            numReferences++;
                            atLeastOneGroupLocated = true;
                        }
                    }

                    x_double = totalX / numReferences;
                    y_double = totalY / numReferences;
                }
                else
                {
                    // The fully disappearing target is in a group. The other target would have been located. We use the last known position of the other targets
                    numReferences = 1;
                    x_double      = trackedGroup.NonOccultedObjectLastCenter.XDouble;
                    y_double      = trackedGroup.NonOccultedObjectLastCenter.YDouble;
                }


                if (numReferences == 0)
                {
                    trackedGroup.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated);
                }
                else
                {
                    int x = (int)(Math.Round(x_double));
                    int y = (int)(Math.Round(y_double));

                    uint[,] pixels = astroImage.GetPixelsArea(x, y, 35);

                    if (trackedGroup.IsSingleObject)
                    {
                        PSFFit fit = new PSFFit(x, y);

                        fit.Fit(pixels);

                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                        {
                            trackedGroup.SingleObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            trackedGroup.SingleObject.SetTrackedObjectMatch(fit);
                        }
                        else if (m_IsFullDisappearance)
                        {
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);
                        }
                        else
                        {
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                        }
                    }
                    else
                    {
                        string       dbg       = "";
                        DoublePSFFit doubleFit = new DoublePSFFit(x, y);

                        int x1 = trackedGroup.LastCenterObject1.X - x + 17;
                        int y1 = trackedGroup.LastCenterObject1.Y - y + 17;
                        int x2 = trackedGroup.LastCenterObject2.X - x + 17;
                        int y2 = trackedGroup.LastCenterObject2.Y - y + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                        {
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                        }

                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit             fit1    = doubleFit.GetGaussian1();
                            PSFFit             fit2    = doubleFit.GetGaussian2();
                            IImagePixel        center1 = null;
                            IImagePixel        center2 = null;
                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool resortToBrightness = false;
                            bool groupIdentified    = trackedGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified && m_IsFullDisappearance)
                            {
                                dbg               += "ReBr::";
                                groupIdentified    = trackedGroup.IdentifyBrightObject(fit1, fit2, STELLAR_OBJECT_MIN_CERTAINTY, out trackedObject1, out trackedObject2, out center1, out center2);
                                resortToBrightness = true;
                            }

                            if (!groupIdentified)
                            {
                                trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                dbg += "PsF::";
                            }
                            else
                            {
                                PSFFit[]             fits           = new PSFFit[] { fit1, fit2 };
                                IImagePixel[]        centers        = new IImagePixel[] { center1, center2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                bool objectCheckSuccessful = resortToBrightness
                                                                        ? trackedGroup.CheckIdentifiedObjects(center1.XDouble, center2.XDouble, center1.YDouble, center2.YDouble)
                                                                        : trackedGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);

                                if (objectCheckSuccessful)
                                {
                                    dbg += "ChS::";
                                    bool   atLeastOneOK = (fit1.IsSolved && fit1.Certainty > GUIDING_STAR_MIN_CERTAINTY) || (fit2.IsSolved && fit2.Certainty > GUIDING_STAR_MIN_CERTAINTY);
                                    double dist         = ImagePixel.ComputeDistance(fit1.XCenter, fit2.XCenter, fit1.YCenter, fit2.YCenter);

                                    if (!atLeastOneOK || ((dist < 2 || dist > 16) && !resortToBrightness))
                                    {
                                        trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                    }

                                    int cntOk = 0;
                                    for (int j = 0; j < 2; j++)
                                    {
                                        PSFFit             fit           = fits[j];
                                        IImagePixel        center        = centers[j];
                                        TrackedObjectLight trackedObject = trackedObjects[j];

                                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                                        {
                                            if (resortToBrightness && trackedObject.IsOccultedStar)
                                            {
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, center, fit.Certainty);
                                                dbg += "OccDi::";
                                            }
                                            else
                                            {
                                                trackedObject.SetTrackedObjectMatch(fit);
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                                dbg += "TrSuc::";
                                            }

                                            cntOk++;
                                        }
                                        else if (m_IsFullDisappearance && trackedObject.IsOccultedStar)
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, resortToBrightness ? center : null, 1);
                                            dbg += "BadCerSuc::";
                                        }
                                        else
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall, resortToBrightness ? center : null, resortToBrightness ? fit.Certainty : (double?)null);
                                            dbg += "BadCerNOSuc::";
                                        }
                                    }

                                    if (cntOk == 2)
                                    {
                                        m_FailedGroupFits = 0;
                                    }
                                }
                                else
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    m_FailedGroupFits++;
                                    dbg += "ChU::";
                                }
                            }
                        }
                        else
                        {
                            m_FailedGroupFits++;
                            dbg += "NoFi::";
                        }

                        trackedGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            IsTrackedSuccessfully = atLeastOneGroupLocated;

            if (IsTrackedSuccessfully)
            {
                RefinedAverageFWHM = m_TrackedObjects.Cast <TrackedObjectLight>().Average(x => x.RefinedFWHM);
            }

            if (m_FailedGroupFits > 10)
            {
                Trace.WriteLine("ERR~10+");
            }
        }
Esempio n. 18
0
        public NotMeasuredReasons MeasureObject(
            IImagePixel center,
            uint[,] data,
            uint[,] backgroundPixels,
            int bpp,
            TangraConfig.PreProcessingFilter filter,
            TangraConfig.PhotometryReductionMethod reductionMethod,
            TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            float aperture,
            double refinedFWHM,
            float refinedAverageFWHM,
            IMeasurableObject measurableObject,
            IImagePixel[] objectsInGroup,
            float[] aperturesInGroup,
            bool fullDisappearance)
        {
            // NOTE: This is how the center of the pixel area passed in data and background arrays is determined
            // TODO: Pass the center as an argument
            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            float msrX0 = (float)center.XDouble;
            float msrY0 = (float)center.YDouble;

            float bgAnnulusFactor = 1;

            switch (filter)
            {
            case TangraConfig.PreProcessingFilter.LowPassFilter:
                data             = ImageFilters.LowPassFilter(data, bpp, true);
                backgroundPixels = ImageFilters.LowPassFilter(backgroundPixels, bpp, true);
                break;

            case TangraConfig.PreProcessingFilter.LowPassDifferenceFilter:
                data             = ImageFilters.LowPassDifferenceFilter(data, bpp, true);
                backgroundPixels = ImageFilters.LowPassDifferenceFilter(backgroundPixels, bpp, true);
                break;

            default:
                break;
            }

            float modelFWHM = float.NaN;

            if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
            {
                if (TangraConfig.Settings.Photometry.UseUserSpecifiedFWHM)
                {
                    modelFWHM = TangraConfig.Settings.Photometry.UserSpecifiedFWHM;
                }
                else
                {
                    modelFWHM = refinedAverageFWHM;
                }
            }

            DoublePSFFit             doublefit       = null;
            PSFFit                   fit             = null;
            IBackgroundModelProvider backgroundModel = null;

            // 1 - Fit a PSF to the current obejct
            if (objectsInGroup != null && objectsInGroup.Length == 2)
            {
                // 1A - When this is a star group
                int x1 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[0].XDouble - center.XDouble);
                int y1 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[0].YDouble - center.YDouble);
                int x2 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[1].XDouble - center.XDouble);
                int y2 = (int)Math.Round((data.GetLength(0) / 2) + objectsInGroup[1].YDouble - center.YDouble);
                doublefit = new DoublePSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    doublefit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    doublefit.SetAveragedModelFWHM(modelFWHM);
                }

                doublefit.Fit(data, x1, y1, x2, y2);

                PSFFit star1 = doublefit.GetGaussian1();
                PSFFit star2 = doublefit.GetGaussian2();

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(data, star1, star2);

                    doublefit.Fit(data, bg3dFit, x1, y1, x2, y2);

                    star1           = doublefit.GetGaussian1();
                    star2           = doublefit.GetGaussian2();
                    backgroundModel = bg3dFit;
                }

                double d1 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X1Center, measurableObject.Center.YDouble, doublefit.Y1Center);
                double d2 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X2Center, measurableObject.Center.YDouble, doublefit.Y2Center);

                fit = (d1 < d2) ? star1 : star2;

                if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
                {
                    // NOTE: If aperture photometry is used, we measure the double object in a single larger aperture centered at the middle
                    double alpha = Math.Atan((star2.YCenter - star1.YCenter) / (star2.XCenter - star1.XCenter));

                    float dx = (float)((star1.FWHM - star2.FWHM) * Math.Cos(alpha));
                    float dy = (float)((star1.FWHM - star2.FWHM) * Math.Sin(alpha));

                    msrX0 = (float)(star1.XCenter - star1.FWHM + star2.XCenter + star2.FWHM) / 2.0f - dx;
                    msrY0 = (float)(star1.YCenter - star1.FWHM + star2.YCenter + star2.FWHM) / 2.0f - dy;

                    aperture        = aperturesInGroup.Sum();
                    bgAnnulusFactor = 0.67f;
                }
            }
            else if (reductionMethod != TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                // 1B - When this is a single star
                fit = new PSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    fit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    fit.SetAveragedModelFWHM(modelFWHM);
                }

                fit.Fit(data, measurableObject.PsfFittingMatrixSize);

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    // If 3D Poly Background is used then fit the background, and supply it to the PSF Fitting
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(backgroundPixels, fit, null);

                    backgroundModel = bg3dFit;

                    if (psfFittingMethod != TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                    {
                        /* 3D Poly modelling works in a direct fit only with non-linear fitting */
                        fit.Fit(backgroundPixels, bg3dFit, measurableObject.PsfFittingMatrixSize);
                    }
                }
            }
            else if (
                reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry &&
                m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
            {
                // 1C - Single star with aperture photometry and 3D Poly Background
                var bg3dFit = new Background3DPolynomialFit();
                bg3dFit.Fit(backgroundPixels, (float)(centerX - msrX0 + 17), (float)(centerY - msrY0 + 17), 2 * aperture);

                backgroundModel = bg3dFit;
            }

            // 2 - Do the actual photometric measurements (signal and background) based on the selected methods
            if (reductionMethod == TangraConfig.PhotometryReductionMethod.PsfPhotometry)
            {
                // 2A - PSF Photometry
                if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.DirectNonLinearFit)
                {
                    return(DoNonLinearProfileFittingPhotometry(
                               fit,
                               data, centerX, centerY, msrX0, msrY0,
                               aperture,
                               measurableObject.PsfFittingMatrixSize,
                               psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                               measurableObject.IsOccultedStar && fullDisappearance,
                               backgroundPixels,
                               measurableObject.MayHaveDisappeared,
                               refinedFWHM,
                               bgAnnulusFactor));
                }
                else if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                {
                    return(DoLinearProfileFittingOfAveragedMoodelPhotometry(
                               fit,
                               data, centerX, centerY, msrX0, msrY0, modelFWHM,
                               aperture,
                               measurableObject.PsfFittingMatrixSize,
                               psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                               measurableObject.IsOccultedStar && fullDisappearance,
                               backgroundPixels,
                               measurableObject.MayHaveDisappeared,
                               bgAnnulusFactor, backgroundModel));
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                return(DoAperturePhotometry(
                           data, centerX, centerY, msrX0, msrY0,
                           aperture,
                           measurableObject.PsfFittingMatrixSize,
                           backgroundPixels, bgAnnulusFactor, backgroundModel,
                           measurableObject.Center.X, measurableObject.Center.Y));
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.OptimalExtraction)
            {
                return(DoOptimalExtractionPhotometry(
                           fit,
                           data, centerX, centerY, msrX0, msrY0,
                           aperture,
                           measurableObject.PsfFittingMatrixSize,
                           measurableObject.IsOccultedStar && fullDisappearance,
                           backgroundPixels,
                           measurableObject.MayHaveDisappeared,
                           refinedFWHM, bgAnnulusFactor));
            }
            else
            {
                throw new ArgumentOutOfRangeException("reductionMethod");
            }
        }
Esempio n. 19
0
        public NotMeasuredReasons MeasureObject(
            IImagePixel center,
            uint[,] data,
            uint[,] backgroundPixels,
			int bpp,
            TangraConfig.PreProcessingFilter filter,
            TangraConfig.PhotometryReductionMethod reductionMethod,
			TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            float aperture,
            double refinedFWHM,
            float refinedAverageFWHM,
			IMeasurableObject measurableObject,
			IImagePixel[] objectsInGroup,
			float[] aperturesInGroup,
            bool fullDisappearance)
        {
            // NOTE: This is how the center of the pixel area passed in data and background arrays is determined
            // TODO: Pass the center as an argument
            int centerX = (int)Math.Round(center.XDouble);
            int centerY = (int)Math.Round(center.YDouble);

            float msrX0 = (float)center.XDouble;
            float msrY0 = (float)center.YDouble;

            float bgAnnulusFactor = 1;

            switch (filter)
            {
                case TangraConfig.PreProcessingFilter.LowPassFilter:
                    data = ImageFilters.LowPassFilter(data, bpp, true);
                    backgroundPixels = ImageFilters.LowPassFilter(backgroundPixels, bpp, true);
                    break;
                case TangraConfig.PreProcessingFilter.LowPassDifferenceFilter:
                    data = ImageFilters.LowPassDifferenceFilter(data, bpp, true);
                    backgroundPixels = ImageFilters.LowPassDifferenceFilter(backgroundPixels, bpp, true);
                    break;
                default:
                    break;
            }

            float modelFWHM = float.NaN;
            if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
            {
                if (TangraConfig.Settings.Photometry.UseUserSpecifiedFWHM)
                    modelFWHM = TangraConfig.Settings.Photometry.UserSpecifiedFWHM;
                else
                    modelFWHM = refinedAverageFWHM;
            }

            DoublePSFFit doublefit = null;
            PSFFit fit = null;
            IBackgroundModelProvider backgroundModel = null;

            // 1 - Fit a PSF to the current obejct
            if (objectsInGroup != null && objectsInGroup.Length == 2)
            {
                // 1A - When this is a star group
                int x1 = (int) Math.Round((data.GetLength(0)/2) + objectsInGroup[0].XDouble - center.XDouble);
                int y1 = (int) Math.Round((data.GetLength(0)/2) + objectsInGroup[0].YDouble - center.YDouble);
                int x2 = (int) Math.Round((data.GetLength(0)/2) + objectsInGroup[1].XDouble - center.XDouble);
                int y2 = (int) Math.Round((data.GetLength(0)/2) + objectsInGroup[1].YDouble - center.YDouble);
                doublefit = new DoublePSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    doublefit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    doublefit.SetAveragedModelFWHM(modelFWHM);
                }

                doublefit.Fit(data, x1, y1, x2, y2);

                PSFFit star1 = doublefit.GetGaussian1();
                PSFFit star2 = doublefit.GetGaussian2();

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(data, star1, star2);

                    doublefit.Fit(data, bg3dFit, x1, y1, x2, y2);

                    star1 = doublefit.GetGaussian1();
                    star2 = doublefit.GetGaussian2();
                    backgroundModel = bg3dFit;
                }

                double d1 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X1Center, measurableObject.Center.YDouble, doublefit.Y1Center);
                double d2 = ImagePixel.ComputeDistance(measurableObject.Center.XDouble, doublefit.X2Center, measurableObject.Center.YDouble, doublefit.Y2Center);

                fit = (d1 < d2) ? star1 : star2;

                if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
                {
                    // NOTE: If aperture photometry is used, we measure the double object in a single larger aperture centered at the middle
                    double alpha = Math.Atan((star2.YCenter - star1.YCenter) / (star2.XCenter - star1.XCenter));

                    float dx = (float)((star1.FWHM - star2.FWHM) * Math.Cos(alpha));
                    float dy = (float)((star1.FWHM - star2.FWHM) * Math.Sin(alpha));

                    msrX0 = (float)(star1.XCenter - star1.FWHM + star2.XCenter + star2.FWHM) / 2.0f - dx;
                    msrY0 = (float)(star1.YCenter - star1.FWHM + star2.YCenter + star2.FWHM) / 2.0f - dy;

                    aperture = aperturesInGroup.Sum();
                    bgAnnulusFactor = 0.67f;
                }
            }
            else if (reductionMethod != TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                // 1B - When this is a single star
                fit = new PSFFit(centerX, centerY);

                if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel &&
                    !float.IsNaN(modelFWHM))
                {
                    fit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                    fit.SetAveragedModelFWHM(modelFWHM);
                }

                fit.Fit(data, measurableObject.PsfFittingMatrixSize);

                if (m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
                {
                    // If 3D Poly Background is used then fit the background, and supply it to the PSF Fitting
                    var bg3dFit = new Background3DPolynomialFit();
                    bg3dFit.Fit(backgroundPixels, fit, null);

                    backgroundModel = bg3dFit;

                    if (psfFittingMethod != TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                        /* 3D Poly modelling works in a direct fit only with non-linear fitting */
                        fit.Fit(backgroundPixels, bg3dFit, measurableObject.PsfFittingMatrixSize);
                }
            }
            else if (
                reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry &&
                m_BackgroundMethod == TangraConfig.BackgroundMethod.Background3DPolynomial)
            {
                // 1C - Single star with aperture photometry and 3D Poly Background
                var bg3dFit = new Background3DPolynomialFit();
                bg3dFit.Fit(backgroundPixels, (float)(centerX - msrX0 + 17), (float)(centerY - msrY0 + 17), 2 * aperture);

                backgroundModel = bg3dFit;
            }

            // 2 - Do the actual photometric measurements (signal and background) based on the selected methods
            if (reductionMethod == TangraConfig.PhotometryReductionMethod.PsfPhotometry)
            {
                // 2A - PSF Photometry
                if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.DirectNonLinearFit)
                {
                    return DoNonLinearProfileFittingPhotometry(
                        fit,
                        data, centerX, centerY, msrX0, msrY0,
                        aperture,
                        measurableObject.PsfFittingMatrixSize,
                        psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                        measurableObject.IsOccultedStar && fullDisappearance,
                        backgroundPixels,
                        measurableObject.MayHaveDisappeared,
                        refinedFWHM,
                        bgAnnulusFactor);
                }
                else if (psfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                {
                    return DoLinearProfileFittingOfAveragedMoodelPhotometry(
                        fit,
                        data, centerX, centerY, msrX0, msrY0, modelFWHM,
                        aperture,
                        measurableObject.PsfFittingMatrixSize,
                        psfQuadrature == TangraConfig.PsfQuadrature.NumericalInAperture,
                        measurableObject.IsOccultedStar && fullDisappearance,
                        backgroundPixels,
                        measurableObject.MayHaveDisappeared,
                        bgAnnulusFactor, backgroundModel);
                }
                else
                    throw new NotImplementedException();
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.AperturePhotometry)
            {
                return DoAperturePhotometry(
                    data, centerX, centerY, msrX0, msrY0,
                    aperture,
                    measurableObject.PsfFittingMatrixSize,
                    backgroundPixels, bgAnnulusFactor, backgroundModel,
                    measurableObject.Center.X, measurableObject.Center.Y);
            }
            else if (reductionMethod == TangraConfig.PhotometryReductionMethod.OptimalExtraction)
            {
                return DoOptimalExtractionPhotometry(
                    fit,
                    data, centerX, centerY, msrX0, msrY0,
                    aperture,
                    measurableObject.PsfFittingMatrixSize,
                    measurableObject.IsOccultedStar && fullDisappearance,
                    backgroundPixels,
                    measurableObject.MayHaveDisappeared,
                    refinedFWHM, bgAnnulusFactor);
            }
            else
                throw new ArgumentOutOfRangeException("reductionMethod");
        }
Esempio n. 20
0
        internal static NotMeasuredReasons MeasureObject(
			IImagePixel center,
			uint[,] data,
			uint[,] backgroundPixels,
			int bpp,
			MeasurementsHelper measurer,
			TangraConfig.PreProcessingFilter filter,
			TangraConfig.PhotometryReductionMethod reductionMethod,
			TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittngMethod,
			float aperture,
			double refinedFWHM,
			float refinedAverageFWHM,
			IMeasurableObject measurableObject,
			IImagePixel[] groupCenters,
			float[] aperturesInGroup,
			bool fullDisappearance
			)
        {
            return measurer.MeasureObject(
                center, data, backgroundPixels, bpp, filter, reductionMethod, psfQuadrature, psfFittngMethod,
                aperture, refinedFWHM, refinedAverageFWHM, measurableObject, groupCenters, aperturesInGroup, fullDisappearance);
        }
Esempio n. 21
0
 public static double DistanceTo(this IImagePixel pixel1, double x, double y)
 {
     return(Math.Sqrt(Math.Pow(pixel1.XDouble - x, 2) + Math.Pow(pixel1.YDouble - y, 2)));
 }
Esempio n. 22
0
 public ImagePixel(IImagePixel clone)
     : this(uint.MinValue, clone.XDouble, clone.YDouble)
 {
 }
Esempio n. 23
0
 public ImagePixel(IImagePixel clone)
     : this(clone.Brightness, clone.XDouble, clone.YDouble)
 {
 }
Esempio n. 24
0
 private void LocateSingleNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
 {
     LocateNonGuidingObject(astroImage, trackedObject, newStaringPos);
 }
Esempio n. 25
0
        internal bool IdentifyBrightObject(PSFFit fit1, PSFFit fit2, float minStarCertainty, out TrackedObjectLight obj1, out TrackedObjectLight obj2, out IImagePixel center1, out IImagePixel center2)
        {
            double brightness1 = (fit1.Certainty > minStarCertainty ? fit1.Brightness : 1);
            double brightness2 = (fit2.Certainty > minStarCertainty ? fit2.Brightness : 1);
            double bDiff = Math.Abs(brightness1 - brightness2);
            double bRatio = bDiff / Math.Max(brightness1, brightness2);

            if (bRatio > 0.5)
            {
                bool fit1Brighter = brightness1 > brightness2;
                bool oldFit1Brighter = LastCenterObject1.Brightness > LastCenterObject2.Brightness;
                double oldDeltaXBrightFaint = oldFit1Brighter ? LastCenterObject1.XDouble - LastCenterObject2.XDouble : LastCenterObject2.XDouble - LastCenterObject1.XDouble;
                double oldDeltaYBrightFaint = oldFit1Brighter ? LastCenterObject1.YDouble - LastCenterObject2.YDouble : LastCenterObject2.YDouble - LastCenterObject1.YDouble;

                if (!(fit1Brighter ^ oldFit1Brighter))
                {
                    // 1 == 1; 2 == 2
                    if (fit1Brighter)
                    {
                        center1 = new ImagePixel((int)brightness1, fit1.XCenter, fit1.YCenter);
                        center2 = new ImagePixel((int)brightness2, fit1.XCenter - oldDeltaXBrightFaint, fit1.YCenter - oldDeltaYBrightFaint);
                        return Match1122(out obj1, out obj2);
                    }
                    else
                    {
                        center1 = new ImagePixel((int)brightness2, fit2.XCenter, fit2.YCenter);
                        center2 = new ImagePixel((int)brightness1, fit2.XCenter - oldDeltaXBrightFaint, fit2.YCenter - oldDeltaYBrightFaint);
                        return Match1122(out obj1, out obj2);
                    }
                }
                else
                {
                    // 1 == 2; 2 == 1
                    if (fit1Brighter)
                    {
                        center2 = new ImagePixel((int)brightness1, fit1.XCenter, fit1.YCenter);
                        center1 = new ImagePixel((int)brightness2, fit1.XCenter - oldDeltaXBrightFaint, fit1.YCenter - oldDeltaYBrightFaint);
                        return Match1212(out obj1, out obj2);
                    }
                    else
                    {
                        center2 = new ImagePixel((int)brightness2, fit2.XCenter, fit2.YCenter);
                        center1 = new ImagePixel((int)brightness1, fit2.XCenter - oldDeltaXBrightFaint, fit2.YCenter - oldDeltaYBrightFaint);
                        return Match1212(out obj1, out obj2);
                    }
                }
            }

            center1 = null;
            center2 = null;
            return NoMatch(out obj1, out obj2);
        }
Esempio n. 26
0
        private void LocateFixedApertureObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos)
        {
            double averageX = 0;
            double averageY = 0;

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

            trackedObject.SetIsLocated(true, NotMeasuredReasons.FixedObject);
            trackedObject.ThisFrameX = (float)averageX;
            trackedObject.ThisFrameY = (float)averageY;
            trackedObject.PSFFit = null;
            trackedObject.ThisSignalLevel = float.NaN;
            trackedObject.ThisFrameCertainty = float.NaN;
        }
Esempio n. 27
0
        public override void NextFrame(int frameNo, IAstroImage astroImage)
        {
            IsTrackedSuccessfully = false;

            // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location
            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup objectGroup = m_TrackedObjectGroups[i];
                objectGroup.NextFrame();

                if (objectGroup.TrackLater)
                {
                    // Group position will be determined after the rest of the stars are found
                }
                else
                {
                    if (objectGroup.IsSingleObject)
                    {
                        TrackedObjectLight trackedObject = (TrackedObjectLight) objectGroup.SingleObject;
                        uint[,] pixels = astroImage.GetPixelsArea(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y, 17);
                        var fit = new PSFFit(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y);
                        fit.FittingMethod = PSFFittingMethod.NonLinearFit;
                        fit.Fit(pixels);

                        if (fit.IsSolved)
                        {
                            if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                            }
                            else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                            }
                            else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                            {
                                trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                            }
                            else
                            {
                                trackedObject.SetTrackedObjectMatch(fit);
                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            }
                        }
                    }
                    else
                    {
                        string dbg = "";

                        int areaCenterX = (objectGroup.LastCenterObject1.X + objectGroup.LastCenterObject2.X) / 2;
                        int areaCenterY = (objectGroup.LastCenterObject1.Y + objectGroup.LastCenterObject2.Y) / 2;

                        uint[,] pixels = astroImage.GetPixelsArea(areaCenterX, areaCenterY, 35);
                        var doubleFit = new DoublePSFFit(areaCenterX, areaCenterY);

                        int x1 = objectGroup.LastCenterObject1.X - areaCenterX + 17;
                        int y1 = objectGroup.LastCenterObject1.Y - areaCenterY + 17;
                        int x2 = objectGroup.LastCenterObject2.X - areaCenterX + 17;
                        int y2 = objectGroup.LastCenterObject2.Y - areaCenterY + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;
                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit fit1 = doubleFit.GetGaussian1();
                            PSFFit fit2 = doubleFit.GetGaussian2();

                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool groupIdentified = objectGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified)
                            {
                                dbg += "Ni-";
                                objectGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);

                                //Bitmap bmp = new Bitmap(100, 200);
                                //using (Graphics g = Graphics.FromImage(bmp))
                                //{
                                //	doubleFit.DrawInternalPoints(g, new Rectangle(0, 0, 100, 200), 5, 5, Brushes.Lime, Brushes.Yellow, 8);
                                //	g.Save();
                                //}
                                //bmp.Save(@"D:\Hristo\mutual_double_fit.bmp");
                                m_FailedGroupFits++;
                            }
                            else
                            {
                                PSFFit[] fits = new PSFFit[] { fit1, fit2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                int tooSmallCertainties = 0;
                                int errors = 0;

                                for (int j = 0; j < 2; j++)
                                {
                                    PSFFit fit = fits[j];
                                    TrackedObjectLight trackedObject = trackedObjects[j];

                                    if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY)
                                    {
                                        tooSmallCertainties++;
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "TsGs-";
                                    }
                                    else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange);
                                        dbg += "Fw-";
                                        errors++;
                                    }
                                    else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION)
                                    {
                                        trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated);
                                        dbg += "Elo-";
                                        errors++;
                                    }
                                    else
                                    {
                                        trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                        dbg += "Ts-";
                                    }
                                }

                                if (tooSmallCertainties == 2)
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                                    errors++;
                                    m_FailedGroupFits++;
                                    dbg += "Uncer-";
                                }

                                if (errors == 0)
                                {
                                    if (objectGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter))
                                    {
                                        trackedObjects[0].SetTrackedObjectMatch(fits[0]);
                                        trackedObjects[1].SetTrackedObjectMatch(fits[1]);
                                        m_FailedGroupFits = 0;
                                        dbg += "Id-";

                                        double dist = ImagePixel.ComputeDistance(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);
                                        if (dist < 2)
                                        {
                                            Trace.WriteLine("TOO CLOSE");
                                        }

                                        if (dist > 16)
                                        {
                                            Trace.WriteLine("TOO FAR");
                                        }
                                    }
                                    else
                                    {
                                        dbg += "NoId-";
                                    }
                                }
                            }
                        }
                        else
                            dbg += "NoSlv-";

                        objectGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            bool atLeastOneGroupLocated = false;

            for (int i = 0; i < m_TrackedObjectGroups.Count; i++)
            {
                TrackedObjectGroup trackedGroup = m_TrackedObjectGroups[i];

                if (!trackedGroup.IsSingleObject && trackedGroup.LastCenterObject1 != null && trackedGroup.LastCenterObject2 != null)
                {
                    Trace.WriteLine(string.Format("({0}, {1}, {2}) ({3},{4},{5}) [{6},{7}]",
                        trackedGroup.LastCenterObject1.XDouble, trackedGroup.LastCenterObject1.YDouble, trackedGroup.LastCenterObject1.Brightness,
                        trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject2.YDouble, trackedGroup.LastCenterObject2.Brightness,
                        trackedGroup.LastCenterObject1.XDouble - trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject1.YDouble - trackedGroup.LastCenterObject2.YDouble));
                }

                bool containsFullyDisappearingTarget = trackedGroup.ContainsOcultedStar && m_IsFullDisappearance;

                if (!containsFullyDisappearingTarget && trackedGroup.IsLocated)
                    atLeastOneGroupLocated = true;

                if (!containsFullyDisappearingTarget)
                    continue;

                int numReferences = 0;
                double x_double;
                double y_double;

                if (trackedGroup.IsSingleObject && m_IsFullDisappearance)
                {
                    // This is the case for single fully disappearing targets
                    double totalX = 0;
                    double totalY = 0;
                    numReferences = 0;

                    for (int j = 0; j < m_TrackedObjectGroups.Count; j++)
                    {
                        TrackedObjectGroup referenceGroup = (TrackedObjectGroup)m_TrackedObjectGroups[j];
                        if (referenceGroup.IsLocated)
                        {
                            totalX += (trackedGroup.BrigherOriginalObject.ApertureStartingX - referenceGroup.BrigherOriginalObject.ApertureStartingX) + referenceGroup.BrigherObjectLastCenter.XDouble;
                            totalY += (trackedGroup.BrigherOriginalObject.ApertureStartingY - referenceGroup.BrigherOriginalObject.ApertureStartingY) + referenceGroup.BrigherObjectLastCenter.YDouble;
                            numReferences++;
                            atLeastOneGroupLocated = true;
                        }
                    }

                    x_double = totalX / numReferences;
                    y_double = totalY / numReferences;
                }
                else
                {
                    // The fully disappearing target is in a group. The other target would have been located. We use the last known position of the other targets
                    numReferences = 1;
                    x_double = trackedGroup.NonOccultedObjectLastCenter.XDouble;
                    y_double = trackedGroup.NonOccultedObjectLastCenter.YDouble;
                }

                if (numReferences == 0)
                {
                    trackedGroup.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated);
                }
                else
                {
                    int x = (int)(Math.Round(x_double));
                    int y = (int)(Math.Round(y_double));

                    uint[,] pixels = astroImage.GetPixelsArea(x, y, 35);

                    if (trackedGroup.IsSingleObject)
                    {
                        PSFFit fit = new PSFFit(x, y);

                        fit.Fit(pixels);

                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                        {
                            trackedGroup.SingleObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                            trackedGroup.SingleObject.SetTrackedObjectMatch(fit);
                        }
                        else if (m_IsFullDisappearance)
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound);
                        else
                            trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall);
                    }
                    else
                    {
                        string dbg = "";
                        DoublePSFFit doubleFit = new DoublePSFFit(x, y);

                        int x1 = trackedGroup.LastCenterObject1.X - x + 17;
                        int y1 = trackedGroup.LastCenterObject1.Y - y + 17;
                        int x2 = trackedGroup.LastCenterObject2.X - x + 17;
                        int y2 = trackedGroup.LastCenterObject2.Y - y + 17;

                        if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel)
                            doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel;

                        doubleFit.Fit(pixels, x1, y1, x2, y2);

                        if (doubleFit.IsSolved)
                        {
                            PSFFit fit1 = doubleFit.GetGaussian1();
                            PSFFit fit2 = doubleFit.GetGaussian2();
                            IImagePixel center1 = null;
                            IImagePixel center2 = null;
                            TrackedObjectLight trackedObject1;
                            TrackedObjectLight trackedObject2;

                            bool resortToBrightness = false;
                            bool groupIdentified = trackedGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2);
                            if (!groupIdentified && m_IsFullDisappearance)
                            {
                                dbg += "ReBr::";
                                groupIdentified = trackedGroup.IdentifyBrightObject(fit1, fit2, STELLAR_OBJECT_MIN_CERTAINTY, out trackedObject1, out trackedObject2, out center1, out center2);
                                resortToBrightness = true;
                            }

                            if (!groupIdentified)
                            {
                                trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                dbg += "PsF::";
                            }
                            else
                            {
                                PSFFit[] fits = new PSFFit[] { fit1, fit2 };
                                IImagePixel[] centers = new IImagePixel[] { center1, center2 };
                                TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 };

                                bool objectCheckSuccessful = resortToBrightness
                                    ? trackedGroup.CheckIdentifiedObjects(center1.XDouble, center2.XDouble, center1.YDouble, center2.YDouble)
                                    : trackedGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter);

                                if (objectCheckSuccessful)
                                {
                                    dbg += "ChS::";
                                    bool atLeastOneOK = (fit1.IsSolved && fit1.Certainty > GUIDING_STAR_MIN_CERTAINTY) || (fit2.IsSolved && fit2.Certainty > GUIDING_STAR_MIN_CERTAINTY);
                                    double dist = ImagePixel.ComputeDistance(fit1.XCenter, fit2.XCenter, fit1.YCenter, fit2.YCenter);

                                    if (!atLeastOneOK || ((dist < 2 || dist > 16) && !resortToBrightness))
                                    {
                                        trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed);
                                    }

                                    int cntOk = 0;
                                    for (int j = 0; j < 2; j++)
                                    {
                                        PSFFit fit = fits[j];
                                        IImagePixel center = centers[j];
                                        TrackedObjectLight trackedObject = trackedObjects[j];

                                        if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY)
                                        {
                                            if (resortToBrightness && trackedObject.IsOccultedStar)
                                            {
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, center, fit.Certainty);
                                                dbg += "OccDi::";
                                            }
                                            else
                                            {
                                                trackedObject.SetTrackedObjectMatch(fit);
                                                trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully);
                                                dbg += "TrSuc::";
                                            }

                                            cntOk++;
                                        }
                                        else if (m_IsFullDisappearance && trackedObject.IsOccultedStar)
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, resortToBrightness ? center : null, 1);
                                            dbg += "BadCerSuc::";
                                        }
                                        else
                                        {
                                            trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall, resortToBrightness ? center : null, resortToBrightness ? fit.Certainty : (double?)null);
                                            dbg += "BadCerNOSuc::";
                                        }
                                    }

                                    if (cntOk == 2)
                                    {
                                        m_FailedGroupFits = 0;
                                    }
                                }
                                else
                                {
                                    trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck);
                                    m_FailedGroupFits++;
                                    dbg += "ChU::";
                                }
                            }
                        }
                        else
                        {
                            m_FailedGroupFits++;
                            dbg += "NoFi::";
                        }

                        trackedGroup.ValidatePosition();
                        Trace.WriteLine(dbg);
                    }
                }
            }

            IsTrackedSuccessfully = atLeastOneGroupLocated;

            if (IsTrackedSuccessfully)
                RefinedAverageFWHM = m_TrackedObjects.Cast<TrackedObjectLight>().Average(x => x.RefinedFWHM);

            if (m_FailedGroupFits > 10)
            {
                Trace.WriteLine("ERR~10+");
            }
        }
Esempio n. 28
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);
            }
        }
Esempio n. 29
0
        protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage)
        {
            OccultedStar.NewFrame();
            m_NotCertain = false;
            float expectedX;
            float expectedY;

            GetExpectedXY(out expectedX, out expectedY);

            uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, 17);

            // 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)expectedX, (int)expectedY);

            gaussian.Fit(pixels, 17);

            IImagePixel firstCenter =
                gaussian.IsSolved
                    ? new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter)
                    : astroImage.GetCentroid((int)expectedX, (int)expectedY, 17, m_MedianValue);

            if (firstCenter != null)
            {
                // Do a second fit
                pixels   = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, 17);
                gaussian = new PSFFit(firstCenter.X, firstCenter.Y);
                gaussian.Fit(pixels, OccultedStar.PsfFitMatrixSize);
                if (gaussian.IsSolved)
                {
                    double signal = gaussian.IMax - gaussian.I0; if (signal < 0)
                    {
                        signal = 0;
                    }
                    double brightnessFluctoation = signal > OccultedStar.RefinedOrLastSignalLevel
                                                       ? signal / OccultedStar.RefinedOrLastSignalLevel
                                                       : OccultedStar.RefinedOrLastSignalLevel / signal;

                    //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel;
                    double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation;

                    if (fluckDiff < 1 || (LightCurveReductionContext.Instance.HighFlickeringOrLargeStars && !LightCurveReductionContext.Instance.FullDisappearance && !LightCurveReductionContext.Instance.IsDriftThrough))
                    {
                        OccultedStar.PSFFit             = gaussian;
                        OccultedStar.ThisFrameX         = (float)gaussian.XCenter;
                        OccultedStar.ThisFrameY         = (float)gaussian.YCenter;
                        OccultedStar.ThisSignalLevel    = (float)(gaussian.IMax - gaussian.I0);
                        OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                        OccultedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully);
                    }
                    else
                    {
                        m_NotCertain = true;

                        // This is the Occulted Star, so no brightness fluctoations can be used as excuses!
                        FitObjectInLimitedArea(OccultedStar, astroImage, expectedX, expectedY);
                        OccultedStar.SetIsLocated(
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null,
                            LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null
                                                                ? NotMeasuredReasons.TrackedSuccessfully
                                                                : NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar);

                        m_NotCertain = !OccultedStar.IsLocated;

                        if (m_PreviousPositions.Count > 1 && LightCurveReductionContext.Instance.FullDisappearance && LightCurveReductionContext.Instance.IsDriftThrough)
                        {
                            var prevSignals            = m_PreviousPositions.Select(x => x.Brightness).ToList();
                            var prevSignalMedian       = prevSignals.Median();
                            var prevSignalSigma        = Math.Sqrt(prevSignals.Sum(x => (x - prevSignalMedian) * (x - prevSignalMedian)) / (m_PreviousPositions.Count - 1));
                            var bigBrightnessVariation = (Math.Abs(signal - prevSignalMedian) > prevSignalSigma);
                            m_NotCertain = m_NotCertain || bigBrightnessVariation;
                        }

                        if (m_NotCertain)
                        {
                            OccultedStar.ThisFrameX         = expectedX;
                            OccultedStar.ThisFrameY         = expectedY;
                            OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;
                        }
                    }
                }
                else
                {
                    OccultedStar.ThisFrameX         = expectedX;
                    OccultedStar.ThisFrameY         = expectedY;
                    OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                    Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, OccultedStar.TargetNo));
                    OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
                }
            }
            else
            {
                OccultedStar.ThisFrameX         = expectedX;
                OccultedStar.ThisFrameY         = expectedY;
                OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty;

                Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo));
                OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed);
            }
        }
Esempio n. 30
0
 public static double DistanceTo(this IImagePixel pixel1, IImagePixel pixel2)
 {
     return Math.Sqrt(Math.Pow(pixel1.XDouble - pixel2.XDouble, 2) + Math.Pow(pixel1.YDouble - pixel2.YDouble, 2));
 }
Esempio n. 31
0
        private LCMeasurement ProcessSingleUnit(
            LCMeasurement reading,
            bool useLowPass,
            bool useLowPassDiff,
            int newFitMatrixSize,
            float newSignalAperture,
            bool fixedAperture,
            MeasurementsHelper measurer,
			IImagePixel[] groupCenters,
			float[] aperturesInGroup)
        {
            reading.ReProcessingPsfFitMatrixSize = newFitMatrixSize;

            TrackedObjectConfig objConfig = Footer.TrackedObjects[reading.TargetNo];
            ImagePixel center = new ImagePixel(reading.X0, reading.Y0);

            int areaSize = groupCenters != null && groupCenters.Length > 1 ? 35 : 17;

            if (Context.Filter != LightCurveContext.FilterType.NoFilter) areaSize += 2;

            uint[,] data = BitmapFilter.CutArrayEdges(reading.PixelData, (35 - areaSize) / 2);

            var filter = TangraConfig.PreProcessingFilter.NoFilter;
            if (useLowPassDiff) filter = TangraConfig.PreProcessingFilter.LowPassDifferenceFilter;
            else if (useLowPass) filter = TangraConfig.PreProcessingFilter.LowPassFilter;

            NotMeasuredReasons rv = ReduceLightCurveOperation.MeasureObject(
                center,
                data,
                reading.PixelData,
                Context.BitPix,
                measurer,
                filter,
                Context.SignalMethod,
                Context.PsfQuadratureMethod,
                Context.PsfFittingMethod,
                newSignalAperture,
                objConfig.RefinedFWHM,
                Footer.RefinedAverageFWHM,
                reading,
                groupCenters,
                aperturesInGroup,
                Footer.ReductionContext.FullDisappearance);

            reading.SetIsMeasured(rv);
            reading.TotalReading = (uint)measurer.TotalReading;
            reading.TotalBackground = (uint)measurer.TotalBackground;
            reading.ApertureX = measurer.XCenter;
            reading.ApertureY = measurer.YCenter;
            reading.ApertureSize = measurer.Aperture;

            return reading;
        }
Esempio n. 32
0
        public virtual void SetIsTracked(bool isMeasured, NotMeasuredReasons reason, IImagePixel estimatedCenter, double? psfCertainty)
        {
            IsLocated = isMeasured;

            // Remove the Tracked Successfully flag if set
            NotMeasuredReasons = (NotMeasuredReasons)((int)NotMeasuredReasons & ~(int)NotMeasuredReasons.TrackedSuccessfully);

            NotMeasuredReasons = (NotMeasuredReasons)((int)NotMeasuredReasons & 0x00FFFF) | reason;
            if (estimatedCenter != null)
            {
                Center = estimatedCenter;
                LastKnownGoodPosition = estimatedCenter;
            }

            if (psfCertainty != null)
                LastKnownGoodPsfCertainty = psfCertainty.Value;
        }
Esempio n. 33
0
        private void ProcessSingleUnitSet(
			List<LCMeasurement> units,
		    bool useLowPass,
		    bool useLowPassDiff,
		    MeasurementsHelper measurer)
        {
            for (int i = 0; i < units.Count; i++)
            {
                LCMeasurement reading = units[i];
                IImagePixel[] groupCenters = new IImagePixel[0];
                float[] aperturesInGroup = new float[0];

                TrackedObjectConfig objConfig = Footer.TrackedObjects[reading.TargetNo];
                List<TrackedObjectConfig> gropedObjects = Footer.TrackedObjects.Where(x => objConfig.GroupId >= 0 && x.GroupId == objConfig.GroupId).ToList();
                if (gropedObjects.Count > 1)
                {
                    groupCenters = new IImagePixel[gropedObjects.Count];
                    aperturesInGroup = new float[gropedObjects.Count];

                    for (int j = 0; j < gropedObjects.Count; j++)
                    {
                        LCMeasurement mea = units[Footer.TrackedObjects.IndexOf(gropedObjects[j])];
                        groupCenters[j] = new ImagePixel(mea.X0, mea.Y0);
                        aperturesInGroup[j] = gropedObjects[j].ApertureInPixels;
                    }
                }

                units[i] = ProcessSingleUnit(
                    reading, useLowPass, useLowPassDiff,
                    Context.ReProcessFitAreas[i], Context.ReProcessApertures[i], Header.FixedApertureFlags[i],
                    measurer, groupCenters, aperturesInGroup);
            }
        }