public static Image <Rgb24> DrawGraph(string label, double[] histogram, int imageWidth, int height, int scalingFactor)
        {
            Pen pen1 = new Pen(Color.White, 1f);

            //Pen pen2 = new Pen(Color.Red, 1);
            Pen pen3 = new Pen(Color.Wheat, 1f);

            //Pen pen4 = new Pen(Color.Purple, 1);
            var brush      = new SolidBrush(Color.Red);
            var stringFont = Drawing.Arial9;

            //Font stringFont = Drawing.Tahoma9;
            //SizeF stringSize = new SizeF();

            int barWidth = imageWidth / histogram.Length;

            // double sum = histogram.Sum();
            // DataTools.getMaxIndex(histogram, out int maxBin);

            //double maxValue = histogram[maxBin];

            var bmp1 = new Image <Rgb24>(imageWidth, height);

            bmp1.Mutate(g1 =>
            {
                g1.Clear(Color.Black);

                for (int i = 1; i < 10; i++)
                {
                    int grid = imageWidth * i / 10;
                    g1.DrawLine(pen3, grid, height - 1, grid, 0);
                }

                g1.DrawLine(pen1, 0, height - 1, imageWidth, height - 1);

                // draw mode bin and upper percentile bound
                //g.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
                //g.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

                for (int b = 0; b < histogram.Length; b++)
                {
                    int x = b * barWidth;
                    int y = (int)Math.Ceiling(histogram[b] * height * scalingFactor);
                    g1.FillRectangle(brush, x, height - y - 1, barWidth, y);
                }
            });

            var bmp2 = new Image <Rgb24>(imageWidth, 20);

            bmp2.Mutate(g2 =>
            {
                g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
                g2.DrawText(label, stringFont, Color.Wheat, new PointF(4, 3));
            });

            Image <Rgb24>[] images = { bmp2, bmp1 };
            Image <Rgb24>   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This method assumes that the height of the passed sonogram image is half of the original frame size.
        /// This assumption allows the frequency scale grid lines to be placed at the correct intervals.
        /// </summary>
        public static Image FrameSonogram(
            Image sonogramImage,
            Image titleBar,
            TimeSpan minuteOffset,
            TimeSpan xAxisTicInterval,
            TimeSpan xAxisPixelDuration,
            TimeSpan labelInterval,
            int nyquist,
            int hertzInterval)
        {
            double secondsDuration = xAxisPixelDuration.TotalSeconds * sonogramImage.Width;
            var    fullDuration    = TimeSpan.FromSeconds(secondsDuration);

            // init frequency scale
            int frameSize = sonogramImage.Height * 2;
            var freqScale = new FrequencyScale(nyquist, frameSize, hertzInterval);

            SpectrogramTools.DrawGridLinesOnImage((Bitmap)sonogramImage, minuteOffset, fullDuration, xAxisTicInterval, freqScale);

            int imageWidth = sonogramImage.Width;
            var timeBmp    = ImageTrack.DrawShortTimeTrack(minuteOffset, xAxisPixelDuration, xAxisTicInterval, labelInterval, imageWidth, "Seconds");

            Image[] imageArray = { titleBar, timeBmp, sonogramImage, timeBmp };
            return(ImageTools.CombineImagesVertically(imageArray));
        }
        //public static Image DrawImageOfDistribution(double[,] matrix, int width, int height, string label)
        //{
        //    double[] array = DataTools.Matrix2Array(matrix);
        //    SpectralStats stats = GetModeAndOneTailedStandardDeviation(array, width, UpperPercentileDefault);
        //    double value = stats.GetValueOfNthPercentile(UpperPercentileDefault);

        //    var image =
        //        GraphsAndCharts.DrawHistogram(
        //            label,
        //            stats.Distribution,
        //            stats.UpperPercentileBin,
        //            new Dictionary<string, double>()
        //            {
        //                        { "min",  stats.Minimum },
        //                        { "max",  stats.Maximum },
        //                        { "mode", stats.Mode },
        //                        { "sd",   stats.StandardDeviation },
        //                        { UpperPercentileLabel,  value },
        //                        { "count",  stats.Count },
        //            },
        //            width,
        //            height);
        //    return image;
        //}

        public static Dictionary <string, SpectralStats> WriteSummaryIndexDistributionStatistics(Dictionary <string, double[]> summaryIndices, DirectoryInfo outputDirectory, string fileStem)
        {
            // to accumulate the images
            int width     = 100; // pixels
            int height    = 100; // pixels
            var imageList = new List <Image>();
            Dictionary <string, SpectralStats> indexDistributionStatistics = new Dictionary <string, SpectralStats>();

            string[] indexKeys = summaryIndices.Keys.ToArray();

            foreach (string key in indexKeys)
            {
                if (summaryIndices.ContainsKey(key))
                {
                    double[]      array = summaryIndices[key];
                    SpectralStats stats = GetModeAndOneTailedStandardDeviation(array, width, UpperPercentileDefault);
                    stats.GetValueOfNthPercentile(UpperPercentileDefault, out int binId, out double value);
                    stats.UpperPercentileBin = binId;
                    indexDistributionStatistics.Add(key, stats); // add index statistics

                    // CVR (cover) and EVN (events/sec) have discrete, sparse distributions when calculating for zoomed tiles,
                    // and most values are in the zero bin.
                    // Therefore they return value = 0.0; This is a bug!
                    // To avoid this problem, set value = maximum when percentileBin = 0
                    if (binId == 0)
                    {
                        value = stats.Maximum;
                    }

                    imageList.Add(
                        GraphsAndCharts.DrawHistogram(
                            key,
                            stats.Distribution,
                            stats.UpperPercentileBin,
                            new Dictionary <string, double>()
                    {
                        { "min", stats.Minimum },
                        { "max", stats.Maximum },
                        { "mode", stats.Mode },
                        { "sd", stats.StandardDeviation },
                        { UpperPercentileLabel, value },
                        { "count", stats.Count },
                    },
                            width,
                            height));
                }
            }

            FileInfo statsFile = new FileInfo(GetSummaryStatsPath(outputDirectory, fileStem));

            Json.Serialise(statsFile, indexDistributionStatistics);

            Image  image3    = ImageTools.CombineImagesVertically(imageList.ToArray());
            string imagePath = GetSummaryImagePath(outputDirectory, fileStem);

            image3.Save(imagePath);

            return(indexDistributionStatistics);
        }
Ejemplo n.º 4
0
        } // HiRes3() spectrogram images

        /// <summary>
        /// HERVE GLOTIN
        ///  To produce HIres spectrogram images
        ///  This is used to analyse Herve Glotin's BIRD50 data set.
        ///  Joins images of the same species
        /// </summary>
        public static void HiRes4()
        {
            // set up IP and OP directories
            string inputDir = @"C:\SensorNetworks\Output\BIRD50\Testing";
            string imageInputDir = @"C:\SensorNetworks\Output\BIRD50\TrainingRidgeImages";
            string imageOutputDir = @"C:\SensorNetworks\Output\BIRD50\TrainingSpeciesImages";

            //string imageOutputDir = @"C:\SensorNetworks\Output\BIRD50\TestingRidgeImages";
            string speciesLabelsFile = @"C:\SensorNetworks\Output\BIRD50\AmazonBird50_training_output.csv";
            string countsArrayFilePath = @"C:\SensorNetworks\Output\BIRD50\AmazonBird50_training_Counts.txt";
            int speciesCount = 50;
            int count = 924; //trainingCount

            //int count = 375; //testCount
            //count = 3;

            // READ IN THE SPECIES LABELS FILE AND SET UP THE DATA
            string[] fileID = new string[count];
            int[] speciesID = new int[speciesCount];
            BirdClefExperiment1.ReadGlotinsSpeciesLabelFile(speciesLabelsFile, count, out fileID, out speciesID);

            // INIT array of species counts
            int[] speciesNumbers = new int[speciesCount];

            // loop through all 50 species
            for (int i = 0; i < speciesCount; i++)
            {
                int speciesLabel = i + 1;
                Console.WriteLine("Species " + speciesLabel);

                // set up the image list for one species
                List<Image> imageList = new List<Image>();

                for (int j = 0; j < count; j++)
                {
                    if (speciesID[j] != speciesLabel)
                    {
                        continue;
                    }

                    // get the file name
                    FileInfo file = new FileInfo(Path.Combine(imageInputDir, fileID[j] + ".Ridges.png"));
                    Image bmp = ImageTools.ReadImage2Bitmap(file.FullName);
                    imageList.Add(bmp);

                    speciesNumbers[i]++;
                } // end for loop j

                Image combinedImage = ImageTools.CombineImagesVertically(imageList, 900);
                string outputFileName = string.Format("Species{0}.png", speciesLabel);
                string imagePath = Path.Combine(imageOutputDir, outputFileName);
                combinedImage.Save(imagePath);
            } // end for loop i

            int sum = speciesNumbers.Sum();
            Console.WriteLine("Sum of species number array = " + sum);
            bool addLineNumbers = true;
            FileTools.WriteArray2File(speciesNumbers, addLineNumbers, countsArrayFilePath);
        } // Herve Glotin's BIRD50 Dataset,  Joins images of the same species
        public static Image DrawTStatisticSpectrogramsOfSingleIndex(string key, LDSpectrogramRGB cs1, LDSpectrogramRGB cs2, double tStatThreshold)
        {
            var image1 = cs1.DrawGreyscaleSpectrogramOfIndex(key);
            var image2 = cs2.DrawGreyscaleSpectrogramOfIndex(key);

            if (image1 == null || image2 == null)
            {
                Console.WriteLine("WARNING: From method ColourSpectrogram.DrawTStatisticGreyscaleSpectrogramOfIndex()");
                Console.WriteLine("         Null image returned with key: {0}", key);
                return(null);
            }

            //frame image 1
            int nyquist      = cs1.SampleRate / 2;
            int herzInterval = 1000;

            string title    = $"{key} SPECTROGRAM for: {cs1.FileName}.      (scale:hours x kHz)";
            var    titleBar = LDSpectrogramRGB.DrawTitleBarOfGrayScaleSpectrogram(title, image1.Width);

            image1 = LDSpectrogramRGB.FrameLDSpectrogram(image1, titleBar, cs1, nyquist, herzInterval);

            //frame image 2
            title    = $"{key} SPECTROGRAM for: {cs2.FileName}.      (scale:hours x kHz)";
            titleBar = LDSpectrogramRGB.DrawTitleBarOfGrayScaleSpectrogram(title, image2.Width);
            image2   = LDSpectrogramRGB.FrameLDSpectrogram(image2, titleBar, cs1, nyquist, herzInterval);

            //get matrices required to calculate matrix of t-statistics
            double[,] avg1 = cs1.GetSpectrogramMatrix(key);
            if (key.Equals("ENT"))
            {
                avg1 = MatrixTools.SubtractValuesFromOne(avg1);
            }

            double[,] std1 = cs1.GetStandarDeviationMatrix(key);
            double[,] avg2 = cs2.GetSpectrogramMatrix(key);
            if (key.Equals("ENT"))
            {
                avg2 = MatrixTools.SubtractValuesFromOne(avg2);
            }

            double[,] std2 = cs2.GetStandarDeviationMatrix(key);

            //draw a spectrogram of t-statistic values
            //double[,] tStatMatrix = SpectrogramDifference.GetTStatisticMatrix(avg1, std1, cs1.SampleCount, avg2, std2, cs2.SampleCount);
            //Image image3 = SpectrogramDifference.DrawTStatisticSpectrogram(tStatMatrix);
            //titleBar = SpectrogramDifference.DrawTitleBarOfTStatisticSpectrogram(cs1.BaseName, cs2.BaseName, image1.Width, titleHt);
            //image3 = ColourSpectrogram.FrameSpectrogram(image3, titleBar, minOffset, cs2.X_interval, cs2.Y_interval);

            //draw a difference spectrogram derived from by thresholding a t-statistic matrix
            var image4 = DrawDifferenceSpectrogramDerivedFromSingleTStatistic(key, cs1, cs2, tStatThreshold, ColourGain);

            title    = string.Format("{0} DIFFERENCE SPECTROGRAM (thresholded by t-statistic={3}) for: {1} - {2}.      (scale:hours x kHz)", key, cs1.FileName, cs2.FileName, tStatThreshold);
            titleBar = LDSpectrogramRGB.DrawTitleBarOfGrayScaleSpectrogram(title, image2.Width);
            image4   = LDSpectrogramRGB.FrameLDSpectrogram(image4, titleBar, cs2, nyquist, herzInterval);

            var combinedImage = ImageTools.CombineImagesVertically(image1, image2, image4);

            return(combinedImage);
        }
        /// <summary>
        /// This method compares the acoustic indices derived from two different long duration recordings of the same length.
        /// It takes as input six csv files of acoustic indices in spectrogram columns, three csv files for each of the original recordings to be compared.
        /// The method produces one spectrogram image files:
        /// 1) A false-colour difference spectrogram, where the difference is shown as a plus/minus departure from grey.
        /// </summary>
        public static void DrawDifferenceSpectrogram(DirectoryInfo ipdir, FileInfo ipFileName1, FileInfo ipFileName2, DirectoryInfo opdir)
        {
            var cs1 = new LDSpectrogramRGB(minuteOffset, xScale, sampleRate, frameWidth, colorMap)
            {
                FileName         = ipFileName1.Name,
                ColorMode        = colorMap,
                BackgroundFilter = backgroundFilterCoeff,
            };

            string[] keys = colorMap.Split('-');
            cs1.ReadCsvFiles(ipdir, ipFileName1.Name, keys);
            if (cs1.GetCountOfSpectrogramMatrices() == 0)
            {
                LoggedConsole.WriteLine("There are no spectrogram matrices in cs1.dictionary.");
                return;
            }

            var cs2 = new LDSpectrogramRGB(minuteOffset, xScale, sampleRate, frameWidth, colorMap)
            {
                FileName         = ipFileName2.Name,
                ColorMode        = colorMap,
                BackgroundFilter = backgroundFilterCoeff,
            };

            cs2.ReadCsvFiles(ipdir, ipFileName2.Name, keys);
            if (cs2.GetCountOfSpectrogramMatrices() == 0)
            {
                LoggedConsole.WriteLine("There are no spectrogram matrices in cs2.dictionary.");
                return;
            }

            //string title1 = String.Format("DIFFERENCE SPECTROGRAM ({0} - {1})      (scale:hours x kHz)       (colour: R-G-B={2})", ipFileName1, ipFileName2, cs1.ColorMODE);
            //Image deltaSp1 = LDSpectrogramDifference.DrawDifferenceSpectrogram(cs1, cs2, colourGain);
            //Image titleBar1 = LDSpectrogramRGB.DrawTitleBarOfFalseColourSpectrogram(title1, deltaSp1.Width, SpectrogramConstants.HEIGHT_OF_TITLE_BAR);
            //deltaSp1 = LDSpectrogramRGB.FrameSpectrogram(deltaSp1, titleBar1, minuteOffset, cs1.X_interval, cs1.Y_interval);
            //string opFileName1 = ipFileName1 + ".Difference.COLNEG.png";
            //deltaSp1.Save(Path.Combine(opdir.FullName, opFileName1));

            //Draw positive difference spectrograms in one image.
            double colourGain = 2.0;

            Image <Rgb24>[] images = DrawPositiveDifferenceSpectrograms(cs1, cs2, colourGain);

            int    nyquist      = cs1.SampleRate / 2;
            int    herzInterval = 1000;
            string title        =
                $"DIFFERENCE SPECTROGRAM where {ipFileName1} > {ipFileName2}.      (scale:hours x kHz)       (colour: R-G-B={cs1.ColorMode})";
            var titleBar = LDSpectrogramRGB.DrawTitleBarOfFalseColourSpectrogram(title, images[0].Width);

            images[0] = LDSpectrogramRGB.FrameLDSpectrogram(images[0], titleBar, cs1, nyquist, herzInterval);

            title     = string.Format("DIFFERENCE SPECTROGRAM where {1} > {0}      (scale:hours x kHz)       (colour: R-G-B={2})", ipFileName1, ipFileName2, cs1.ColorMode);
            titleBar  = LDSpectrogramRGB.DrawTitleBarOfFalseColourSpectrogram(title, images[1].Width);
            images[1] = LDSpectrogramRGB.FrameLDSpectrogram(images[1], titleBar, cs1, nyquist, herzInterval);
            Image  combinedImage = ImageTools.CombineImagesVertically(images);
            string opFileName    = ipFileName1 + "-" + ipFileName2 + ".Difference.png";

            combinedImage.Save(Path.Combine(opdir.FullName, opFileName));
        }
Ejemplo n.º 7
0
        public static Image <Rgb24> FrameSliceOf3DSpectrogram_DayOfYear(Image <Rgb24> bmp1, Image <Rgb24> titleBar, int year, int dayOfYear, TimeSpan xInterval, int herzValue, FileInfo sunriseSetData, int nyquistFreq)
        {
            Image <Rgb24> suntrack = SunAndMoon.AddSunTrackToImage(bmp1.Width, sunriseSetData, year, dayOfYear);

            bmp1.Mutate(g =>
            {
                Pen pen        = new Pen(Color.White, 1);
                var stringFont = Drawing.Arial12;

                //Font stringFont = Drawing.Tahoma9;

                DateTime theDate  = new DateTime(year, 1, 1).AddDays(dayOfYear - 1);
                string dateString = $"{year} {DataTools.MonthNames[theDate.Month - 1]} {theDate.Day:d2}";
                g.DrawText(dateString, stringFont, Color.Wheat, new PointF(10, 3));
            });

            TimeSpan xAxisPixelDuration = TimeSpan.FromSeconds(60);
            var      minuteOffset       = TimeSpan.Zero;
            double   secondsDuration    = xAxisPixelDuration.TotalSeconds * bmp1.Width;
            TimeSpan fullDuration       = TimeSpan.FromSeconds(secondsDuration);

            // init frequency scale
            int herzInterval = 1000;
            int frameSize    = bmp1.Height;
            var freqScale    = new DSP.FrequencyScale(nyquistFreq, frameSize, herzInterval);

            SpectrogramTools.DrawGridLinesOnImage((Image <Rgb24>)bmp1, minuteOffset, fullDuration, xInterval, freqScale);

            int trackHeight      = 20;
            int imageHt          = bmp1.Height + trackHeight + trackHeight + trackHeight;
            var xAxisTicInterval = TimeSpan.FromMinutes(60); // assume 60 pixels per hour
            var timeScale24Hour  = ImageTrack.DrawTimeTrack(fullDuration, minuteOffset, xAxisTicInterval, bmp1.Width, trackHeight, "hours");

            var imageList = new List <Image <Rgb24> >
            {
                titleBar,
                timeScale24Hour,
                suntrack,
                bmp1,
                timeScale24Hour
            };
            var compositeBmp = ImageTools.CombineImagesVertically(imageList);

            // trackHeight = compositeBmp.Height;
            // Image<Rgb24> timeScale12Months = ImageTrack.DrawYearScaleVertical(40, trackHeight);
            // Image<Rgb24> freqScale = DrawFreqScale_vertical(40, trackHeight, HerzValue, nyquistFreq);

            imageList = new List <Image <Rgb24> >();

            // imageList.Add(timeScale12Months);
            imageList.Add(compositeBmp);

            // imageList.Add(freqScale);
            compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray());

            return(compositeBmp);
        }
        /// <summary>
        /// Asumes signal is between -1 and +1.
        /// </summary>
        public static Image <Rgb24> DrawWaveform(string label, double[] signal, int imageWidth, int height, double scalingFactor)
        {
            Pen pen1       = new Pen(Color.White, 1f);
            Pen pen2       = new Pen(Color.Lime, 1f);
            Pen pen3       = new Pen(Color.Wheat, 1f);
            var stringFont = Drawing.Arial9;

            int barWidth = imageWidth / signal.Length;

            // DataTools.getMaxIndex(signal, out int maxBin);
            // double maxValue = signal[maxBin];
            // double sum = histogram.Sum();
            // double[] normalArray = DataTools.NormaliseArea()

            int yzero = height / 2;
            int grid1 = imageWidth / 4;
            int grid2 = imageWidth / 2;
            int grid3 = imageWidth * 3 / 4;

            var bmp1 = new Image <Rgb24>(imageWidth, height);

            bmp1.Mutate(g1 =>
            {
                g1.Clear(Color.Black);
                g1.DrawLine(pen3, 0, yzero, imageWidth, yzero);
                g1.DrawLine(pen3, grid1, height - 1, grid1, 0);
                g1.DrawLine(pen3, grid2, height - 1, grid2, 0);
                g1.DrawLine(pen3, grid3, height - 1, grid3, 0);
                g1.DrawLine(pen1, 0, height - 1, imageWidth, height - 1);

                // draw mode bin and upper percentile bound
                //g1.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
                //g1.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

                int previousY = yzero;
                for (int b = 0; b < signal.Length; b++)
                {
                    int x = b * barWidth;
                    int y = yzero - (int)Math.Ceiling(signal[b] * height * scalingFactor);
                    g1.DrawLine(pen2, x, previousY, x + 1, y);
                    previousY = y;
                }
            });

            var bmp2 = new Image <Rgb24>(imageWidth, 20);

            bmp2.Mutate(g2 =>
            {
                g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
                g2.DrawText(label, stringFont, Color.Wheat, new PointF(4, 3));
            });

            Image <Rgb24>[] images = { bmp2, bmp1 };
            Image <Rgb24>   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Creates an image from the frequency/oscillations matrix.
        /// The y-axis scale = frequency bins as per normal spectrogram.
        /// The x-axis scale is oscillations per second.
        /// </summary>
        /// <param name="freqOscilMatrix">the input frequency/oscillations matrix</param>
        /// <param name="framesPerSecond">to give the time scale</param>
        /// <param name="freqBinWidth">to give the frequency scale</param>
        /// <param name="sampleLength">to allow calculation of the oscillations scale</param>
        /// <param name="algorithmName">the algorithm used to compute the oscillations.</param>
        /// <returns>bitmap image</returns>
        public static Image GetFreqVsOscillationsImage(double[,] freqOscilMatrix, double framesPerSecond, double freqBinWidth, int sampleLength, string algorithmName)
        {
            // remove the high cycles/sec end of the matrix because nothing really happens here.
            int maxRows = freqOscilMatrix.GetLength(0) / 2;

            freqOscilMatrix = MatrixTools.Submatrix(freqOscilMatrix, 0, 0, maxRows - 1, freqOscilMatrix.GetLength(1) - 1);

            // get the OSC spectral index
            var spectralIndex = MatrixTools.GetMaximumColumnValues(freqOscilMatrix);

            // Convert spectrum index to oscillations per second
            double oscillationBinWidth = framesPerSecond / sampleLength;

            //draw an image
            freqOscilMatrix = MatrixTools.MatrixRotate90Anticlockwise(freqOscilMatrix);

            // each value is to be drawn as a 5 pixel x 5 pixel square
            int xscale = 5;
            int yscale = 5;

            if (maxRows < 10)
            {
                xscale = 10;
            }

            //var image1 = ImageTools.DrawMatrixInColour(freqOscilMatrix, xPixelsPerCell: xscale, yPixelsPerCell: yscale);
            //var image2 = ImageTools.DrawVectorInColour(DataTools.reverseArray(spectralIndex), cellWidth: xscale);
            var image1 = ImageTools.DrawMatrixInGrayScale(freqOscilMatrix, xPixelsPerCell: xscale, yPixelsPerCell: yscale, reverse: true);

            spectralIndex = DataTools.NormaliseByScalingMaxValueToOne(spectralIndex);
            var image2 = ImageTools.DrawVectorInGrayScaleWithoutNormalisation(DataTools.reverseArray(spectralIndex), xscale, yscale, reverse: true);

            var image = ImageTools.CombineImagesInLine(new[] { image1, image2 });

            // place a grid line every 5 cycles per second.
            double cycleInterval = 5.0;
            double xTicInterval  = cycleInterval / oscillationBinWidth * xscale;

            // a tic every 1000 Hz.
            int    herzInterval = 1000;
            double yTicInterval = herzInterval / freqBinWidth * yscale;

            int xOffset = xscale / 2;
            int yOffset = yscale / 2;

            image = ImageTools.DrawYaxisScale(image, 10, herzInterval, yTicInterval, yOffset);
            image = ImageTools.DrawXaxisScale(image, 15, cycleInterval, xTicInterval, 10, -xOffset);

            var titleBar  = DrawTitleBarOfOscillationSpectrogram(algorithmName, image.Width);
            var imageList = new List <Image> {
                titleBar, image
            };
            var compositeBmp = (Bitmap)ImageTools.CombineImagesVertically(imageList);

            return(compositeBmp);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// This is cut down version of the method of same name in LDSpectrogramRGB.cs.
        /// </summary>
        /// <param name="ldSpectrogramConfig">config for ldfc spectrogram.</param>
        /// <param name="outputDirectory">outputDirectory.</param>
        /// <param name="indexGenerationData">indexGenerationData.</param>
        /// <param name="basename">stem name of the original recording.</param>
        /// <param name="indexSpectrograms">Optional spectra to pass in. If specified the spectra will not be loaded from disk!.</param>
        private static string DrawSpectrogramsFromSpectralIndices(
            LdSpectrogramConfig ldSpectrogramConfig,
            DirectoryInfo outputDirectory,
            IndexGenerationData indexGenerationData,
            string basename,
            Dictionary <string, double[, ]> indexSpectrograms = null)
        {
            string colorMap1            = ldSpectrogramConfig.ColorMap1; // SpectrogramConstants.RGBMap_ACI_ENT_EVN;
            string colorMap2            = ldSpectrogramConfig.ColorMap2; // SpectrogramConstants.RGBMap_BGN_PMN_OSC;
            double blueEnhanceParameter = ldSpectrogramConfig.BlueEnhanceParameter.Value;

            var    cs1      = new LDSpectrogramRGB(ldSpectrogramConfig, indexGenerationData, colorMap1);
            string fileStem = basename;

            cs1.FileName = fileStem;

            // calculate start time by combining DatetimeOffset with minute offset.
            cs1.StartOffset = indexGenerationData.AnalysisStartOffset;
            if (indexGenerationData.RecordingStartDate.HasValue)
            {
                DateTimeOffset dto = (DateTimeOffset)indexGenerationData.RecordingStartDate;
                cs1.RecordingStartDate = dto;
                if (dto != null)
                {
                    cs1.StartOffset = dto.TimeOfDay + cs1.StartOffset;
                }
            }

            var indexProperties = IndexCalculateSixOnly.GetIndexProperties();

            cs1.SetSpectralIndexProperties(indexProperties);

            // Load the Index Spectrograms into a Dictionary
            cs1.LoadSpectrogramDictionary(indexSpectrograms);
            if (cs1.GetCountOfSpectrogramMatrices() == 0)
            {
                Log.Error("No spectrogram matrices in the dictionary. Spectrogram files do not exist?");
                throw new InvalidOperationException("Cannot find spectrogram matrix files");
            }

            // draw all available gray scale index spectrograms.
            var keys = indexProperties.Keys.ToArray();

            cs1.DrawGreyScaleSpectrograms(outputDirectory, fileStem, keys);

            // create two false-color spectrogram images
            var   image1NoChrome = cs1.DrawFalseColorSpectrogramChromeless(cs1.ColorMode, colorMap1, blueEnhanceParameter);
            var   image2NoChrome = cs1.DrawFalseColorSpectrogramChromeless(cs1.ColorMode, colorMap2, blueEnhanceParameter);
            var   spacer         = new Image <Rgb24>(image1NoChrome.Width, 10);
            var   imageList      = new[] { image1NoChrome, spacer, image2NoChrome, spacer };
            Image image3         = ImageTools.CombineImagesVertically(imageList);
            var   outputPath     = FilenameHelpers.AnalysisResultPath(outputDirectory, fileStem, "2Maps", "png");

            image3.Save(outputPath);
            return(outputPath);
        }
Ejemplo n.º 11
0
        public static Image <Rgb24> ConcatenateFourChannelImages(FileInfo[] imageFiles, DirectoryInfo imageDirectory, string fileSuffix, string date)
        {
            // get first image to find its dimensions
            var image = (Image <Rgb24>)Image.Load(imageFiles[0].FullName);

            var  brush      = Color.White;
            Font stringFont = Drawing.Tahoma12;

            //create spacer image
            int           width       = 1;
            int           height      = image.Height;
            Image <Rgb24> spacerImage = new Image <Rgb24>(width, height);

            spacerImage.Mutate(g =>
            {
                g.Clear(Color.DarkGray);
            });

            // init output list of images
            var fourChannelList = new List <Image <Rgb24> >();

            for (int channel = 0; channel < 4; channel++)
            {
                var imageList = new List <Image <Rgb24> >();

                //   Monitoring_Rosin_20120329T000000 + 0200_.merged.wav.channel_0__2Maps.png;
                string fileMatch = $@"0000+0200_.merged.wav.channel_{channel}__{fileSuffix}";

                foreach (FileInfo imageFile in imageFiles)
                {
                    if (!imageFile.Name.EndsWith(fileMatch))
                    {
                        continue;
                    }

                    image = (Image <Rgb24>)Image.Load(imageFile.FullName);
                    imageList.Add(image);
                    imageList.Add(spacerImage);
                }

                imageList.Add(spacerImage);
                imageList.Add(spacerImage);
                var concatImage = ImageTools.CombineImagesInLine(imageList);
                concatImage.Mutate(g =>
                {
                    string chn = $"ch{channel + 1}";
                    g.DrawTextSafe(chn, stringFont, brush, new PointF(2, 40));
                });

                fourChannelList.Add(concatImage);
            }

            var combinedImage = ImageTools.CombineImagesVertically(fourChannelList);

            return(combinedImage);
        }
Ejemplo n.º 12
0
        public static Image FrameSliceOf3DSpectrogram_ConstantMin(Bitmap bmp1, Image titleBar, int nyquistFreq, int minuteOfDay, FileInfo sunriseSetData)
        {
            int imageWidth  = bmp1.Width;
            int imageHeight = bmp1.Height;

            Graphics g          = Graphics.FromImage(bmp1);
            Pen      pen        = new Pen(Color.White);
            Font     stringFont = new Font("Arial", 12);

            TimeSpan time = TimeSpan.FromMinutes(minuteOfDay);
            string   str  = string.Format("Time = {0}h:{1}m", time.Hours, time.Minutes);

            g.DrawString(str, stringFont, Brushes.Wheat, new PointF(10, 7));

            int binCount = 512;

            if (imageHeight <= 256)
            {
                binCount = 256;
            }

            int    lineCount        = nyquistFreq / 1000;
            double gridLineInterval = 1000 / (nyquistFreq / (double)binCount);

            for (int i = 1; i <= lineCount; i++)
            {
                int y = imageHeight - (int)Math.Round(i * gridLineInterval);
                for (int x = 1; x < imageWidth; x++)
                {
                    bmp1.SetPixel(x, y, Color.White);
                    bmp1.SetPixel(x - 1, y, Color.Black);
                    x++;
                }
            }

            AddDaylightMinutesToImage(bmp1, sunriseSetData, minuteOfDay);

            //TimeSpan xAxisPixelDuration = TimeSpan.FromSeconds(60);
            //var minOffset = TimeSpan.Zero;
            //SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp1, minOffset, X_interval, xAxisPixelDuration, 120, 10);

            const int trackHeight       = 20;
            var       timeScale12Months = ImageTrack.DrawYearScale_horizontal(imageWidth, trackHeight);
            var       imageList         = new List <Image> {
                titleBar, timeScale12Months, bmp1, timeScale12Months
            };
            var compositeBmp = ImageTools.CombineImagesVertically(imageList.ToArray());

            //imageWidth = compositeBmp.Height;
            //imageList = new List<Image>();
            //imageList.Add(timeScale12Months);
            //imageList.Add(compositeBmp);
            //compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray());

            return(compositeBmp);
        }
Ejemplo n.º 13
0
        public static Image DrawGraph(string label, double[] histogram, int imageWidth, int height, int scalingFactor)
        {
            Pen pen1 = new Pen(Color.White);

            //Pen pen2 = new Pen(Color.Red);
            Pen pen3 = new Pen(Color.Wheat);

            //Pen pen4 = new Pen(Color.Purple);
            var brush      = new SolidBrush(Color.Red);
            var stringFont = new Font("Arial", 9);

            //Font stringFont = new Font("Tahoma", 9);
            //SizeF stringSize = new SizeF();

            int barWidth = imageWidth / histogram.Length;

            // double sum = histogram.Sum();
            // DataTools.getMaxIndex(histogram, out int maxBin);

            //double maxValue = histogram[maxBin];
            var bmp1 = new Bitmap(imageWidth, height, PixelFormat.Format24bppRgb);
            var g1   = Graphics.FromImage(bmp1);

            g1.Clear(Color.Black);

            for (int i = 1; i < 10; i++)
            {
                int grid = imageWidth * i / 10;
                g1.DrawLine(pen3, grid, height - 1, grid, 0);
            }

            g1.DrawLine(pen1, 0, height - 1, imageWidth, height - 1);

            // draw mode bin and upper percentile bound
            //g.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
            //g.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

            for (int b = 0; b < histogram.Length; b++)
            {
                int x = b * barWidth;
                int y = (int)Math.Ceiling(histogram[b] * height * scalingFactor);
                g1.FillRectangle(brush, x, height - y - 1, barWidth, y);
            }

            Bitmap   bmp2 = new Bitmap(imageWidth, 20, PixelFormat.Format24bppRgb);
            Graphics g2   = Graphics.FromImage(bmp2);

            g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
            g2.DrawString(label, stringFont, Brushes.Wheat, new PointF(4, 3));

            Image[] images = { bmp2, bmp1 };
            Image   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 14
0
        public static Image FrameSliceOf3DSpectrogram_DayOfYear(Image bmp1, Image titleBar, int year, int dayOfYear, TimeSpan xInterval, int herzValue, FileInfo sunriseSetData, int nyquistFreq)
        {
            Bitmap suntrack = SunAndMoon.AddSunTrackToImage(bmp1.Width, sunriseSetData, year, dayOfYear);

            Graphics g          = Graphics.FromImage(bmp1);
            Pen      pen        = new Pen(Color.White);
            Font     stringFont = new Font("Arial", 12);

            //Font stringFont = new Font("Tahoma", 9);

            DateTime theDate    = new DateTime(year, 1, 1).AddDays(dayOfYear - 1);
            string   dateString = string.Format("{0} {1} {2:d2}", year, DataTools.MonthNames[theDate.Month - 1], theDate.Day);

            g.DrawString(dateString, stringFont, Brushes.Wheat, new PointF(10, 3));

            TimeSpan xAxisPixelDuration = TimeSpan.FromSeconds(60);
            var      minuteOffset       = TimeSpan.Zero;
            double   secondsDuration    = xAxisPixelDuration.TotalSeconds * bmp1.Width;
            TimeSpan fullDuration       = TimeSpan.FromSeconds(secondsDuration);

            // init frequency scale
            int herzInterval = 1000;
            int frameSize    = bmp1.Height;
            var freqScale    = new DSP.FrequencyScale(nyquistFreq, frameSize, herzInterval);

            SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp1, minuteOffset, fullDuration, xInterval, freqScale);

            int trackHeight      = 20;
            int imageHt          = bmp1.Height + trackHeight + trackHeight + trackHeight;
            var xAxisTicInterval = TimeSpan.FromMinutes(60); // assume 60 pixels per hour
            var timeScale24Hour  = ImageTrack.DrawTimeTrack(fullDuration, minuteOffset, xAxisTicInterval, bmp1.Width, trackHeight, "hours");

            var imageList = new List <Image>();

            imageList.Add(titleBar);
            imageList.Add(timeScale24Hour);
            imageList.Add(suntrack);
            imageList.Add(bmp1);
            imageList.Add(timeScale24Hour);
            Image compositeBmp = ImageTools.CombineImagesVertically(imageList.ToArray());

            // trackHeight = compositeBmp.Height;
            // Bitmap timeScale12Months = ImageTrack.DrawYearScaleVertical(40, trackHeight);
            // Bitmap freqScale = DrawFreqScale_vertical(40, trackHeight, HerzValue, nyquistFreq);

            imageList = new List <Image>();

            // imageList.Add(timeScale12Months);
            imageList.Add(compositeBmp);

            // imageList.Add(freqScale);
            compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray());

            return(compositeBmp);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Asumes signal is between -1 and +1.
        /// </summary>
        public static Image DrawWaveform(string label, double[] signal, int imageWidth, int height, double scalingFactor)
        {
            Pen  pen1       = new Pen(Color.White);
            Pen  pen2       = new Pen(Color.Lime);
            Pen  pen3       = new Pen(Color.Wheat);
            Font stringFont = new Font("Arial", 9);

            int barWidth = imageWidth / signal.Length;

            // DataTools.getMaxIndex(signal, out int maxBin);
            // double maxValue = signal[maxBin];
            // double sum = histogram.Sum();
            // double[] normalArray = DataTools.NormaliseArea()

            int yzero = height / 2;
            int grid1 = imageWidth / 4;
            int grid2 = imageWidth / 2;
            int grid3 = imageWidth * 3 / 4;

            Bitmap   bmp1 = new Bitmap(imageWidth, height, PixelFormat.Format24bppRgb);
            Graphics g1   = Graphics.FromImage(bmp1);

            g1.Clear(Color.Black);
            g1.DrawLine(pen3, 0, yzero, imageWidth, yzero);
            g1.DrawLine(pen3, grid1, height - 1, grid1, 0);
            g1.DrawLine(pen3, grid2, height - 1, grid2, 0);
            g1.DrawLine(pen3, grid3, height - 1, grid3, 0);
            g1.DrawLine(pen1, 0, height - 1, imageWidth, height - 1);

            // draw mode bin and upper percentile bound
            //g1.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
            //g1.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

            int previousY = yzero;

            for (int b = 0; b < signal.Length; b++)
            {
                int x = b * barWidth;
                int y = yzero - (int)Math.Ceiling(signal[b] * height * scalingFactor);
                g1.DrawLine(pen2, x, previousY, x + 1, y);
                previousY = y;
            }

            Bitmap   bmp2 = new Bitmap(imageWidth, 20, PixelFormat.Format24bppRgb);
            Graphics g2   = Graphics.FromImage(bmp2);

            g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
            g2.DrawString(label, stringFont, Brushes.Wheat, new PointF(4, 3));

            Image[] images = { bmp2, bmp1 };
            Image   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Assumes passed data has been normalised in 0,1.
        /// </summary>
        public static Image <Rgb24> DrawGraph(string label, double[] normalisedData, int imageHeight)
        {
            int imageWidth = normalisedData.Length;
            var pen1       = new Pen(Color.White, 1f);
            var pen2       = new Pen(Color.Red, 1f);

            // Pen pen3 = new Pen(Color.Wheat, 1);
            // Pen pen4 = new Pen(Color.Purple, 1);
            // SolidBrush brush = new SolidBrush(Color.Red);
            var stringFont = Drawing.Arial9;

            //Font stringFont = Drawing.Tahoma9;
            //SizeF stringSize = new SizeF();


            var bmp1 = new Image <Rgb24>(imageWidth, imageHeight);

            bmp1.Mutate(g1 =>
            {
                g1.Clear(Color.Black);

                //for (int i = 1; i < 10; i++)
                //{
                //    int grid = imageWidth * i / 10;
                //    g1.DrawLine(pen3, grid, height - 1, grid, 0);
                //}
                //g1.DrawLine(pen1, 0, height - 1, imageWidth, imageHeight - 1);
                // draw mode bin and upper percentile bound
                //g.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
                //g.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

                int previousY = (int)Math.Ceiling(normalisedData[0] * imageHeight);
                for (int x = 1; x < imageWidth; x++)
                {
                    int y = (int)Math.Ceiling(normalisedData[x] * imageHeight);
                    g1.DrawLine(pen2, x - 1, imageHeight - previousY, x, imageHeight - y);
                    previousY = y;
                }
            });

            var bmp2 = new Image <Rgb24>(imageWidth, 20);

            bmp2.Mutate(g2 =>
            {
                g2.DrawLine(pen1, 0, 0, imageWidth, 0);
                g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
                g2.DrawText(label, stringFont, Color.Wheat, new PointF(4, 3));
            });

            Image <Rgb24>[] images = { bmp2, bmp1 };
            Image <Rgb24>   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 17
0
        public static Image <Rgb24> FrameSliceOf3DSpectrogram_ConstantMin(Image <Rgb24> bmp1, Image <Rgb24> titleBar, int nyquistFreq, int minuteOfDay, FileInfo sunriseSetData)
        {
            int imageWidth  = bmp1.Width;
            int imageHeight = bmp1.Height;

            Pen  pen        = new Pen(Color.White, 1);
            Font stringFont = Drawing.Arial12;

            TimeSpan time = TimeSpan.FromMinutes(minuteOfDay);
            string   str  = $"Time = {time.Hours}h:{time.Minutes}m";

            bmp1.Mutate(g => { g.DrawText(str, stringFont, Color.Wheat, new PointF(10, 7)); });

            int binCount = 512;

            if (imageHeight <= 256)
            {
                binCount = 256;
            }

            int    lineCount        = nyquistFreq / 1000;
            double gridLineInterval = 1000 / (nyquistFreq / (double)binCount);

            for (int i = 1; i <= lineCount; i++)
            {
                int y = imageHeight - (int)Math.Round(i * gridLineInterval);
                for (int x = 1; x < imageWidth; x++)
                {
                    bmp1[x, y]     = Color.White;
                    bmp1[x - 1, y] = Color.Black;
                    x++;
                }
            }

            AddDaylightMinutesToImage(bmp1, sunriseSetData, minuteOfDay);

            //TimeSpan xAxisPixelDuration = TimeSpan.FromSeconds(60);
            //var minOffset = TimeSpan.Zero;
            //SpectrogramTools.DrawGridLinesOnImage((Image<Rgb24>)bmp1, minOffset, X_interval, xAxisPixelDuration, 120, 10);

            const int trackHeight       = 20;
            var       timeScale12Months = ImageTrack.DrawYearScale_horizontal(imageWidth, trackHeight);
            var       imageList         = new [] { titleBar, timeScale12Months, bmp1, timeScale12Months };
            var       compositeBmp      = ImageTools.CombineImagesVertically(imageList);

            //imageWidth = compositeBmp.Height;
            //imageList = new List<Image>();
            //imageList.Add(timeScale12Months);
            //imageList.Add(compositeBmp);
            //compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray());

            return(compositeBmp);
        }
        public static Image ConcatenateFourChannelImages(FileInfo[] imageFiles, DirectoryInfo imageDirectory, string fileSuffix, string date)
        {
            // get first image to find its dimensions
            Image image = Image.FromFile(imageFiles[0].FullName);

            Brush brush      = Brushes.White;
            Font  stringFont = new Font("Tahoma", 12);

            //create spacer image
            int      width       = 1;
            int      height      = image.Height;
            Bitmap   spacerImage = new Bitmap(width, height);
            Graphics g           = Graphics.FromImage(spacerImage);

            g.Clear(Color.DarkGray);

            // init output list of images
            var fourChannelList = new List <Image>();

            for (int channel = 0; channel < 4; channel++)
            {
                var imageList = new List <Image>();

                //   Monitoring_Rosin_20120329T000000 + 0200_.merged.wav.channel_0__2Maps.png;
                string fileMatch = string.Format(@"0000+0200_.merged.wav.channel_{0}__{1}", channel, fileSuffix);

                foreach (FileInfo imageFile in imageFiles)
                {
                    if (!imageFile.Name.EndsWith(fileMatch))
                    {
                        continue;
                    }

                    image = Image.FromFile(imageFile.FullName);
                    imageList.Add(image);
                    imageList.Add(spacerImage);
                }

                imageList.Add(spacerImage);
                imageList.Add(spacerImage);
                Image concatImage = ImageTools.CombineImagesInLine(imageList);
                g = Graphics.FromImage(concatImage);
                string chn = string.Format("ch{0}", channel + 1);
                g.DrawString(chn, stringFont, brush, new PointF(2, 40));

                fourChannelList.Add(concatImage);
            }

            Image combinedImage = ImageTools.CombineImagesVertically(fourChannelList);

            return(combinedImage);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// This method draws only top and bottom time scales and adds the title bar.
        /// It does NOT include the frequency grid lines.
        /// </summary>
        public static Image <Rgb24> FrameSonogram(
            Image <Rgb24> sonogramImage,
            Image <Rgb24> titleBar,
            TimeSpan minuteOffset,
            TimeSpan xAxisTicInterval,
            TimeSpan xAxisPixelDuration,
            TimeSpan labelInterval)
        {
            int imageWidth = sonogramImage.Width;
            var timeBmp    = ImageTrack.DrawShortTimeTrack(minuteOffset, xAxisPixelDuration, xAxisTicInterval, labelInterval, imageWidth, "Seconds");

            return(ImageTools.CombineImagesVertically(titleBar, timeBmp, sonogramImage, timeBmp));
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Assumes passed data has been normalised in 0,1.
        /// </summary>
        public static Image DrawGraph(string label, double[] normalisedData, int imageHeight)
        {
            int imageWidth = normalisedData.Length;
            var pen1       = new Pen(Color.White);
            var pen2       = new Pen(Color.Red);

            // Pen pen3 = new Pen(Color.Wheat);
            // Pen pen4 = new Pen(Color.Purple);
            // SolidBrush brush = new SolidBrush(Color.Red);
            var stringFont = new Font("Arial", 9);

            //Font stringFont = new Font("Tahoma", 9);
            //SizeF stringSize = new SizeF();

            var bmp1 = new Bitmap(imageWidth, imageHeight, PixelFormat.Format24bppRgb);
            var g1   = Graphics.FromImage(bmp1);

            g1.Clear(Color.Black);

            //for (int i = 1; i < 10; i++)
            //{
            //    int grid = imageWidth * i / 10;
            //    g1.DrawLine(pen3, grid, height - 1, grid, 0);
            //}
            //g1.DrawLine(pen1, 0, height - 1, imageWidth, imageHeight - 1);
            // draw mode bin and upper percentile bound
            //g.DrawLine(pen4, modeBin, height - 1, modeBin, 0);
            //g.DrawLine(pen4, upperBound, height - 1, upperBound, 0);

            int previousY = (int)Math.Ceiling(normalisedData[0] * imageHeight);

            for (int x = 1; x < imageWidth; x++)
            {
                int y = (int)Math.Ceiling(normalisedData[x] * imageHeight);
                g1.DrawLine(pen2, x - 1, imageHeight - previousY, x, imageHeight - y);
                previousY = y;
            }

            Bitmap   bmp2 = new Bitmap(imageWidth, 20, PixelFormat.Format24bppRgb);
            Graphics g2   = Graphics.FromImage(bmp2);

            g2.DrawLine(pen1, 0, 0, imageWidth, 0);
            g2.DrawLine(pen1, 0, bmp2.Height - 1, imageWidth, bmp2.Height - 1);
            g2.DrawString(label, stringFont, Brushes.Wheat, new PointF(4, 3));

            Image[] images = { bmp2, bmp1 };
            Image   bmp    = ImageTools.CombineImagesVertically(images);

            return(bmp);
        }
Ejemplo n.º 21
0
        public void TestCombineImagesVertically()
        {
            var actual = ImageTools.CombineImagesVertically(
                null,
                Drawing.NewImage(100, 100, Color.Red),
                Drawing.NewImage(100, 20, Color.Red),
                Drawing.NewImage(100, 200, Color.Red),
                null,
                Drawing.NewImage(100, 20, Color.Red),
                null);

            Assert.That.ImageIsSize(100, 340, actual);
            Assert.That.ImageRegionIsColor(actual.Bounds(), Color.Red, actual);
        }
Ejemplo n.º 22
0
        public static Dictionary <string, SpectralStats> WriteSummaryIndexDistributionStatistics(Dictionary <string, double[]> summaryIndices, DirectoryInfo outputDirectory, string fileStem)
        {
            // to accumulate the images
            int width     = 100; // pixels
            int height    = 100; // pixels
            var imageList = new List <Image>();
            Dictionary <string, SpectralStats> indexDistributionStatistics = new Dictionary <string, SpectralStats>();

            string[] indexKeys = summaryIndices.Keys.ToArray();

            foreach (string key in indexKeys)
            {
                if (summaryIndices.ContainsKey(key))
                {
                    double[]      array = summaryIndices[key];
                    SpectralStats stats = GetModeAndOneTailedStandardDeviation(array, width, UpperPercentileDefault);
                    indexDistributionStatistics.Add(key, stats); // add index statistics
                    double value = stats.GetValueOfNthPercentile(UpperPercentileDefault);

                    imageList.Add(
                        GraphsAndCharts.DrawHistogram(
                            key,
                            stats.Distribution,
                            stats.UpperPercentileBin,
                            new Dictionary <string, double>()
                    {
                        { "min", stats.Minimum },
                        { "max", stats.Maximum },
                        { "mode", stats.Mode },
                        { "sd", stats.StandardDeviation },
                        { UpperPercentileLabel, value },
                        { "count", stats.Count },
                    },
                            width,
                            height));
                }
            }

            FileInfo statsFile = new FileInfo(GetSummaryStatsPath(outputDirectory, fileStem));

            Json.Serialise(statsFile, indexDistributionStatistics);

            Image  image3    = ImageTools.CombineImagesVertically(imageList.ToArray());
            string imagePath = GetSummaryImagePath(outputDirectory, fileStem);

            image3.Save(imagePath);

            return(indexDistributionStatistics);
        }
        // #######################################################################################################################################
        // ### ABOVE METHODS DRAW TIME GRID LINES ON SPECTROGRAMS ####################################################################################
        // #######################################################################################################################################

        public static Image <Rgb24> GetImageFullyAnnotated(Image <Rgb24> image, string title, int[,] gridLineLocations, TimeSpan duration)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            FrequencyScale.DrawFrequencyLinesOnImage((Image <Rgb24>)image, gridLineLocations, includeLabels: true);

            var titleBar       = LDSpectrogramRGB.DrawTitleBarOfGrayScaleSpectrogram(title, image.Width);
            var timeBmp        = ImageTrack.DrawTimeTrack(duration, image.Width);
            var compositeImage = ImageTools.CombineImagesVertically(titleBar, timeBmp, image, timeBmp);

            return(compositeImage);
        }
Ejemplo n.º 24
0
        public static Image FrameSliceOf3DSpectrogram_ConstantFreq(Image bmp1, Image titleBar, TimeSpan xInterval, int herzValue, FileInfo sunriseSetData, int nyquistFreq)
        {
            SunAndMoon.AddSunRiseSetLinesToImage((Bitmap)bmp1, sunriseSetData, 0, 365, 1); // assume full year and 1px/day

            var g          = Graphics.FromImage(bmp1);
            var pen        = new Pen(Color.White);
            var stringFont = new Font("Arial", 12);
            var str        = $"Freq = {herzValue} Hz";

            g.DrawString(str, stringFont, Brushes.Wheat, new PointF(10, 7));

            var    xAxisPixelDuration = TimeSpan.FromSeconds(60);
            var    startOffset        = TimeSpan.Zero;
            double secondsDuration    = xAxisPixelDuration.TotalSeconds * bmp1.Width;
            var    fullDuration       = TimeSpan.FromSeconds(secondsDuration);

            // init frequency scale
            int herzInterval = 1000;
            int frameSize    = bmp1.Height;
            var freqScale    = new DSP.FrequencyScale(nyquistFreq, frameSize, herzInterval);

            SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp1, startOffset, fullDuration, xInterval, freqScale);

            int trackHeight      = 20;
            var xAxisTicInterval = TimeSpan.FromMinutes(60); // assume 60 pixels per hour
            var timeScale24Hour  = ImageTrack.DrawTimeTrack(fullDuration, startOffset, xAxisTicInterval, bmp1.Width, trackHeight, "hours");

            var imageList = new List <Image> {
                titleBar, timeScale24Hour, bmp1, timeScale24Hour
            };
            var compositeBmp = ImageTools.CombineImagesVertically(imageList.ToArray());

            if (compositeBmp == null)
            {
                throw new ArgumentNullException(nameof(compositeBmp));
            }

            trackHeight = compositeBmp.Height;
            Bitmap timeScale12Months = ImageTrack.DrawYearScaleVertical(40, trackHeight);
            Bitmap freqScaleImage    = DrawFreqScale_vertical(40, trackHeight, herzValue, nyquistFreq);

            imageList = new List <Image> {
                timeScale12Months, compositeBmp, freqScaleImage
            };
            compositeBmp = ImageTools.CombineImagesInLine(imageList.ToArray());

            return(compositeBmp);
        }
Ejemplo n.º 25
0
        public static Image BriggsNoiseFilterAndGetSonograms(double[,] matrix, int percentileThreshold, double binaryThreshold,
                                                             TimeSpan recordingDuration, TimeSpan X_AxisInterval, TimeSpan stepDuration, int nyquist, int herzInterval)
        {
            //double[,] m = NoiseRemoval_Briggs.BriggsNoiseFilter(matrix, percentileThreshold);
            double[,] m = NoiseReduction_byDivisionAndSqrRoot(matrix, percentileThreshold);

            var images = new List <Image <Rgb24> >();

            string title  = "TITLE ONE";
            var    image1 = DrawSonogram(m, recordingDuration, X_AxisInterval, stepDuration, nyquist, herzInterval, title);

            images.Add(image1);

            m     = ImageTools.WienerFilter(m, 7); //Briggs uses 17
            m     = MatrixTools.SubtractAndTruncate2Zero(m, 1.0);
            title = "TITLE TWO";
            var image2 = DrawSonogram(m, recordingDuration, X_AxisInterval, stepDuration, nyquist, herzInterval, title);

            images.Add(image2);

            //int[] histo = Histogram.Histo(m, 100);
            //DataTools.writeArray(histo);
            //DataTools.WriteMinMaxOfArray(MatrixTools.Matrix2Array(m));

            m = MatrixTools.ThresholdMatrix2RealBinary(m, binaryThreshold);   //works for low SNR recordings

            //title = "TITLE THREE";
            //Image image3 = DrawSonogram(m, recordingDuration, X_AxisInterval, stepDuration, Y_AxisInterval, title);
            //images.Add(image3);

            m = ImageTools.GaussianBlur_5cell(m);

            //m = ImageTools.GaussianBlur_5cell(m);
            //m = ImageTools.Blur(m, 5); // use a simple neighbourhood blurring function.

            double binaryThreshold2 = binaryThreshold * 0.8;

            m     = MatrixTools.ThresholdMatrix2RealBinary(m, binaryThreshold2);
            title = "TITLE FOUR";
            var image4 = DrawSonogram(m, recordingDuration, X_AxisInterval, stepDuration, nyquist, herzInterval, title);

            images.Add(image4);

            Image combinedImage = ImageTools.CombineImagesVertically(images);

            return(combinedImage);
        }
Ejemplo n.º 26
0
        public static void TestTemplates(FileInfo listOfIndexFiles, FileInfo templatesFile, FileInfo imageOfLdfcSpectrogram)
        {
            var contentDictionary = ContentSignatures.ContentDescriptionOfMultipleRecordingFiles(listOfIndexFiles, templatesFile);

            // Write the results to a csv file
            var outputDirectory = templatesFile.DirectoryName;
            var filePath        = Path.Combine(outputDirectory ?? throw new InvalidOperationException("Output directory does not exist."), "AcousticSignatures.csv");

            FileTools.WriteDictionaryAsCsvFile(contentDictionary, filePath);

            // get content description plots and use to examine score distributions.
            var contentPlots = ContentSignatures.GetPlots(contentDictionary);
            var images       = GraphsAndCharts.DrawPlotDistributions(contentPlots);
            var plotsImage   = ImageTools.CombineImagesVertically(images);
            var path1        = Path.Combine(outputDirectory, "ScoreDistributions.png");

            plotsImage.Save(path1);

            // Attach plots to LDFC spectrogram and write to file
            var imageList = new List <Image <Rgb24> >();

            if (imageOfLdfcSpectrogram != null)
            {
                var ldfcSpectrogram = Image.Load <Rgb24>(imageOfLdfcSpectrogram.FullName);
                imageList.Add(ldfcSpectrogram);
            }

            if (contentPlots != null)
            {
                int plotHeight = 30;
                foreach (var plot in contentPlots)
                {
                    var imageOfPlot = plot.DrawAnnotatedPlot(plotHeight);
                    imageList.Add(imageOfPlot);
                }
            }

            if (imageList.Count != 0)
            {
                var opImage = ImageTools.CombineImagesVertically(imageList);
                var path2   = Path.Combine(outputDirectory, templatesFile.BaseName() + ".TestOfTemplates.png");
                opImage.Save(path2);
            }

            //Console.WriteLine("# Finished test of content description templates");
        }
Ejemplo n.º 27
0
        /// <summary>
        /// This method produces four spectrograms using four different values of neighbour hood decibel threshold.
        /// It can be used for test purposes.
        /// </summary>
        /// <param name="deciBelSpectrogram">the noisy decibel spectrogram</param>
        /// <param name="xAxisInterval">x-axis tic interval</param>
        /// <param name="stepDuration">the x-axis times scale</param>
        /// <param name="nyquist">max freq value</param>
        /// <param name="hzInterval">y-axis frequency scale</param>
        /// <returns>Image containing four sepctrograms</returns>
        public static Image ModalNoiseRemovalAndGetSonograms(
            double[,] deciBelSpectrogram,
            TimeSpan xAxisInterval,
            TimeSpan stepDuration,
            int nyquist,
            int hzInterval)
        {
            // The number of SDs above the mean for noise removal.
            // Set sdCount = -0.5 becuase when sdCount >= zero, noies removal is a bit severe for environmental recordings.
            var sdCount = -0.5;
            var nrt     = NoiseReductionType.Modal;
            var tuple   = SNR.NoiseReduce(deciBelSpectrogram, nrt, sdCount);

            var noiseReducedSpectrogram1 = tuple.Item1;

            var title  = "title1";
            var image1 = DrawSonogram(noiseReducedSpectrogram1, xAxisInterval, stepDuration, nyquist, hzInterval, title);

            double dBThreshold = 0.0; // SPECTRAL dB THRESHOLD for smoothing background

            double[,] noiseReducedSpectrogram2 = SNR.RemoveNeighbourhoodBackgroundNoise(noiseReducedSpectrogram1, dBThreshold);
            title = "title2";
            var image2 = DrawSonogram(noiseReducedSpectrogram2, xAxisInterval, stepDuration, nyquist, hzInterval, title);

            // SPECTRAL dB THRESHOLD for smoothing background
            dBThreshold = 3.0;
            noiseReducedSpectrogram2 = SNR.RemoveNeighbourhoodBackgroundNoise(noiseReducedSpectrogram1, dBThreshold);
            title = "title3";
            var image3 = DrawSonogram(noiseReducedSpectrogram2, xAxisInterval, stepDuration, nyquist, hzInterval, title);

            // SPECTRAL dB THRESHOLD for smoothing background
            dBThreshold = 10.0;
            noiseReducedSpectrogram2 = SNR.RemoveNeighbourhoodBackgroundNoise(noiseReducedSpectrogram1, dBThreshold);
            title = "title4";
            var image4 = DrawSonogram(noiseReducedSpectrogram2, xAxisInterval, stepDuration, nyquist, hzInterval, title);

            var array = new Image[4];

            array[0] = image1;
            array[1] = image2;
            array[2] = image3;
            array[3] = image4;
            var combinedImage = ImageTools.CombineImagesVertically(array);

            return(combinedImage);
        }
        public static Image CreateImageOfSpectralIndices(SpectralIndexValues spectralIndices)
        {
            var images = new List <Image>();

            foreach (var key in Keys)
            {
                var      spectrum        = CachedSelectors[key](spectralIndices);
                double[] normalisedIndex = DataTools.normalise(spectrum);

                var image = GraphsAndCharts.DrawGraph(key, normalisedIndex, 100);
                images.Add(image);
            }

            var combinedImage = ImageTools.CombineImagesVertically(images.ToArray());

            return(combinedImage);
        }
Ejemplo n.º 29
0
        public static Image DrawFalseColorSpectrograms(Arguments args, string fileStem, Dictionary <string, IndexProperties> indexProperties, Dictionary <string, double[, ]> spectra = null)
        {
            // note: the spectra are oriented as per visual orientation, i.e. xAxis = time framesDictionary<string, Int16>.KeyCollection keys = AuthorList.Keys
            // string[] keys = spectra.Keys.ToCommaSeparatedList().Split(',');
            // int frameCount = spectra[keys[0]].GetLength(1);

            int    sampleRate       = 22050;
            int    frameWidth       = 512;
            double backgroundFilter = 0.75;  // 0.75 means small values are accentuated.
            var    minuteOffset     = TimeSpan.Zero;
            var    dataScale        = args.TemporalScale;
            string colorMap         = args.ColourMap1 ?? LDSpectrogramRGB.DefaultColorMap1;
            var    cs1 = new LDSpectrogramRGB(minuteOffset, dataScale, sampleRate, frameWidth, colorMap)
            {
                FileName                 = fileStem,
                BackgroundFilter         = backgroundFilter,
                IndexCalculationDuration = dataScale,
            };

            // set the relevant dictionary of index properties
            cs1.SetSpectralIndexProperties(indexProperties);
            cs1.SpectrogramMatrices = spectra;

            // get parameter from the config file.
            var configFile           = args.FalseColourSpectrogramConfig.ToFileInfo();
            var config               = LdSpectrogramConfig.ReadYamlToConfig(configFile);
            var blueEnhanceParameter = config.BlueEnhanceParameter ?? 0.0;

            var image1       = cs1.DrawFalseColorSpectrogramChromeless("NEGATIVE", colorMap, blueEnhanceParameter);
            var fullDuration = TimeSpan.FromSeconds(image1.Width * dataScale.TotalSeconds);

            string title       = fileStem;
            var    titleImage  = LDSpectrogramRGB.DrawTitleBarOfFalseColourSpectrogram(title, image1.Width);
            int    trackHeight = 20;
            var    timeScale   = ImageTrack.DrawTimeRelativeTrack(fullDuration, image1.Width, trackHeight);

            colorMap = args.ColourMap2 ?? LDSpectrogramRGB.DefaultColorMap2;
            var image2 = cs1.DrawFalseColorSpectrogramChromeless("NEGATIVE", colorMap, blueEnhanceParameter);
            var list   = new List <Image> {
                titleImage, image1, timeScale, image2
            };
            var combinedImage = ImageTools.CombineImagesVertically(list.ToArray());

            return(combinedImage);
        }
Ejemplo n.º 30
0
        public Image <Rgb24> GetImageFullyAnnotated(Image <Rgb24> image, string title, int[,] gridLineLocations, Color?tag = null)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            FrequencyScale.DrawFrequencyLinesOnImage(image, gridLineLocations, includeLabels: true);

            var titleBar = DrawTitleBarOfGrayScaleSpectrogram(title, image.Width, tag);
            var timeBmp  = ImageTrack.DrawTimeTrack(this.Duration, image.Width);
            var list     = new List <Image <Rgb24> > {
                titleBar, timeBmp, image, timeBmp
            };
            var compositeImage = ImageTools.CombineImagesVertically(list);

            return(compositeImage);
        }