public static Task <BitmapSource> Stretch(IRenderedImage image, double factor, double blackClipping) { return(Task.Run(async() => { var imageStatistics = await image.RawImageData.Statistics.Task; if (image.Image.Format == PixelFormats.Gray16) { using (var bmp = ImageUtility.BitmapFromSource(image.Image, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale)) { return Stretch(imageStatistics, bmp, image.Image.Format, factor, blackClipping); } } else if (image.Image.Format == PixelFormats.Rgb48) { using (var bmp = ImageUtility.BitmapFromSource(image.Image, System.Drawing.Imaging.PixelFormat.Format48bppRgb)) { return Stretch(imageStatistics, bmp, image.Image.Format, factor, blackClipping); } } else { throw new NotSupportedException(); } })); }
public void MeasureContrast(IProgress <ApplicationStatus> progress) { try { using (MyStopWatch.Measure()) { Stopwatch overall = Stopwatch.StartNew(); progress?.Report(new ApplicationStatus() { Status = "Preparing image for contrast measurement" }); _bitmapToAnalyze = ImageUtility.Convert16BppTo8Bpp(_originalBitmapSource); _token.ThrowIfCancellationRequested(); //Crop if there is ROI if (UseROI && InnerCropRatio < 1) { Rectangle cropRectangle = GetCropRectangle(InnerCropRatio); _bitmapToAnalyze = new Crop(cropRectangle).Apply(_bitmapToAnalyze); } if (_noiseReduction == NoiseReductionEnum.Median) { new Median().ApplyInPlace(_bitmapToAnalyze); } //Make sure resizing is independent of Star Sensitivity _resizefactor = (double)_maxWidth / _bitmapToAnalyze.Width; _inverseResizefactor = 1.0 / _resizefactor; /* Resize to speed up manipulation */ ResizeBitmapToAnalyze(); progress?.Report(new ApplicationStatus() { Status = "Measuring Contrast" }); _token.ThrowIfCancellationRequested(); if (ContrastDetectionMethod == ContrastDetectionMethodEnum.Laplace) { if (_noiseReduction == NoiseReductionEnum.None || _noiseReduction == NoiseReductionEnum.Median) { int[,] kernel = new int[7, 7]; kernel = LaplacianOfGaussianKernel(7, 1.0); new Convolution(kernel).ApplyInPlace(_bitmapToAnalyze); } else if (_noiseReduction == NoiseReductionEnum.Normal) { int[,] kernel = new int[9, 9]; kernel = LaplacianOfGaussianKernel(9, 1.4); new Convolution(kernel).ApplyInPlace(_bitmapToAnalyze); } else if (_noiseReduction == NoiseReductionEnum.High) { int[,] kernel = new int[11, 11]; kernel = LaplacianOfGaussianKernel(11, 1.8); new Convolution(kernel).ApplyInPlace(_bitmapToAnalyze); } else { int[,] kernel = new int[13, 13]; kernel = LaplacianOfGaussianKernel(13, 2.2); new Convolution(kernel).ApplyInPlace(_bitmapToAnalyze); } //Get mean and standard dev Accord.Imaging.ImageStatistics stats = new Accord.Imaging.ImageStatistics(_bitmapToAnalyze); AverageContrast = stats.GrayWithoutBlack.Mean; ContrastStdev = 0.01; //Stdev of convoluted image is not a measure of error - using same figure for all } else if (ContrastDetectionMethod == ContrastDetectionMethodEnum.Sobel) { if (_noiseReduction == NoiseReductionEnum.None || _noiseReduction == NoiseReductionEnum.Median) { //Nothing to do } else if (_noiseReduction == NoiseReductionEnum.Normal) { _bitmapToAnalyze = new FastGaussianBlur(_bitmapToAnalyze).Process(1); } else if (_noiseReduction == NoiseReductionEnum.High) { _bitmapToAnalyze = new FastGaussianBlur(_bitmapToAnalyze).Process(2); } else { _bitmapToAnalyze = new FastGaussianBlur(_bitmapToAnalyze).Process(3); } int[,] kernel = { { -1, -2, 0, 2, 1 }, { -2, -4, 0, 4, 2 }, { 0, 0, 0, 0, 0 }, { 2, 4, 0, -4, -2 }, { 1, 2, 0, -2, -1 } }; new Convolution(kernel).ApplyInPlace(_bitmapToAnalyze); //Get mean and standard dev Accord.Imaging.ImageStatistics stats = new Accord.Imaging.ImageStatistics(_bitmapToAnalyze); AverageContrast = stats.GrayWithoutBlack.Mean; ContrastStdev = 0.01; //Stdev of convoluted image is not a measure of error - using same figure for all } _token.ThrowIfCancellationRequested(); _bitmapToAnalyze.Dispose(); overall.Stop(); Debug.Print("Overall contrast detection: " + overall.Elapsed); overall = null; } } catch (OperationCanceledException) { } finally { progress?.Report(new ApplicationStatus() { Status = string.Empty }); } return; }
public void Detect(IProgress <ApplicationStatus> progress) { try { using (MyStopWatch.Measure()) { progress?.Report(new ApplicationStatus() { Status = "Preparing image for star detection" }); _bitmapToAnalyze = ImageUtility.Convert16BppTo8Bpp(_originalBitmapSource); _token.ThrowIfCancellationRequested(); /* Perform initial noise reduction on full size image if necessary */ if (_noiseReduction != NoiseReductionEnum.None) { ReduceNoise(); } /* Resize to speed up manipulation */ ResizeBitmapToAnalyze(); /* prepare image for structure detection */ PrepareForStructureDetection(_bitmapToAnalyze); progress?.Report(new ApplicationStatus() { Status = "Detecting structures" }); /* get structure info */ _blobCounter = DetectStructures(_bitmapToAnalyze); progress?.Report(new ApplicationStatus() { Status = "Analyzing stars" }); _starlist = IdentifyStars(); _token.ThrowIfCancellationRequested(); if (_starlist.Count > 0) { var m = (from star in _starlist select star.HFR).Average(); var s = Math.Sqrt(((from star in _starlist select star.HFR * star.HFR).Sum() - _starlist.Count() * m * m) / _starlist.Count()); Logger.Info($"Average HFR: {m}, HFR σ: {s}, Detected Stars {_starlist.Count}"); //todo change AverageHFR = m; HFRStdDev = double.IsNaN(s) ? 0 : s; DetectedStars = _starlist.Count; } _blobCounter = null; _bitmapToAnalyze.Dispose(); } } catch (OperationCanceledException) { } finally { progress?.Report(new ApplicationStatus() { Status = string.Empty }); } return; }
public BahtinovImage GrabBahtinov() { var bahtinovImage = new BahtinovImage(); Bitmap convertedSource; if (originalSource.Format != System.Windows.Media.PixelFormats.Gray8) { if (originalSource.Format != System.Windows.Media.PixelFormats.Gray16) { using (var imgToConvert = ImageUtility.BitmapFromSource(originalSource, System.Drawing.Imaging.PixelFormat.Format48bppRgb)) { convertedSource = new Grayscale(0.2125, 0.7154, 0.0721).Apply(imgToConvert); } convertedSource = ImageUtility.Convert16BppTo8Bpp(ImageUtility.ConvertBitmap(convertedSource, System.Windows.Media.PixelFormats.Gray16)); } else { convertedSource = ImageUtility.Convert16BppTo8Bpp(originalSource); } } else { convertedSource = ImageUtility.BitmapFromSource(originalSource, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); convertedSource.Palette = ImageUtility.GetGrayScalePalette(); } using (var focusEllipsePen = new System.Drawing.Pen(System.Drawing.Brushes.Green, 1)) { using (var intersectEllipsePen = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1)) { var mediaColor = backgroundColor; var drawingColor = System.Drawing.Color.FromArgb(mediaColor.A, mediaColor.R, mediaColor.G, mediaColor.B); using (var linePen = new System.Drawing.Pen(drawingColor, 1)) { using (var bahtinovedBitmap = new Bitmap(convertedSource.Width, convertedSource.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) { Graphics graphics = Graphics.FromImage(bahtinovedBitmap); graphics.DrawImage(convertedSource, 0, 0); /* Apply filters and detection*/ CannyEdgeDetector filter = new CannyEdgeDetector(); filter.GaussianSize = 10; filter.ApplyInPlace(convertedSource); HoughLineTransformation lineTransform = new HoughLineTransformation(); lineTransform.ProcessImage(convertedSource); HoughLine[] lines = lineTransform.GetMostIntensiveLines(6); List <Line> bahtinovLines = new List <Line>(); foreach (HoughLine line in lines) { var k = TranslateHughLineToLine(line, bahtinovedBitmap.Width, bahtinovedBitmap.Height); bahtinovLines.Add(k); } float x1, x2, y1, y2; if (bahtinovLines.Count == 6) { var orderedPoints = bahtinovLines.OrderBy(x => 1.0d / x.Slope).ToList(); var threeLines = new List <Line>(); for (var i = 0; i < orderedPoints.Count(); i += 2) { var l1 = orderedPoints[i]; var l2 = orderedPoints[i + 1]; var inter = (l1.Intercept + l2.Intercept) / 2.0f; var slope = (l1.Slope + l2.Slope) / 2.0f; var centerLine = Line.FromSlopeIntercept(slope, inter); threeLines.Add(centerLine); x1 = 0; x2 = convertedSource.Width; y1 = double.IsInfinity(centerLine.Slope) ? centerLine.Intercept : centerLine.Slope + centerLine.Intercept; y2 = double.IsInfinity(centerLine.Slope) ? centerLine.Intercept : (centerLine.Slope * (convertedSource.Width) + centerLine.Intercept); graphics.DrawLine( linePen, new PointF(x1, y1), new PointF(x2, y2)); } /* Intersect outer bahtinov lines */ var intersection = threeLines[0].GetIntersectionWith(threeLines[2]); if (intersection.HasValue) { /* get orthogonale to center line through intersection */ var centerBahtinovLine = threeLines[1]; var orthogonalSlope = -1.0f / centerBahtinovLine.Slope; var orthogonalIntercept = intersection.Value.Y - orthogonalSlope * intersection.Value.X; var orthogonalCenter = Line.FromSlopeIntercept(orthogonalSlope, orthogonalIntercept); var intersection2 = centerBahtinovLine.GetIntersectionWith(orthogonalCenter); if (intersection2.HasValue && !double.IsInfinity(intersection2.Value.X)) { x1 = intersection.Value.X; y1 = intersection.Value.Y; x2 = intersection2.Value.X; y2 = intersection2.Value.Y; bahtinovImage.Distance = intersection.Value.DistanceTo(intersection2.Value); var t = bahtinovImage.Distance * 4 / bahtinovImage.Distance; var x3 = (float)((1 - t) * x1 + t * x2); var y3 = (float)((1 - t) * y1 + t * y2); var r = 10; graphics.DrawEllipse( intersectEllipsePen, new RectangleF(x3 - r, y3 - r, 2 * r, 2 * r)); graphics.DrawEllipse( focusEllipsePen, new RectangleF(x2 - r, y2 - r, 2 * r, 2 * r)); graphics.DrawLine( intersectEllipsePen, new PointF(x3, y3), new PointF(x2, y2)); } } } var img = ImageUtility.ConvertBitmap(bahtinovedBitmap, System.Windows.Media.PixelFormats.Bgr24); convertedSource.Dispose(); img.Freeze(); bahtinovImage.Image = img; return(bahtinovImage); } } } } }