예제 #1
0
        } // method DrawAggregatedSpectrograms()

        public static Image DrawGrayScaleSpectrograms(Arguments arguments, string fileStem, TimeSpan dataScale, Dictionary <string, double[, ]> spectra = null)
        {
            int sampleRate = 22050;
            int frameWidth = 512;

            //double backgroundFilter = 0.0; // 0.0 means small values are removed.
            double backgroundFilter = 0.75;  // 0.75 means small values are accentuated.
            string analysisType     = AcousticIndices.TowseyAcoustic;

            string[] keys = LDSpectrogramRGB.GetArrayOfAvailableKeys();

            //LoggedConsole.WriteLine("# Spectrogram Config      file: " + arguments.SpectrogramConfigPath);
            //LoggedConsole.WriteLine("# Index Properties Config file: " + arguments.IndexPropertiesConfig);
            var inputDirectory = arguments.InputDataDirectory;
            Dictionary <string, IndexProperties> indexProperties = IndexProperties.GetIndexProperties(arguments.IndexPropertiesConfig.ToFileInfo());

            if (spectra == null)
            {
                //C:\SensorNetworks\Output\BIRD50\Training\ID0001\Towsey.Acoustic\ID0001__Towsey.Acoustic.ACI
                spectra = IndexMatrices.ReadSpectralIndices(inputDirectory.ToDirectoryInfo(), fileStem, analysisType, keys);
            }

            // note: the spectra are oriented as per visual orientation, i.e. xAxis = time frames
            //int frameCount = spectra[keys[0]].GetLength(1);
            var cs1 = new LDSpectrogramRGB(minuteOffset: TimeSpan.Zero, xScale: dataScale, sampleRate: sampleRate, frameWidth: frameWidth, colourMap: null)
            {
                FileName                 = fileStem,
                BackgroundFilter         = backgroundFilter,
                IndexCalculationDuration = dataScale,
            };

            cs1.SetSpectralIndexProperties(indexProperties); // set the relevant dictionary of index properties
            cs1.SpectrogramMatrices = spectra;
            if (cs1.GetCountOfSpectrogramMatrices() == 0)
            {
                LoggedConsole.WriteLine("WARNING:  " + fileStem + ":   No spectrogram matrices in the dictionary. Spectrogram files do not exist?");
                return(null);
            }

            List <Image> list       = new List <Image>();
            Font         stringFont = new Font("Arial", 14);

            foreach (string key in keys)
            {
                var image = cs1.DrawGreyscaleSpectrogramOfIndex(key);

                int width  = 70;
                int height = image.Height;
                var label  = new Bitmap(width, height);
                var g1     = Graphics.FromImage(label);
                g1.Clear(Color.Gray);
                g1.DrawString(key, stringFont, Brushes.Black, new PointF(4, 30));
                g1.DrawLine(new Pen(Color.Black), 0, 0, width, 0); //draw upper boundary
                g1.DrawLine(new Pen(Color.Black), 0, 1, width, 1); //draw upper boundary

                Image[] imagearray    = { label, image };
                var     labelledImage = ImageTools.CombineImagesInLine(imagearray);
                list.Add(labelledImage);
            } //foreach key

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

            return(combinedImage);
        } // method DrawGrayScaleSpectrograms()
예제 #2
0
        } // method DrawAggregatedSpectrograms()

        public static Image <Rgb24> DrawGrayScaleSpectrograms(Arguments arguments, string fileStem, TimeSpan dataScale, Dictionary <string, double[, ]> spectra = null)
        {
            // default values
            int sampleRate = 22050;
            int frameWidth = 512;

            //double backgroundFilter = 0.0; // 0.0 means small values are removed.
            double backgroundFilter = 0.75;  // 0.75 means small values are accentuated.
            string analysisType     = AcousticIndices.TowseyAcoustic;

            string[] keys           = LDSpectrogramRGB.GetArrayOfAvailableKeys();
            var      inputDirectory = arguments.InputDataDirectory;
            Dictionary <string, IndexProperties> indexProperties = IndexProperties.GetIndexProperties(arguments.IndexPropertiesConfig.ToFileInfo());

            if (spectra == null)
            {
                spectra = IndexMatrices.ReadSpectralIndices(inputDirectory.ToDirectoryInfo(), fileStem, analysisType, keys);
            }

            // note: the spectra are oriented as per visual orientation, i.e. xAxis = time frames
            //int frameCount = spectra[keys[0]].GetLength(1);
            var cs1 = new LDSpectrogramRGB(minuteOffset: TimeSpan.Zero, xScale: dataScale, sampleRate: sampleRate, frameWidth: frameWidth, colorMap: null)
            {
                FileName                 = fileStem,
                BackgroundFilter         = backgroundFilter,
                IndexCalculationDuration = dataScale,
            };

            cs1.SetSpectralIndexProperties(indexProperties); // set the relevant dictionary of index properties
            cs1.SpectrogramMatrices = spectra;
            if (cs1.GetCountOfSpectrogramMatrices() == 0)
            {
                LoggedConsole.WriteLine("WARNING:  " + fileStem + ":   No spectrogram matrices in the dictionary. Spectrogram files do not exist?");
                return(null);
            }

            var list       = new List <Image <Rgb24> >();
            var stringFont = Drawing.Arial14;

            foreach (string key in keys)
            {
                var image = cs1.DrawGreyscaleSpectrogramOfIndex(key);

                int width  = 70;
                int height = image.Height;
                var label  = new Image <Rgb24>(width, height);
                label.Mutate(g1 =>
                {
                    g1.Clear(Color.Gray);
                    g1.DrawText(key, stringFont, Color.Black, new PointF(4, 30));
                    g1.DrawLine(new Pen(Color.Black, 1), 0, 0, width, 0); //draw upper boundary
                    g1.DrawLine(new Pen(Color.Black, 1), 0, 1, width, 1); //draw upper boundary
                });
                var imagearray    = new[] { label, image };
                var labelledImage = ImageTools.CombineImagesInLine(imagearray);
                list.Add(labelledImage);
            } //foreach key

            var combinedImage = ImageTools.CombineImagesVertically(list);

            return(combinedImage);
        } // method DrawGrayScaleSpectrograms()
예제 #3
0
        public void TestAnalyzeSr64000Recording()
        {
            int    sampleRate = 64000;
            double duration   = 420; // signal duration in seconds = 7 minutes

            int[]  harmonics     = { 500, 1000, 2000, 4000, 8000 };
            var    recording     = DspFilters.GenerateTestRecording(sampleRate, duration, harmonics, WaveType.Cosine);
            string recordingName = "TemporaryRecording2";
            var    recordingPath = this.outputDirectory.CombineFile(recordingName + ".wav");

            WavWriter.WriteWavFileViaFfmpeg(recordingPath, recording.WavReader);

            var fst       = FreqScaleType.Linear125Octaves7Tones28Nyquist32000;
            var freqScale = new FrequencyScale(fst);

            /*
             * // draw the signal as spectrogram just for debugging purposes
             * // but can only draw a two minute spectrogram when sr=64000 - change duration above.
             * duration = 120; // if drawing sonogram, then set signal duration = 2 minutes
             * var sonogram = OctaveFreqScale.ConvertRecordingToOctaveScaleSonogram(recording, fst);
             * var sonogramImage = sonogram.GetImageFullyAnnotated(sonogram.GetImage(), "SPECTROGRAM", freqScale.GridLineLocations);
             * var outputImagePath = this.outputDirectory.CombineFile("SignalSpectrogram_OctaveFreqScale.png");
             * sonogramImage.Save(outputImagePath.FullName);
             */

            // Now need to rewrite the config file with new parameter settings
            var configPath = PathHelper.ResolveConfigFile("Towsey.Acoustic.yml");

            // Convert the Config config to IndexCalculateConfig class and merge in the unnecesary parameters.
            //Config configuration = Yaml.Deserialise(configPath);
            //IndexCalculateConfig config = IndexCalculateConfig.GetConfig(configuration, false);

            // because of difficulties in dealing with Config config files, just edit the text file!!!!!
            var configLines = File.ReadAllLines(configPath.FullName);

            configLines[configLines.IndexOf(x => x.StartsWith("IndexCalculationDuration: "))] = "IndexCalculationDuration: 15.0";

            //configLines[configLines.IndexOf(x => x.StartsWith("BgNoiseBuffer: "))] = "BgNoiseBuffer: 5.0";
            configLines[configLines.IndexOf(x => x.StartsWith("FrequencyScale: Linear"))] = "FrequencyScale: " + fst;

            // the is the only octave scale currently functioning for IndexCalculate class
            configLines[configLines.IndexOf(x => x.StartsWith("FrameLength"))]    = $"FrameLength: {freqScale.WindowSize}";
            configLines[configLines.IndexOf(x => x.StartsWith("ResampleRate: "))] = "ResampleRate: 64000";

            // write the edited Config file to temporary output directory
            var newConfigPath = this.outputDirectory.CombineFile("Towsey.Acoustic.yml");

            File.WriteAllLines(newConfigPath.FullName, configLines);

            PathHelper.ResolveConfigFile("IndexPropertiesConfig.yml").CopyTo(this.outputDirectory.CombineFile("IndexPropertiesConfig.yml").FullName);

            var arguments = new AnalyseLongRecording.Arguments
            {
                Source        = recordingPath,
                Config        = newConfigPath.FullName,
                Output        = this.outputDirectory,
                MixDownToMono = true,
                Parallel      = !Debugger.IsAttached,
            };

            AnalyseLongRecording.Execute(arguments);

            var resultsDirectory = this.outputDirectory.Combine("Towsey.Acoustic");
            var listOfFiles      = resultsDirectory.EnumerateFiles().ToArray();

            Assert.AreEqual(19, listOfFiles.Length);

            var csvCount = listOfFiles.Count(f => f.Name.EndsWith(".csv"));

            Assert.AreEqual(15, csvCount);

            var jsonCount = listOfFiles.Count(f => f.Name.EndsWith(".json"));

            Assert.AreEqual(2, jsonCount);

            var pngCount = listOfFiles.Count(f => f.Name.EndsWith(".png"));

            Assert.AreEqual(2, pngCount);

            var bgnFile = resultsDirectory.CombineFile(recordingName + "__Towsey.Acoustic.BGN.csv");

            double[,] actualBgn = Csv.ReadMatrixFromCsv <double>(bgnFile, TwoDimensionalArray.None);

            var expectedSpectrumFile = PathHelper.ResolveAsset("LongDuration", "BgnMatrix.OctaveScale.csv");

            // uncomment the following line when first produce the array
            // bgnFile.CopyTo(expectedSpectrumFile.FullName);

            // compare actual BGN file with expected file.
            var expectedBgn = Csv.ReadMatrixFromCsv <double>(expectedSpectrumFile, TwoDimensionalArray.None);

            CollectionAssert.That.AreEqual(expectedBgn, actualBgn, 0.000_000_001);

            var array = MatrixTools.GetRow(actualBgn, 0);

            Assert.AreEqual(28, actualBgn.RowLength());
            Assert.AreEqual(256, array.Length);

            // draw array just to check peaks are in correct places - just for debugging purposes
            var ldsBgnSpectrumFile = this.outputDirectory.CombineFile("Spectrum2.png");

            GraphsAndCharts.DrawGraph(array, "LD BGN SPECTRUM Octave", ldsBgnSpectrumFile);

            // ##########################################
            // SECOND part of test is to create the LD spectrograms because they are not created when IndexCalcDuration < 60 seconds
            // first read in the index generation data
            var icdPath         = resultsDirectory.CombineFile(recordingName + "__IndexGenerationData.json");
            var indexConfigData = Json.Deserialize <IndexGenerationData>(icdPath);

            var indexPropertiesConfig = PathHelper.ResolveConfigFile("IndexPropertiesConfig.yml");

            var ldSpectrogramConfigFile = PathHelper.ResolveConfigFile("SpectrogramFalseColourConfig.yml");
            var ldSpectrogramConfig     = LdSpectrogramConfig.ReadYamlToConfig(ldSpectrogramConfigFile);

            ldSpectrogramConfig.FreqScale = fst.ToString();

            // finally read in the dictionary of spectra
            string analysisType        = "Towsey.Acoustic";
            var    keys                = LDSpectrogramRGB.GetArrayOfAvailableKeys();
            var    dictionaryOfSpectra = IndexMatrices.ReadSpectralIndices(resultsDirectory, recordingName, analysisType, keys);

            LDSpectrogramRGB.DrawSpectrogramsFromSpectralIndices(
                inputDirectory: resultsDirectory,
                outputDirectory: resultsDirectory,
                ldSpectrogramConfig: ldSpectrogramConfig,
                indexPropertiesConfigPath: indexPropertiesConfig,
                indexGenerationData: indexConfigData,
                basename: recordingName,
                analysisType: analysisType,
                indexSpectrograms: dictionaryOfSpectra);

            // test number of images - should now be 23
            listOfFiles = resultsDirectory.EnumerateFiles().ToArray();
            pngCount    = listOfFiles.Count(f => f.Name.EndsWith(".png"));
            Assert.AreEqual(22, pngCount);

            var twoMapsImagePath = resultsDirectory.CombineFile(recordingName + "__2Maps.png");
            var twoMapsImage     = Image.Load <Rgb24>(twoMapsImagePath.FullName);

            // image is (7*4) * 652
            Assert.AreEqual(28, twoMapsImage.Width);
            Assert.AreEqual(652, twoMapsImage.Height);
        }