internal SpectraReader(AstroImage image, float angleDegrees) { m_Image = image; m_Mapper = new RotationMapper(image.Width, image.Height, angleDegrees); m_SourceVideoFrame = new RectangleF(0, 0, image.Width, image.Height); }
internal float LocateSpectraAngle(PSFFit selectedStar, AstroImage image) { float x0 = (float)selectedStar.XCenter; float y0 = (float)selectedStar.YCenter; uint brigthness10 = (uint)(0.1 * selectedStar.Brightness); uint brigthness20 = (uint)(0.2 * selectedStar.Brightness); uint brigthness40 = (uint)(0.4 * selectedStar.Brightness); uint bgFromPsf = (uint)(selectedStar.I0); int minDistance = (int)(10 * selectedStar.FWHM); int clearDist = (int)(2 * selectedStar.FWHM); float width = image.Width; float height = image.Height; uint[] angles = new uint[360]; uint[] sums = new uint[360]; uint[] pixAbove10Perc = new uint[360]; uint[] pixAbove20Perc = new uint[360]; uint[] pixAbove40Perc = new uint[360]; int diagonnalPixels = (int)Math.Ceiling(Math.Sqrt(image.Width * image.Width + image.Height * image.Height)); int iFrom = 0; int iTo = 360; bool peakFound = false; for (int i = iFrom; i < iTo; i++) { var mapper = new RotationMapper(image.Width, image.Height, i); PointF p1 = mapper.GetDestCoords(x0, y0); float x1 = p1.X; float y1 = p1.Y; uint rowSum = 0; uint pixAbove10 = 0; uint pixAbove10Max = 0; bool prevPixAbove10 = false; uint pixAbove20 = 0; uint pixAbove20Max = 0; bool prevPixAbove20 = false; uint pixAbove40 = 0; uint pixAbove40Max = 0; bool prevPixAbove40 = false; for (int d = minDistance; d < diagonnalPixels; d++) { PointF p = mapper.GetSourceCoords(x1 + d, y1); if (p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height) { uint value = (uint)image.GetPixel((int)p.X, (int)p.Y); rowSum += value; PointF pu = mapper.GetSourceCoords(x1 + d, y1 + clearDist); PointF pd = mapper.GetSourceCoords(x1 + d, y1 - clearDist); if (pu.X >= 0 && pu.X < width && pu.Y >= 0 && pu.Y < height && pd.X >= 0 && pd.X < width && pd.Y >= 0 && pd.Y < height) { uint value_u = (uint)image.GetPixel((int)pu.X, (int)pu.Y); uint value_d = (uint)image.GetPixel((int)pd.X, (int)pd.Y); if ((value - bgFromPsf) > brigthness10 && value > value_u && value > value_d) { if (prevPixAbove10) pixAbove10++; prevPixAbove10 = true; } else { prevPixAbove10 = false; if (pixAbove10Max < pixAbove10) pixAbove10Max = pixAbove10; pixAbove10 = 0; peakFound = true; } if ((value - bgFromPsf) > brigthness20 && value > value_u && value > value_d) { if (prevPixAbove20) pixAbove20++; prevPixAbove20 = true; } else { prevPixAbove20 = false; if (pixAbove20Max < pixAbove20) pixAbove20Max = pixAbove20; pixAbove20 = 0; peakFound = true; } if ((value - bgFromPsf) > brigthness40 && value > value_u && value > value_d) { if (prevPixAbove40) pixAbove40++; prevPixAbove40 = true; } else { prevPixAbove40 = false; if (pixAbove40Max < pixAbove40) pixAbove40Max = pixAbove40; pixAbove40 = 0; peakFound = true; } } else { prevPixAbove10 = false; if (pixAbove10Max < pixAbove10) pixAbove10Max = pixAbove10; pixAbove10 = 0; prevPixAbove20 = false; if (pixAbove20Max < pixAbove20) pixAbove20Max = pixAbove20; pixAbove20 = 0; prevPixAbove40 = false; if (pixAbove40Max < pixAbove40) pixAbove40Max = pixAbove40; pixAbove40 = 0; peakFound = true; } } } angles[i] = (uint)i; sums[i] = rowSum; pixAbove10Perc[i] = pixAbove10Max; pixAbove20Perc[i] = pixAbove20Max; pixAbove40Perc[i] = pixAbove40Max; } if (!peakFound) return float.NaN; var angles10 = new List<uint>(angles).ToArray(); var angles20 = new List<uint>(angles).ToArray(); var angles40 = new List<uint>(angles).ToArray(); Array.Sort(sums, angles); Array.Sort(pixAbove10Perc, angles10); Array.Sort(pixAbove20Perc, angles20); Array.Sort(pixAbove40Perc, angles40); uint roughAngle = angles[359]; if (pixAbove10Perc[358]*2 < pixAbove10Perc[359]) { // If second best at 10% id a lot smaller score than the top 10% scopem then this is it roughAngle = angles10[359]; } else { if (Math.Abs((int)angles[358] - (int)angles[359]) > 3)// or for large stars the two best can be sequential angles return float.NaN; } uint bestSum = 0; float bestAngle = 0f; for (float a = roughAngle - 1; a < roughAngle + 1; a += 0.02f) { var mapper = new RotationMapper(image.Width, image.Height, a); PointF p1 = mapper.GetDestCoords(x0, y0); float x1 = p1.X; float y1 = p1.Y; uint rowSum = 0; for (int d = minDistance; d < diagonnalPixels; d++) { PointF p = mapper.GetSourceCoords(x1 + d, y1); if (p.X >= 0 && p.X < width && p.Y >= 0 && p.Y < height) { uint pixVal = (uint)image.GetPixel((int)p.X, (int)p.Y); rowSum += pixVal; } } if (rowSum > bestSum) { bestSum = rowSum; bestAngle = a; } } return bestAngle; }