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); }
/// <summary> /// Find a sigma value for the Gaussian Point Distribution Function that produces less error /// </summary> /// <param name="image"></param> /// <param name="star"></param> /// <param name="starReference"></param> /// <param name="options"></param> static GaussianFit FindGaussianPSF(ushort[] image, int iWidth, int iHeight, StarInfo star, int starReference, GaussianFitOptions options) { var peak = star.Peak; var width = GaussianSigmaFromSample(star.Peak, 2, image[(star.Y + 1) * iWidth + star.X + 1]); var widthStep = 1.0; var iterations = 0; // happens when the star is saturated if (double.IsInfinity(width) || width == 0) { width = 5.0; } var x1 = star.X - options.Radius; var x2 = star.X + options.Radius; var y1 = star.Y - options.Radius; var y2 = star.Y + options.Radius; if (x1 < 0 || y1 < 0 || x2 > iWidth || y2 > iHeight) { return(new GaussianFit { Result = GaussianFitResult.Clipped }); } for (iterations = 0; iterations < options.MaxIterations && Math.Abs(widthStep) > options.MinimumChangeThreshold; iterations++) { var direction = GradientTowardsMinimalErrorForGaussian(peak, width, image, iWidth, iHeight, star, options); widthStep = options.IterationStepSize * direction[0]; width = width + widthStep; if (width < 0) { width = 1.0; } } return(new GaussianFit { Width = width, Peak = peak, Iterations = iterations, StarReference = starReference, Result = iterations == options.MaxIterations ? GaussianFitResult.IterationsMaxed : GaussianFitResult.StepMinimumReached }); }
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"); } }
public void NewTestScriptSimplePasses() { StarData s = new StarData(); var starList = s.getStarList(); // Sets the starList to the one obtained from reading the database StarInfo k = new StarInfo(); for (int i = 0; i < starList.Count; i++) { string properName = starList[i][0]; //Name to be displayed (Not yet implemented) double magnitude = k.Magntitude(starList[i][1]); //Not yet used but is the visibility of star in sky double angle = k.ConvertAngle(starList[i][2], starList[i][3]); //Gets vertical angle at which to spawn the star in deg double azimuth = k.ConvertAzimuth(starList[i][2], starList[i][3]); //Gets azimuth (horizontal position) at which to spawn star in deg // Use the Assert class to test conditions Debug.Log("Name" + properName); Debug.Log("angle:" + angle); Debug.Log("azimth:" + azimuth); Debug.Log("Mag:" + magnitude); } }
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); } } }
/// <summary> /// /// </summary> /// <param name="image"></param> /// <param name="iWidth"></param> /// <param name="iHeight"></param> /// <param name="star"></param> /// <param name="starReference"></param> /// <param name="options"></param> /// <returns></returns> public static GaussianFit FindStarGaussianPSF(ushort[] image, int iWidth, int iHeight, StarInfo star, int starReference, GaussianFitOptions options) { return(FindGaussianPSF(image, iWidth, iHeight, star, starReference, options)); }
public static double GaussianFitError(double peak, double width, ushort[] pixels, int iWidth, int iHeight, StarInfo star, GaussianFitOptions options) { var samples = (options.Radius * 2.0) * (options.Radius * 2.0) - 1; var x1 = star.X - options.Radius; var x2 = star.X + options.Radius; var y1 = star.Y - options.Radius; var y2 = star.Y + options.Radius; var error = 0.0; for (var y = y1; y < y2; y++) { for (var x = x1; x < x2; x++) { if (x == star.X && y == star.Y) { continue; } var distanceSquared = (x - star.X) * (x - star.X) + (y - star.Y) * (y - star.Y); if (distanceSquared <= options.Radius * 2) { var prediction = GaussianAmplitudeFromPSF(distanceSquared, peak, width); error += (prediction - pixels[y * iWidth + x]) * (prediction - pixels[y * iWidth + x]); } } } return(error); }
public static double[] GradientTowardsMinimalErrorForGaussian(double peak, double sigma, ushort[] pixels, int iWidth, int iHeight, StarInfo star, GaussianFitOptions options) { var vec = new double[1]; var samples = (options.Radius * 2.0) * (options.Radius * 2.0) - 1; var x1 = star.X - options.Radius; var x2 = star.X + options.Radius; var y1 = star.Y - options.Radius; var y2 = star.Y + options.Radius; for (var y = y1; y < y2; y++) { for (var x = x1; x < x2; x++) { if (x == star.X && y == star.Y) { continue; } var distanceSquared = (x - star.X) * (x - star.X) + (y - star.Y) * (y - star.Y); if (distanceSquared <= options.Radius * 2) { var sample = pixels[y * iWidth + x]; var sigmaSample = GaussianSigmaFromSample(peak, distanceSquared, sample); var sChange = GaussianSigmaErrorSlopeFunction(distanceSquared, peak, sigmaSample, sigma); vec[0] += (-1 * sChange); samples++; } } } vec[0] /= samples; return(vec); }