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; }
public void PostDraw(Graphics g) { if (SelectedStar != null) { if (m_OperationState == SpectroscopyState.ChoosingAngleManually && SelectedAnglePoint != Point.Empty) { PointF p1 = new PointF((float)SelectedStar.XDouble, (float)SelectedStar.YDouble); g.DrawLine(Pens.Aqua, p1, SelectedAnglePoint); } else if (m_OperationState == SpectroscopyState.StarConfirmed || m_OperationState == SpectroscopyState.RunningMeasurements) { g.DrawEllipse(Pens.Aqua, (float)SelectedStar.XDouble - 5, (float)SelectedStar.YDouble - 5, 10, 10); var mapper = new RotationMapper(m_OriginalWidth, m_OriginalHeight, SelectedStarBestAngle); float halfWidth = (float)MeasurementAreaWing; float bgGap = (float)BackgroundAreaGap; float bgSide = (float)BackgroundAreaWing; PointF p0 = mapper.GetDestCoords((float)SelectedStar.XDouble, (float)SelectedStar.YDouble); for (float i = p0.X - mapper.MaxDestDiagonal; i < p0.X + mapper.MaxDestDiagonal; i++) { PointF p1 = mapper.GetSourceCoords(i, p0.Y - halfWidth); PointF p2 = mapper.GetSourceCoords(i + 1, p0.Y - halfWidth); if (m_OriginalVideoFrame.Contains(p1) && m_OriginalVideoFrame.Contains(p2)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraAperturePen, p1, p2); } PointF p3 = mapper.GetSourceCoords(i, p0.Y + halfWidth); PointF p4 = mapper.GetSourceCoords(i + 1, p0.Y + halfWidth); if (m_OriginalVideoFrame.Contains(p3) && m_OriginalVideoFrame.Contains(p4)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraAperturePen, p3, p4); } p1 = mapper.GetSourceCoords(i, p0.Y - halfWidth - bgGap); p2 = mapper.GetSourceCoords(i + 1, p0.Y - halfWidth - bgGap); if (m_OriginalVideoFrame.Contains(p1) && m_OriginalVideoFrame.Contains(p2)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraBackgroundPen, p1, p2); } p3 = mapper.GetSourceCoords(i, p0.Y + halfWidth + bgGap); p4 = mapper.GetSourceCoords(i + 1, p0.Y + halfWidth + bgGap); if (m_OriginalVideoFrame.Contains(p3) && m_OriginalVideoFrame.Contains(p4)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraBackgroundPen, p3, p4); } p1 = mapper.GetSourceCoords(i, p0.Y - halfWidth - bgSide - bgGap); p2 = mapper.GetSourceCoords(i + 1, p0.Y - halfWidth - bgSide - bgGap); if (m_OriginalVideoFrame.Contains(p1) && m_OriginalVideoFrame.Contains(p2)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraBackgroundPen, p1, p2); } p3 = mapper.GetSourceCoords(i, p0.Y + halfWidth + bgSide + bgGap); p4 = mapper.GetSourceCoords(i + 1, p0.Y + halfWidth + bgSide + bgGap); if (m_OriginalVideoFrame.Contains(p3) && m_OriginalVideoFrame.Contains(p4)) { g.DrawLine(m_SpectroscopyController.DisplaySettings.SpectraBackgroundPen, p3, p4); } } } } }
internal float LocateSpectraAngle(PSFFit selectedStar, int?roughStartingAngle = null) { 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); AstroImage image = m_VideoController.GetCurrentAstroImage(false); 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; if (roughStartingAngle.HasValue) { iFrom = roughStartingAngle.Value - 10; iTo = roughStartingAngle.Value + 10; } 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 = image.Pixelmap[(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 = image.Pixelmap[(int)pu.X, (int)pu.Y]; uint value_d = image.Pixelmap[(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 = image.Pixelmap[(int)p.X, (int)p.Y]; rowSum += pixVal; } } if (rowSum > bestSum) { bestSum = rowSum; bestAngle = a; } } return(bestAngle); }