Example #1
0
        public void GaussianPeakErrorFunctionCheck()
        {
            var actual = new double[]
            {
                Photometry.GaussianPeakErrorFunction(35, 90, 7),
                Photometry.GaussianPeakErrorFunction(35, -20, 7)
            };

            Assert.AreEqual(4.4096209912536439, actual[0]);
            Assert.AreEqual(4.4096209912536439, actual[1]);
        }
Example #2
0
        public void AddStars(double minPeak, double maxPeak, double minWidth, double maxWidth, int starCount)
        {
            var drawThreshold = 5.0; // stop drawing the star when its this dim
            var stars         = new List <StarInfo>();

            for (var s = 0; s < starCount; s++)
            {
                var star = new StarInfo();

                star.Peak  = _rand.Next((int)(minPeak * 1000), (int)(maxPeak * 1000)) / 1000.0;
                star.Width = _rand.Next((int)(minWidth * 1000), (int)(maxWidth * 1000)) / 1000.0;

                var distance = 0;
                var value    = 0.0;

                do
                {
                    value = Photometry.GaussianAmplitudeFromPSF(distance * distance, star.Peak, star.Width);
                    distance++;
                }while (value > drawThreshold);

                star.PixelWidth = distance;

                var isOk = false;

                while (!isOk)
                {
                    star.X = _rand.Next(0, Image.Width - 1);
                    star.Y = _rand.Next(0, Image.Height - 1);

                    isOk = true;

                    foreach (var existingStar in Photo.Stars)
                    {
                        var existingWidthSqr = (existingStar.PixelWidth * existingStar.PixelWidth);
                        var starWidthSqr     = (star.PixelWidth * star.PixelWidth);
                        var xDistanceSqr     = (existingStar.X - star.X) * (existingStar.X - star.X);
                        var yDistanceSqr     = (existingStar.Y - star.Y) * (existingStar.Y - star.Y);

                        if (xDistanceSqr + yDistanceSqr < existingWidthSqr + starWidthSqr)
                        {
                            isOk = false;
                        }
                    }
                }

                AddStar(star);

                stars.Add(star);
            }

            Photo.Stars.AddRange(stars);
        }
Example #3
0
        public void GaussianPeakErrorFunctionSlopesTowardsAnswer()
        {
            var actual = new double[]
            {
                Photometry.GaussianPeakErrorSlopeFunction(4.0, 8, 7),
                Photometry.GaussianPeakErrorSlopeFunction(4.0, 5, 7),
                Photometry.GaussianPeakErrorSlopeFunction(4.0, 3, 7),
                Photometry.GaussianPeakErrorSlopeFunction(4.0, 0, 7)
            };

            Assert.AreEqual(+0.01166, Math.Round(actual[0], 5));
            Assert.AreEqual(+0.00292, Math.Round(actual[1], 5));
            Assert.AreEqual(-0.00292, Math.Round(actual[2], 5));
            Assert.AreEqual(-0.01166, Math.Round(actual[3], 5));
        }
Example #4
0
        public void FindStars()
        {
            var underperformed = new List <string>();

            for (var i = 0; i < 10; i++)
            {
                var matches          = 0;
                var image            = new Mat($"stars-{i}-1.png", ImreadModes.Unchanged);
                var photo            = JsonConvert.DeserializeObject <FakePhoto>(File.ReadAllText($"stars-{i}.json"));
                var unsaturatedStars = photo.Stars.Where(x => x.Peak < ushort.MaxValue).Count();

                var pixels = new ushort[image.Height * image.Width];
                var image2 = new Mat(image.Height, image.Width, MatType.CV_16SC1, pixels);

                image.ConvertTo(image2, MatType.CV_16SC1);

                var results = Photometry.FindStars(pixels, image.Width, image.Height, 10000);

                foreach (var result in results)
                {
                    foreach (var star in photo.Stars)
                    {
                        var distanceSq = (result.X - star.X) * (result.X - star.X) + (result.Y - star.Y) * (result.Y - star.Y);
                        if (distanceSq <= 1)
                        {
                            matches++;
                        }
                    }
                }

                if (matches < unsaturatedStars / 3)
                {
                    underperformed.Add($"stars-{i}.png");
                }
            }

            if (underperformed.Count > 0)
            {
                Assert.Fail("Found less than 33% of stars in some images");
            }
        }
Example #5
0
        void CheckStar(Mat image, StarInfo star)
        {
            var px = star.X;
            var py = star.Y;
            var distanceSquared = (px - star.X) * (px - star.X) + (py - star.Y) * (py - star.Y);
            var amplitude       = Photometry.GaussianAmplitudeFromPSF(distanceSquared, star.Peak, star.Width);
            var pixel           = (amplitude > ushort.MaxValue) ? ushort.MaxValue : (ushort)amplitude;

            if (Math.Abs(pixel - Math.Floor(star.Peak)) > 1 && star.Peak < ushort.MaxValue)
            {
                Assert.Fail("Peak star value from gaussian did not match predicted value");
            }

            var pixelValue = image.At <ushort>(star.Y, star.X);
            var peakOk     = pixel == pixelValue;

            if (!peakOk)
            {
                Assert.Fail("Peak star value in image did not match predicted value");
            }
        }
Example #6
0
        public void AddStar(StarInfo star)
        {
            var distance = star.PixelWidth;
            var value    = star.Peak;

            var x1 = star.X - distance;
            var y1 = star.Y - distance;
            var x2 = star.X + distance;
            var y2 = star.Y + distance;

            if (x1 < 0)
            {
                x1 = 0;
            }
            if (x2 >= Image.Width)
            {
                x2 = Image.Width - 1;
            }
            if (y1 < 0)
            {
                y1 = 0;
            }
            if (y2 >= Image.Height)
            {
                y2 = Image.Height - 1;
            }

            for (var py = y1; py < y2; py++)
            {
                for (var px = x1; px < x2; px++)
                {
                    var distanceSquared = (px - star.X) * (px - star.X) + (py - star.Y) * (py - star.Y);
                    var amplitude       = Photometry.GaussianAmplitudeFromPSF(distanceSquared, star.Peak, star.Width);
                    var pixel           = (amplitude > ushort.MaxValue) ? ushort.MaxValue : (ushort)amplitude;
                    Image.Set(py, px, pixel);
                }
            }
        }
Example #7
0
        public void GenerateFakeStarImages()
        {
            var minWidth = 1.0;
            var maxWidth = 2.0;

            for (var i = 0; i < 10; i++)
            {
                var simulator = new PhotoSimulator(_rand);

                simulator.AddStars(100, 500, minWidth, maxWidth, _rand.Next(1, 5));
                simulator.AddStars(500, 8000, minWidth, maxWidth, _rand.Next(1, 5));
                simulator.AddStars(8000, 60000, minWidth, maxWidth, _rand.Next(1, 5));
                simulator.AddStars(60000, 150000, minWidth, maxWidth, 3);

                CheckStars(simulator.Image, simulator.Photo.Stars);

                simulator.SaveAs16BitBitmap($"stars-{i}-1.png");

                simulator.AddHotPixels(_rand.Next(1, 10));
                simulator.SaveAs16BitBitmap($"stars-{i}-2.png");

                simulator.AddShotNoise();
                simulator.SaveAs16BitBitmap($"stars-{i}-3.png");

                simulator.AddReadNoise(_biasPath);
                simulator.SaveAs16BitBitmap($"stars-{i}-4.png");

                simulator.AddPRNUNoise();
                simulator.SaveAs16BitBitmap($"stars-{i}-5.png");

                var background = Photometry.FindSkyBackgroundIntensity(simulator.ImageArray);
                Photometry.Subtract(simulator.Image, (ushort)background);
                simulator.SaveAs16BitBitmap($"stars-{i}-6.png");

                File.WriteAllText($"stars-{i}.json", JsonConvert.SerializeObject(simulator.Photo));
            }
        }
Example #8
0
        public void FitStars()
        {
            var starCount = 0;

            var results = new List <FitStarTestResult>();

            var options = new List <GaussianFitOptions>
            {
                new GaussianFitOptions {
                    Radius = 2, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 3, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 4, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 5, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 6, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 7, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                },
                new GaussianFitOptions {
                    Radius = 8, MaxIterations = 1000, IterationStepSize = 10, MinimumChangeThreshold = 0.000001
                }
            };

            var sources   = new List <List <FitStarTest> >();
            var metadatas = new List <FakePhoto>();

            for (var i = 0; i < 10; i++)
            {
                var inputs = new Dictionary <string, string>
                {
                    { "No noise", $"stars-{i}-1.png" },
                    { "Hot pixels", $"stars-{i}-2.png" },
                    { "Hot pixels/shot noise", $"stars-{i}-3.png" },
                    { "Hot pixels/shot noise/read noise", $"stars-{i}-4.png" },
                    { "Hot pixels/shot noise/read noise/PRNU", $"stars-{i}-5.png" },
                    { "Hot pixels/shot noise/read noise/PRNU - BG removed", $"stars-{i}-6.png" }
                };

                var source = new List <FitStarTest>();

                foreach (var input in inputs)
                {
                    foreach (var option in options)
                    {
                        source.Add(new FitStarTest(input.Key, input.Value, option));
                    }
                }

                sources.Add(source);

                metadatas.Add(JsonConvert.DeserializeObject <FakePhoto>(File.ReadAllText($"stars-{i}.json")));
            }

            var start = DateTime.Now;

            for (var i = 0; i < 10; i++)
            {
                var metadata = metadatas[i];

                foreach (var source in sources[i])
                {
                    foreach (var star in metadata.Stars)
                    {
                        starCount++;

                        var fitOption = source.Options(star);
                        var fit       = Photometry.FindStarGaussianPSF(source.Image, source.ImageWidth, source.ImageHeight, star, 0, fitOption);

                        if (fit.Result == GaussianFitResult.Clipped)
                        {
                            continue;
                        }

                        results.Add(new FitStarTestResult
                        {
                            Name                   = source.Name(star),
                            Peak                   = star.Peak,
                            Width                  = star.Width,
                            Saturated              = star.Peak > ushort.MaxValue,
                            Estimated              = fit.Width,
                            Error                  = Math.Abs(fit.Width - star.Width),
                            Iterations             = fit.Iterations,
                            FitResult              = fit.Result.ToString(),
                            SampleRadius           = fitOption.Radius,
                            IterationStepSize      = fitOption.IterationStepSize,
                            MinimumChangeThreshold = fitOption.MinimumChangeThreshold,
                            MaxIterations          = fitOption.MaxIterations
                        });
                    }
                }
            }

            var end = DateTime.Now;

            var span           = end - start;
            var starsPerSecond = starCount / span.TotalSeconds;

            var output = new StringBuilder();

            output.AppendLine(FitStarTestResult.Header);

            foreach (var result in results)
            {
                output.AppendLine(result.ToString());
            }

            File.WriteAllText("D:\\p\\fit-tests.csv", output.ToString());
        }