Пример #1
0
        private static byte[] UncompressData(byte[] raw, XISFCompressionInfo compressionInfo)
        {
            byte[] outArray = null;

            if (compressionInfo.CompressionType != XISFCompressionTypeEnum.NONE)
            {
                outArray = new byte[compressionInfo.UncompressedSize];

                using (MyStopWatch.Measure($"XISF Decompression = {compressionInfo.CompressionType}")) {
                    switch (compressionInfo.CompressionType)
                    {
                    case XISFCompressionTypeEnum.LZ4:
                    case XISFCompressionTypeEnum.LZ4HC:
                        int size = LZ4Codec.Decode(raw, 0, raw.Length, outArray, 0, compressionInfo.UncompressedSize);

                        if (size != compressionInfo.UncompressedSize)
                        {
                            Logger.Error($"XISF: Indicated uncompressed size does not equal actual size: Indicated: {compressionInfo.UncompressedSize}, Actual: {size}");
                        }

                        break;

                    case XISFCompressionTypeEnum.ZLIB:
                        outArray = ZlibStream.UncompressBuffer(raw);
                        break;
                    }
                }
            }

            return(outArray);
        }
Пример #2
0
 private async void ResizeTimer_Tick(object sender, EventArgs e)
 {
     using (MyStopWatch.Measure()) {
         (sender as DispatcherTimer).Stop();
         await LoadImage();
     }
 }
Пример #3
0
        public bool SelectProfile(ProfileMeta info)
        {
            lock (lockobj) {
                using (MyStopWatch.Measure()) {
                    try {
                        var p = Profile.Load(info.Location);

                        UnregisterChangedEventHandlers();
                        if (ActiveProfile != null)
                        {
                            ActiveProfile.Dispose();
                            Profiles.Where(x => x.Id == ActiveProfile.Id).First().IsActive = false;
                        }

                        ActiveProfile = p;
                        info.IsActive = true;

                        System.Threading.Thread.CurrentThread.CurrentUICulture = ActiveProfile.ApplicationSettings.Language;
                        System.Threading.Thread.CurrentThread.CurrentCulture   = ActiveProfile.ApplicationSettings.Language;
                        Locale.Loc.Instance.ReloadLocale(ActiveProfile.ApplicationSettings.Culture);

                        LocaleChanged?.Invoke(this, null);
                        ProfileChanged?.Invoke(this, null);
                        LocationChanged?.Invoke(this, null);
                        RegisterChangedEventHandlers();
                    } catch (Exception ex) {
                        Logger.Debug(ex.Message + Environment.NewLine + ex.StackTrace);
                        return(false);
                    }
                    return(true);
                }
            }
        }
Пример #4
0
        private static ushort[] FlipAndConvert2d(Array input)
        {
            using (MyStopWatch.Measure("FlipAndConvert2d")) {
                Int32[,] arr = (Int32[, ])input;
                int width  = arr.GetLength(0);
                int height = arr.GetLength(1);

                int      length    = width * height;
                ushort[] flatArray = new ushort[length];
                ushort   value;

                unsafe
                {
                    fixed(Int32 *ptr = arr)
                    {
                        int idx = 0, row = 0;

                        for (int i = 0; i < length; i++)
                        {
                            value = (ushort)ptr[i];

                            idx = ((i % height) * width) + row;
                            if ((i % (height)) == (height - 1))
                            {
                                row++;
                            }

                            ushort b = value;
                            flatArray[idx] = b;
                        }
                    }
                }
                return(flatArray);
            }
        }
Пример #5
0
        public static BitmapSource Stretch(IImageStatistics statistics, Bitmap img, System.Windows.Media.PixelFormat pf, double factor, double blackClipping)
        {
            using (MyStopWatch.Measure()) {
                var filter = ImageUtility.GetColorRemappingFilter(statistics, factor, blackClipping, pf);
                filter.ApplyInPlace(img);

                var source = ImageUtility.ConvertBitmap(img, pf);
                source.Freeze();
                return(source);
            }
        }
Пример #6
0
 public void ReloadLocale(string culture)
 {
     using (MyStopWatch.Measure()) {
         try {
             _activeCulture = new CultureInfo(culture);
         } catch (Exception ex) {
             Logger.Error(ex);
         }
         RaiseAllPropertiesChanged();
     }
 }
Пример #7
0
 private void Save()
 {
     lock (lockobj) {
         using (MyStopWatch.Measure()) {
             try {
                 ActiveProfile.Save();
             } catch (Exception ex) {
                 Logger.Error(ex);
             }
         }
     }
 }
Пример #8
0
 public static DebayeredImageData Debayer(BitmapSource source, System.Drawing.Imaging.PixelFormat pf, bool saveColorChannels = false, bool saveLumChannel = false, SensorType bayerPattern = SensorType.RGGB)
 {
     using (MyStopWatch.Measure()) {
         if (pf != System.Drawing.Imaging.PixelFormat.Format16bppGrayScale)
         {
             throw new NotSupportedException();
         }
         using (var bmp = BitmapFromSource(source, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale)) {
             return(Debayer(bmp, saveColorChannels, saveLumChannel, bayerPattern));
         }
     }
 }
Пример #9
0
        private static bool VerifyChecksum(byte[] raw, XISFChecksumTypeEnum cksumType, string providedCksum)
        {
            string      computedCksum;
            SHA3Managed sha3;

            using (MyStopWatch.Measure($"XISF Checksum = {cksumType}")) {
                switch (cksumType)
                {
                case XISFChecksumTypeEnum.SHA1:
                    SHA1 sha1 = new SHA1CryptoServiceProvider();
                    computedCksum = GetStringFromHash(sha1.ComputeHash(raw));
                    sha1.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA256:
                    SHA256 sha256 = new SHA256CryptoServiceProvider();
                    computedCksum = GetStringFromHash(sha256.ComputeHash(raw));
                    sha256.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA512:
                    SHA512 sha512 = new SHA512CryptoServiceProvider();
                    computedCksum = GetStringFromHash(sha512.ComputeHash(raw));
                    sha512.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA3_256:
                    sha3          = new SHA3Managed(256);
                    computedCksum = GetStringFromHash(sha3.ComputeHash(raw));
                    sha3.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA3_512:
                    sha3          = new SHA3Managed(512);
                    computedCksum = GetStringFromHash(sha3.ComputeHash(raw));
                    sha3.Dispose();
                    break;

                default:
                    return(false);
                }
            }
            if (computedCksum.Equals(providedCksum))
            {
                return(true);
            }
            else
            {
                Logger.Error($"XISF: Invalid data block checksum! Expected: {providedCksum} Got: {computedCksum}");
                return(false);
            }
        }
Пример #10
0
        public BitmapSource GetAnnotatedImage()
        {
            using (MyStopWatch.Measure()) {
                using (var bmp = ImageUtility.Convert16BppTo8Bpp(_originalBitmapSource)) {
                    using (var newBitmap = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) {
                        Graphics graphics = Graphics.FromImage(newBitmap);
                        graphics.DrawImage(bmp, 0, 0);

                        if (_starlist.Count > 0)
                        {
                            int   r, offset = 10;
                            float textposx, textposy;

                            var threshhold = 200;
                            if (_starlist.Count > threshhold)
                            {
                                _starlist.Sort((item1, item2) => item2.Average.CompareTo(item1.Average));
                                _starlist = _starlist.GetRange(0, threshhold);
                            }

                            foreach (Star star in _starlist)
                            {
                                _token.ThrowIfCancellationRequested();
                                r        = (int)Math.Ceiling(star.radius);
                                textposx = star.Position.X - offset;
                                textposy = star.Position.Y - offset;
                                graphics.DrawEllipse(ELLIPSEPEN, new RectangleF(star.Rectangle.X, star.Rectangle.Y, star.Rectangle.Width, star.Rectangle.Height));
                                graphics.DrawString(star.HFR.ToString("##.##"), FONT, TEXTBRUSH, new PointF(Convert.ToSingle(textposx - 1.5 * offset), Convert.ToSingle(textposy + 2.5 * offset)));
                            }
                        }

                        if (UseROI)
                        {
                            graphics.DrawRectangle(RECTPEN, (float)(1 - InnerCropRatio) * imageProperties.Width / 2, (float)(1 - InnerCropRatio) * imageProperties.Height / 2, (float)InnerCropRatio * imageProperties.Width, (float)InnerCropRatio * imageProperties.Height);
                            if (OuterCropRatio < 1)
                            {
                                graphics.DrawRectangle(RECTPEN, (float)(1 - OuterCropRatio) * imageProperties.Width / 2, (float)(1 - OuterCropRatio) * imageProperties.Height / 2, (float)OuterCropRatio * imageProperties.Width, (float)OuterCropRatio * imageProperties.Height);
                            }
                        }

                        var img = ImageUtility.ConvertBitmap(newBitmap, System.Windows.Media.PixelFormats.Bgr24);

                        img.Freeze();
                        return(img);
                    }
                }
            }
        }
Пример #11
0
        public Task <IImageData> Convert(
            MemoryStream s,
            int bitDepth,
            string rawType,
            ImageMetaData metaData,
            CancellationToken token = default)
        {
            return(Task.Run(() => {
                using (MyStopWatch.Measure()) {
                    FIBITMAP img;
                    int left, top, imgWidth, imgHeight;
                    FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_RAW;
                    img = FreeImage.LoadFromStream(s, (FREE_IMAGE_LOAD_FLAGS)8, ref format);

                    FreeImage.GetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, img, "Raw.Frame.Width", out MetadataTag widthTag);
                    FreeImage.GetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, img, "Raw.Frame.Height", out MetadataTag heightTag);
                    FreeImage.GetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, img, "Raw.Frame.Left", out MetadataTag leftTag);
                    FreeImage.GetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, img, "Raw.Frame.Top", out MetadataTag topTag);
                    left = int.Parse(leftTag.ToString());
                    top = int.Parse(topTag.ToString());
                    imgWidth = int.Parse(widthTag.ToString());
                    imgHeight = int.Parse(heightTag.ToString());

                    using (var memStream = new MemoryStream()) {
                        FreeImage.SaveToStream(img, memStream, FREE_IMAGE_FORMAT.FIF_TIFF, FREE_IMAGE_SAVE_FLAGS.TIFF_NONE);
                        memStream.Position = 0;

                        var decoder = new TiffBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

                        CroppedBitmap cropped = new CroppedBitmap(decoder.Frames[0], new System.Windows.Int32Rect(left, top, imgWidth, imgHeight));

                        ushort[] outArray = new ushort[cropped.PixelWidth * cropped.PixelHeight];
                        cropped.CopyPixels(outArray, 2 * cropped.PixelWidth, 0);
                        FreeImage.UnloadEx(ref img);

                        var imageArray = new ImageArray(flatArray: outArray, rawData: s.ToArray(), rawType: rawType);
                        var data = new ImageData(
                            imageArray: imageArray,
                            width: cropped.PixelWidth,
                            height: cropped.PixelHeight,
                            bitDepth: bitDepth,
                            isBayered: true,
                            metaData: metaData);
                        return Task.FromResult <IImageData>(data);
                    }
                }
            }));
        }
Пример #12
0
        public bool Clone(ProfileMeta profileInfo)
        {
            lock (lockobj) {
                using (MyStopWatch.Measure()) {
                    if (profileFileWatcher != null)
                    {
                        profileFileWatcher.EnableRaisingEvents = false;
                    }

                    IProfile clone = null;
                    if (profileInfo.Id == ActiveProfile.Id)
                    {
                        clone = Profile.Clone(ActiveProfile);
                    }
                    else
                    {
                        try {
                            var p = Profile.Load(profileInfo.Location);
                            clone = Profile.Clone(p);
                            p.Dispose();
                        } catch (Exception) {
                            //Profile is in use
                            return(false);
                        }
                    }

                    if (clone != null)
                    {
                        clone.Save();

                        var info = new ProfileMeta()
                        {
                            Id = clone.Id, Name = clone.Name, Location = clone.Location
                        };
                        Profiles.Add(info);
                        clone.Dispose();

                        if (profileFileWatcher != null)
                        {
                            profileFileWatcher.EnableRaisingEvents = true;
                        }
                    }
                    return(true);
                }
            }
        }
Пример #13
0
        private void Load()
        {
            lock (lockobj) {
                using (MyStopWatch.Measure()) {
                    if (!Directory.Exists(PROFILEFOLDER))
                    {
                        Directory.CreateDirectory(PROFILEFOLDER);
                    }

                    foreach (var file in Directory.GetFiles(PROFILEFOLDER, "*.profile"))
                    {
                        var info = Profile.Peek(file);
                        if (info != null)
                        {
                            Profiles.Add(info);
                        }
                    }
                    if (Profiles.Count == 0)
                    {
                        if (File.Exists(OLDPROFILEFILEPATH))
                        {
                            MigrateOldProfile();
                        }
                        else
                        {
                            AddDefaultProfile();
                        }
                    }

                    var l = Profiles.OrderBy(x => x.LastUsed);

                    for (var idx = l.Count() - 1; idx >= 0; idx--)
                    {
                        if (SelectProfile(l.ElementAt(idx)))
                        {
                            return;
                        }
                    }

                    Logger.Debug("All Profiles are in use. Creating a new default profile");
                    var defaultProfile = AddDefaultProfile();
                    SelectProfile(defaultProfile);
                }
            }
        }
Пример #14
0
        public async Task <string> SaveToDisk(FileSaveInfo fileSaveInfo, CancellationToken token, bool forceFileType = false)
        {
            string actualPath = string.Empty;

            try {
                using (MyStopWatch.Measure()) {
                    string tempPath = await SaveToDiskAsync(fileSaveInfo, token, forceFileType);

                    actualPath = FinalizeSave(tempPath, fileSaveInfo.FilePattern);
                }
            } catch (OperationCanceledException ex) {
                throw ex;
            } catch (Exception ex) {
                Logger.Error(ex);
                throw ex;
            } finally {
            }
            return(actualPath);
        }
Пример #15
0
        /// <summary>
        ///  Saves file to application temp path
        /// </summary>
        /// <param name="fileType"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <string> PrepareSave(FileSaveInfo fileSaveInfo, CancellationToken cancelToken = default)
        {
            var actualPath = string.Empty;

            try {
                using (MyStopWatch.Measure()) {
                    actualPath = await SaveToDiskAsync(fileSaveInfo, cancelToken, false);

                    Logger.Debug($"Saving temporary image at {actualPath}");
                }
            } catch (OperationCanceledException ex) {
                throw ex;
            } catch (Exception ex) {
                Logger.Error(ex);
                throw ex;
            } finally {
            }
            return(actualPath);
        }
Пример #16
0
        public static byte[] Unshuffle(byte[] shuffled, int itemSize)
        {
            int size = shuffled.Length;

            byte[] unshuffled    = new byte[size];
            int    numberOfItems = size / itemSize;
            int    s             = 0;

            using (MyStopWatch.Measure("XISF Byte Unshuffle")) {
                for (int j = 0; j < itemSize; ++j)
                {
                    int u = 0 + j;
                    for (int i = 0; i < numberOfItems; ++i, ++s, u += itemSize)
                    {
                        unshuffled[u] = shuffled[s];
                    }
                }
            }

            return(unshuffled);
        }
Пример #17
0
        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;
        }
Пример #18
0
        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;
        }
Пример #19
0
        public static IImageStatistics Create(ImageProperties imageProperties, ushort[] array)
        {
            using (MyStopWatch.Measure()) {
                long   sum            = 0;
                long   squareSum      = 0;
                int    count          = array.Count();
                ushort min            = ushort.MaxValue;
                ushort oldmin         = min;
                ushort max            = 0;
                ushort oldmax         = max;
                long   maxOccurrences = 0;
                long   minOccurrences = 0;

                /* Array mapping: pixel value -> total number of occurrences of that pixel value */
                int[] pixelValueCounts = new int[ushort.MaxValue + 1];
                for (var i = 0; i < array.Length; i++)
                {
                    ushort val = array[i];

                    sum       += val;
                    squareSum += (long)val * val;

                    pixelValueCounts[val]++;

                    min = Math.Min(min, val);
                    if (min != oldmin)
                    {
                        minOccurrences = 0;
                    }
                    if (val == min)
                    {
                        minOccurrences += 1;
                    }

                    max = Math.Max(max, val);
                    if (max != oldmax)
                    {
                        maxOccurrences = 0;
                    }
                    if (val == max)
                    {
                        maxOccurrences += 1;
                    }

                    oldmin = min;
                    oldmax = max;
                }

                double mean     = sum / (double)count;
                double variance = (squareSum - count * mean * mean) / (count);
                double stdev    = Math.Sqrt(variance);

                var    occurrences = 0;
                double median = 0d;
                int    median1 = 0, median2 = 0;
                var    medianlength = array.Length / 2.0;

                /* Determine median out of histogram array */
                for (ushort i = 0; i < ushort.MaxValue; i++)
                {
                    occurrences += pixelValueCounts[i];
                    if (occurrences > medianlength)
                    {
                        median1 = i;
                        median2 = i;
                        break;
                    }
                    else if (occurrences == medianlength)
                    {
                        median1 = i;
                        for (int j = i + 1; j <= ushort.MaxValue; j++)
                        {
                            if (pixelValueCounts[j] > 0)
                            {
                                median2 = j;
                                break;
                            }
                        }
                        break;
                    }
                }
                median = (median1 + median2) / 2.0;

                /* Determine median Absolute Deviation out of histogram array and previously determined median
                 * As the histogram already has the values sorted and we know the median,
                 * we can determine the mad by beginning from the median and step up and down
                 * By doing so we will gain a sorted list automatically, because MAD = DetermineMedian(|xn - median|)
                 * So starting from the median will be 0 (as median - median = 0), going up and down will increment by the steps
                 */

                var medianAbsoluteDeviation = 0.0d;
                occurrences = 0;
                var idxDown = median1;
                var idxUp   = median2;
                while (true)
                {
                    if (idxDown >= 0 && idxDown != idxUp)
                    {
                        occurrences += pixelValueCounts[idxDown] + pixelValueCounts[idxUp];
                    }
                    else
                    {
                        occurrences += pixelValueCounts[idxUp];
                    }

                    if (occurrences > medianlength)
                    {
                        medianAbsoluteDeviation = Math.Abs(idxUp - median);
                        break;
                    }

                    idxUp++;
                    idxDown--;
                    if (idxUp > ushort.MaxValue)
                    {
                        break;
                    }
                }

                var maxPossibleValue = (ushort)((1 << imageProperties.BitDepth) - 1);
                var factor           = (double)HISTOGRAMRESOLUTION / maxPossibleValue;
                var histogram        = pixelValueCounts
                                       .Select((value, index) => new { Index = index, Value = value })
                                       .GroupBy(
                    x => Math.Floor((double)Math.Min(maxPossibleValue, x.Index) * factor),
                    x => x.Value)
                                       .Select(g => new OxyPlot.DataPoint(g.Key, g.Sum()))
                                       .OrderBy(item => item.X).ToImmutableList();

                var statistics = new ImageStatistics();
                statistics.StDev  = stdev;
                statistics.Mean   = mean;
                statistics.Median = median;
                statistics.MedianAbsoluteDeviation = medianAbsoluteDeviation;
                statistics.Max            = max;
                statistics.MaxOccurrences = maxOccurrences;
                statistics.Min            = min;
                statistics.MinOccurrences = minOccurrences;
                statistics.Histogram      = histogram;
                return(statistics);
            }
        }
Пример #20
0
        private async Task <DateTime> UpdateEarthRotationParameters(DateTime startDate)
        {
            var maxUnix = 0l;

            using (MyStopWatch.Measure()) {
                var startDateUnix = Utility.DateTimeToUnixTimeStamp(startDate);
                var data          = QueryOnlineData();

                List <string> rows = new List <string>();
                using (var context = new DatabaseInteraction().GetContext()) {
                    using (var reader = new System.IO.StringReader(data)) {
                        string   headerLine    = reader.ReadLine();
                        string[] headerColumns = headerLine.Split(';');

                        var idxMJD     = Array.FindIndex(headerColumns, x => x.ToLower() == "mjd");
                        var idxYear    = Array.FindIndex(headerColumns, x => x.ToLower() == "year");
                        var idxMonth   = Array.FindIndex(headerColumns, x => x.ToLower() == "month");
                        var idxDay     = Array.FindIndex(headerColumns, x => x.ToLower() == "day");
                        var idxXPole   = Array.FindIndex(headerColumns, x => x.ToLower() == "x_pole");
                        var idxYPole   = Array.FindIndex(headerColumns, x => x.ToLower() == "y_pole");
                        var idxUT1_UTC = Array.FindIndex(headerColumns, x => x.ToLower() == "ut1-utc");
                        var idxLOD     = Array.FindIndex(headerColumns, x => x.ToLower() == "lod");
                        var idxdX      = Array.FindIndex(headerColumns, x => x.ToLower() == "dx");
                        var idxdY      = Array.FindIndex(headerColumns, x => x.ToLower() == "dy");

                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            var columns = line.Split(';');

                            //When column 5 is empty there is no prediction available
                            if (!string.IsNullOrWhiteSpace(columns[idxXPole]))
                            {
                                int year  = int.Parse(columns[idxYear]);
                                int month = int.Parse(columns[idxMonth]);
                                int day   = int.Parse(columns[idxDay]);

                                var date          = new DateTime(year, month, day, 0, 0, 0, DateTimeKind.Utc);
                                var unixTimestamp = Utility.DateTimeToUnixTimeStamp(date);

                                if (unixTimestamp >= startDateUnix)
                                {
                                    double mjd = double.Parse(columns[idxMJD], CultureInfo.InvariantCulture);

                                    double x = double.Parse(columns[idxXPole], CultureInfo.InvariantCulture);
                                    double y = double.Parse(columns[idxYPole], CultureInfo.InvariantCulture);

                                    double ut1_utc = double.Parse(columns[idxUT1_UTC], CultureInfo.InvariantCulture);

                                    double LOD = 0.0;
                                    if (!string.IsNullOrWhiteSpace(columns[idxLOD]))
                                    {
                                        LOD = double.Parse(columns[idxLOD], CultureInfo.InvariantCulture);
                                    }
                                    else
                                    {
                                        maxUnix = Math.Max(maxUnix, unixTimestamp);
                                    }

                                    double dX = 0.0;
                                    double dY = 0.0;
                                    if (!string.IsNullOrWhiteSpace(columns[idxdX]))
                                    {
                                        dX = double.Parse(columns[idxdX], CultureInfo.InvariantCulture) / 1000d;
                                        dY = double.Parse(columns[idxdY], CultureInfo.InvariantCulture) / 1000d;
                                    }

                                    //(date,modifiedjuliandate,x,y,ut1_utc,lod,dx,dy)
                                    rows.Add($"({unixTimestamp.ToString(CultureInfo.InvariantCulture)},{mjd.ToString(CultureInfo.InvariantCulture)},{x.ToString(CultureInfo.InvariantCulture)},{y.ToString(CultureInfo.InvariantCulture)},{ut1_utc.ToString(CultureInfo.InvariantCulture)},{LOD.ToString(CultureInfo.InvariantCulture)},{dX.ToString(CultureInfo.InvariantCulture)},{dY.ToString(CultureInfo.InvariantCulture)})");
                                }
                            }
                        }
                    }
                    //Bulk Query to insert all rows quickly
                    var query = $"INSERT OR REPLACE INTO `earthrotationparameters` (date,modifiedjuliandate,x,y,ut1_utc,lod,dx,dy) VALUES {string.Join($",{Environment.NewLine}", rows)}";
                    await context.Database.ExecuteSqlCommandAsync(query);
                }
            }
            return(Utility.UnixTimeStampToDateTime(maxUnix));
        }
Пример #21
0
        public async Task <List <DeepSkyObject> > GetDeepSkyObjects(
            string imageRepository,
            DeepSkyObjectSearchParams searchParams,
            CancellationToken token)
        {
            using (MyStopWatch.Measure()) {
                if (searchParams == null)
                {
                    throw new ArgumentNullException(nameof(searchParams));
                }

                var dsos = new List <DeepSkyObject>();
                try {
                    using (var context = new NINADbContext(connectionString)) {
                        var query = from dso in context.DsoDetailSet
                                    select new {
                            dso.id,
                            dso.ra,
                            dso.dec,
                            dso.dsotype,
                            dso.magnitude,
                            dso.sizemin,
                            dso.sizemax,
                            dso.constellation,
                            dso.surfacebrightness
                        };

                        if (!string.IsNullOrEmpty(searchParams.Constellation))
                        {
                            query = query.Where(x => x.constellation == searchParams.Constellation);
                        }

                        if (searchParams.RightAscension.From != null)
                        {
                            query = query.Where(x => x.ra >= searchParams.RightAscension.From);
                        }

                        if (searchParams.RightAscension.Thru != null)
                        {
                            query = query.Where(x => x.ra <= searchParams.RightAscension.Thru);
                        }

                        if (searchParams.Declination.From != null)
                        {
                            query = query.Where(x => x.dec >= searchParams.Declination.From);
                        }

                        if (searchParams.Declination.Thru != null)
                        {
                            query = query.Where(x => x.dec <= searchParams.Declination.Thru);
                        }

                        if (searchParams.Size.From.HasValue)
                        {
                            query = query.Where(x => x.sizemin >= searchParams.Size.From);
                        }

                        if (searchParams.Size.Thru.HasValue)
                        {
                            query = query.Where(x => x.sizemax <= searchParams.Size.Thru);
                        }

                        if (searchParams.Brightness.From.HasValue)
                        {
                            query = query.Where(x => x.surfacebrightness >= searchParams.Brightness.From);
                        }

                        if (searchParams.Brightness.Thru.HasValue)
                        {
                            query = query.Where(x => x.surfacebrightness <= searchParams.Brightness.Thru);
                        }

                        if (searchParams.Magnitude.From.HasValue)
                        {
                            query = query.Where(x => x.magnitude >= searchParams.Magnitude.From);
                        }

                        if (searchParams.Magnitude.Thru.HasValue)
                        {
                            query = query.Where(x => x.magnitude <= searchParams.Magnitude.Thru);
                        }

                        if (searchParams.DsoTypes?.Count > 0)
                        {
                            query = query.Where(x => searchParams.DsoTypes.Contains(x.dsotype));
                        }

                        if (!string.IsNullOrEmpty(searchParams.ObjectName))
                        {
                            var name    = searchParams.ObjectName.ToLower();
                            var idQuery = context.CatalogueNrSet.Where(x => x.dsodetailid.ToLower().Contains(name) || (x.catalogue + x.designation).ToLower().Contains(name) || (x.catalogue + " " + x.designation).ToLower().Contains(name)).Select(x => x.dsodetailid).Distinct();

                            query = query.Join(idQuery, dsoDetail => dsoDetail.id, e => e, (dsoDetail, id) => dsoDetail);
                        }

                        if (searchParams.SearchOrder.Direction == "ASC")
                        {
                            query = query.OrderBy(searchParams.SearchOrder.Field);
                        }
                        else
                        {
                            query = query.OrderByDescending(searchParams.SearchOrder.Field);
                        }

                        if (searchParams.Limit != null)
                        {
                            query = query.Take(searchParams.Limit.Value);
                        }

                        var dsosTask = query.ToListAsync(token);

                        var catalogueTask = (from q in query
                                             join cat in context.CatalogueNrSet on q.id equals cat.dsodetailid
                                             select new { cat.dsodetailid, designation = cat.catalogue == "NAME" ? cat.designation : cat.catalogue + " " + cat.designation })
                                            .GroupBy(x => x.dsodetailid)
                                            .ToDictionaryAsync(x => x.Key, x => x.ToList(), token);

                        await Task.WhenAll(dsosTask, catalogueTask);

                        var dsoResult       = dsosTask.Result;
                        var catalogueResult = catalogueTask.Result;

                        foreach (var row in dsoResult)
                        {
                            var id     = row.id;
                            var coords = new Coordinates(row.ra, row.dec, Epoch.J2000, Coordinates.RAType.Degrees);
                            var dso    = new DeepSkyObject(row.id, coords, imageRepository);

                            dso.DSOType = row.dsotype;

                            if (row.magnitude.HasValue)
                            {
                                dso.Magnitude = (double?)row.magnitude;
                            }

                            if (row.sizemax.HasValue)
                            {
                                dso.Size = (double?)row.sizemax;
                            }

                            dso.AlsoKnownAs = catalogueResult[row.id].Select(x => x.designation).ToList();

                            var longestName = dso.AlsoKnownAs.Aggregate("", (max, cur) => max.Length > cur.Length ? max : cur);
                            dso.Name = longestName;

                            if (!string.IsNullOrEmpty(row.constellation))
                            {
                                dso.Constellation = row.constellation;
                            }

                            if (row.surfacebrightness.HasValue)
                            {
                                dso.SurfaceBrightness = (double?)row.surfacebrightness;
                            }

                            dsos.Add(dso);
                        }
                    }
                } catch (OperationCanceledException) {
                } catch (Exception ex) {
                    if (!ex.Message.Contains("Execution was aborted by the user"))
                    {
                        Logger.Error(ex);
                        Notification.ShowError(ex.Message);
                    }
                }

                return(dsos);
            }
        }
Пример #22
0
        public async Task <IImageData> Convert(
            MemoryStream s,
            int bitDepth,
            string rawType,
            ImageMetaData metaData,
            CancellationToken token = default)
        {
            return(await Task.Run(async() => {
                using (MyStopWatch.Measure()) {
                    var fileextension = ".raw";
                    var filename = Path.GetRandomFileName();
                    var rawfile = Path.Combine(Utility.APPLICATIONTEMPPATH, filename + fileextension);

                    using (var filestream = new System.IO.FileStream(rawfile, System.IO.FileMode.Create)) {
                        s.WriteTo(filestream);
                    }

                    ImageData data = null;
                    var outputFile = Path.Combine(Utility.APPLICATIONTEMPPATH, filename + ".tiff");
                    try {
                        System.Diagnostics.Process process;
                        System.Diagnostics.ProcessStartInfo startInfo;
                        var sb = new StringBuilder();
                        using (MyStopWatch.Measure("DCRawStart")) {
                            process = new System.Diagnostics.Process();
                            startInfo = new System.Diagnostics.ProcessStartInfo();
                            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
                            startInfo.FileName = DCRAWLOCATION;
                            startInfo.UseShellExecute = false;
                            startInfo.RedirectStandardOutput = true;
                            startInfo.RedirectStandardError = true;
                            startInfo.RedirectStandardInput = true;
                            startInfo.CreateNoWindow = true;
                            startInfo.Arguments = "-4 -d -T -t 0 -v \"" + rawfile + "\"";
                            process.StartInfo = startInfo;
                            process.EnableRaisingEvents = true;

                            process.OutputDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => {
                                sb.AppendLine(e.Data);
                            };

                            process.ErrorDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => {
                                sb.AppendLine(e.Data);
                            };

                            process.Start();
                            process.BeginOutputReadLine();
                            process.BeginErrorReadLine();

                            await process.WaitForExitAsync(token);

                            Logger.Trace(sb.ToString());
                        }

                        using (MyStopWatch.Measure("DCRawReadIntoImageArray")) {
                            if (File.Exists(outputFile))
                            {
                                TiffBitmapDecoder TifDec = new TiffBitmapDecoder(new Uri(outputFile), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
                                BitmapFrame bmp = TifDec.Frames[0];
                                ushort[] pixels = new ushort[bmp.PixelWidth *bmp.PixelHeight];
                                bmp.CopyPixels(pixels, 2 * bmp.PixelWidth, 0);

                                //Due to the settings of dcraw decoding the values will be stretched to 16 bits
                                bitDepth = 16;

                                var imageArray = new ImageArray(flatArray: pixels, rawData: s.ToArray(), rawType: rawType);
                                data = new ImageData(
                                    imageArray: imageArray,
                                    width: (int)bmp.PixelWidth,
                                    height: (int)bmp.PixelHeight,
                                    bitDepth: bitDepth,
                                    isBayered: true,
                                    metaData: metaData);
                            }
                            else
                            {
                                Logger.Error("File not found: " + outputFile);
                                throw new Exception("Error occured during DCRaw conversion." + Environment.NewLine + sb.ToString());
                            }
                        }
                    } catch (Exception ex) {
                        Notification.Notification.ShowError(ex.Message);
                        Logger.Error(ex);
                    } finally {
                        if (File.Exists(rawfile))
                        {
                            File.Delete(rawfile);
                        }
                        if (File.Exists(outputFile))
                        {
                            File.Delete(outputFile);
                        }
                    }
                    return data;
                }
            }));
        }
Пример #23
0
 private void RefreshCameraInfoCache()
 {
     using (MyStopWatch.Measure()) {
         _info = ASICameraDll.GetCameraProperties(_cameraId);
     }
 }
Пример #24
0
        /// <summary>
        /// Convert the ushort array to a byte arraay, compressing with the requested algorithm if required
        /// </summary>
        /// <param name="data"></param>
        /// <returns>Uncompressed or compressed byte array</returns>
        private byte[] PrepareArray(ushort[] data)
        {
            byte[] outArray;

            /*
             * Convert the ushort[] into a byte[]
             * From here onwards we deal in byte arrays only
             */
            byte[] byteArray = new byte[data.Length * ShuffleItemSize];
            Buffer.BlockCopy(data, 0, byteArray, 0, data.Length * ShuffleItemSize);

            /*
             * Compress the data block as configured.
             */
            using (MyStopWatch.Measure($"XISF Compression = {CompressionType}")) {
                if (CompressionType == XISFCompressionTypeEnum.LZ4)
                {
                    if (ByteShuffling)
                    {
                        CompressionName = "lz4+sh";
                        byteArray       = Shuffle(byteArray, ShuffleItemSize);
                    }
                    else
                    {
                        CompressionName = "lz4";
                    }

                    byte[] tmpArray       = new byte[LZ4Codec.MaximumOutputSize(byteArray.Length)];
                    int    compressedSize = LZ4Codec.Encode(byteArray, 0, byteArray.Length, tmpArray, 0, tmpArray.Length, LZ4Level.L00_FAST);

                    outArray = new byte[compressedSize];
                    Array.Copy(tmpArray, outArray, outArray.Length);
                    tmpArray = null;
                }
                else if (CompressionType == XISFCompressionTypeEnum.LZ4HC)
                {
                    if (ByteShuffling)
                    {
                        CompressionName = "lz4hc+sh";
                        byteArray       = Shuffle(byteArray, ShuffleItemSize);
                    }
                    else
                    {
                        CompressionName = "lz4hc";
                    }

                    byte[] tmpArray       = new byte[LZ4Codec.MaximumOutputSize(byteArray.Length)];
                    int    compressedSize = LZ4Codec.Encode(byteArray, 0, byteArray.Length, tmpArray, 0, tmpArray.Length, LZ4Level.L06_HC);

                    outArray = new byte[compressedSize];
                    Array.Copy(tmpArray, outArray, outArray.Length);
                    tmpArray = null;
                }
                else if (CompressionType == XISFCompressionTypeEnum.ZLIB)
                {
                    if (ByteShuffling)
                    {
                        CompressionName = "zlib+sh";
                        byteArray       = Shuffle(byteArray, ShuffleItemSize);
                    }
                    else
                    {
                        CompressionName = "zlib";
                    }

                    outArray = ZlibStream.CompressBuffer(byteArray);
                }
                else
                {
                    outArray = new byte[byteArray.Length];
                    Array.Copy(byteArray, outArray, outArray.Length);
                    CompressionName = null;
                }
            }

            // Revert to the original data array in case the compression is bigger than uncompressed
            if (outArray.Length > byteArray.Length)
            {
                if (ByteShuffling)
                {
                    //As the original array is shuffled it needs to be unshuffled again - this scenario should be highly unlikely anyways
                    outArray = Unshuffle(byteArray, ShuffleItemSize);
                }
                else
                {
                    outArray = byteArray;
                }
                CompressionType = XISFCompressionTypeEnum.NONE;

                Logger.Debug("XISF output array is larger after compression. Image will be prepared uncompressed instead.");
            }

            if (CompressionType != XISFCompressionTypeEnum.NONE)
            {
                double percentChanged = (1 - ((double)outArray.Length / (double)byteArray.Length)) * 100;
                Logger.Debug($"XISF: {CompressionType} compressed {byteArray.Length} bytes to {outArray.Length} bytes ({percentChanged.ToString("#.##")}%)");
            }

            /*
             * Checksum the data block as configured.
             * If the data block is compressed, we always checksum the compressed form, not the uncompressed form.
             */
            using (MyStopWatch.Measure($"XISF Checksum = {ChecksumType}")) {
                SHA3Managed sha3;

                switch (ChecksumType)
                {
                case XISFChecksumTypeEnum.SHA1:
                    SHA1 sha1 = new SHA1CryptoServiceProvider();
                    Checksum     = GetStringFromHash(sha1.ComputeHash(outArray));
                    ChecksumName = "sha-1";
                    sha1.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA256:
                    SHA256 sha256 = new SHA256CryptoServiceProvider();
                    Checksum     = GetStringFromHash(sha256.ComputeHash(outArray));
                    ChecksumName = "sha-256";
                    sha256.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA512:
                    SHA512 sha512 = new SHA512CryptoServiceProvider();
                    Checksum     = GetStringFromHash(sha512.ComputeHash(outArray));
                    ChecksumName = "sha-512";
                    sha512.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA3_256:
                    sha3         = new SHA3Managed(256);
                    Checksum     = GetStringFromHash(sha3.ComputeHash(outArray));
                    ChecksumName = "sha3-256";
                    sha3.Dispose();
                    break;

                case XISFChecksumTypeEnum.SHA3_512:
                    sha3         = new SHA3Managed(512);
                    Checksum     = GetStringFromHash(sha3.ComputeHash(outArray));
                    ChecksumName = "sha3-512";
                    sha3.Dispose();
                    break;

                case XISFChecksumTypeEnum.NONE:
                default:
                    Checksum     = null;
                    ChecksumName = null;
                    break;
                }
            }

            return(outArray);
        }
Пример #25
0
        public static DebayeredImageData Debayer(Bitmap bmp, bool saveColorChannels = false, bool saveLumChannel = false, SensorType bayerPattern = SensorType.RGGB)
        {
            using (MyStopWatch.Measure()) {
                var filter = new BayerFilter16bpp();
                filter.SaveColorChannels = saveColorChannels;
                filter.SaveLumChannel    = saveLumChannel;

                Logger.Debug($"Debayering pattern {bayerPattern}");

                switch (bayerPattern)
                {
                case SensorType.RGGB:
                    filter.BayerPattern = new int[, ] {
                        { RGB.B, RGB.G }, { RGB.G, RGB.R }
                    };
                    break;

                case SensorType.RGBG:
                    filter.BayerPattern = new int[, ] {
                        { RGB.G, RGB.B }, { RGB.G, RGB.R }
                    };
                    break;

                case SensorType.GRGB:
                    filter.BayerPattern = new int[, ] {
                        { RGB.B, RGB.G }, { RGB.R, RGB.G }
                    };
                    break;

                case SensorType.GRBG:
                    filter.BayerPattern = new int[, ] {
                        { RGB.G, RGB.B }, { RGB.R, RGB.G }
                    };
                    break;

                case SensorType.GBGR:
                    filter.BayerPattern = new int[, ] {
                        { RGB.R, RGB.G }, { RGB.B, RGB.G }
                    };
                    break;

                case SensorType.GBRG:
                    filter.BayerPattern = new int[, ] {
                        { RGB.G, RGB.R }, { RGB.B, RGB.G }
                    };
                    break;

                case SensorType.BGRG:
                    filter.BayerPattern = new int[, ] {
                        { RGB.G, RGB.R }, { RGB.G, RGB.B }
                    };
                    break;

                case SensorType.BGGR:
                    filter.BayerPattern = new int[, ] {
                        { RGB.R, RGB.G }, { RGB.G, RGB.B }
                    };
                    break;

                default:
                    throw new InvalidImagePropertiesException(string.Format(Locale.Loc.Instance["LblUnsupportedCfaPattern"], bayerPattern));
                }

                DebayeredImageData debayered = new DebayeredImageData();
                debayered.ImageSource = ConvertBitmap(filter.Apply(bmp), PixelFormats.Rgb48);
                debayered.ImageSource.Freeze();
                debayered.Data = filter.LRGBArrays;
                return(debayered);
            }
        }