Skip to content

Commit

Permalink
Write methods to read in acoustic index spectrograms.
Browse files Browse the repository at this point in the history
Issue #252 Start work on reading index matrices and checking that they are correctly read by producing a grey-scale spectrogram.
  • Loading branch information
towsey committed Sep 4, 2019
1 parent 857b9f7 commit d1d9f9f
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/AnalysisPrograms/Sandpit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace AnalysisPrograms
using Acoustics.Tools.Wav;
using AnalyseLongRecordings;
using AudioAnalysisTools;
using AudioAnalysisTools.ContentDescriptionTools;
using AudioAnalysisTools.DSP;
using AudioAnalysisTools.Indices;
using AudioAnalysisTools.LongDurationSpectrograms;
Expand Down Expand Up @@ -61,6 +62,10 @@ public override Task<int> Execute(CommandLineApplication app)
Log.Verbosity = 1;
Log.WriteLine("# Start Time = " + tStart.ToString(CultureInfo.InvariantCulture));

// CONTENT DESCRIPTION
//ReadSpectralIndicesFromTwoFalseColourSpectrogramRibbons();
ContentDescriptionDev();

//AnalyseFrogDataSet();
//Audio2CsvOverOneFile();
//Audio2CsvOverMultipleFiles();
Expand Down Expand Up @@ -105,7 +110,6 @@ public override Task<int> Execute(CommandLineApplication app)
//TestTernaryPlots();
//TestDirectorySearchAndFileSearch();
//TestNoiseReduction();
ReadSpectralIndicesFromTwoFalseColourSpectrogramRibbons();
//Oscillations2014.TESTMETHOD_DrawOscillationSpectrogram();
//Oscillations2014.TESTMETHOD_GetSpectralIndex_Osc();

Expand All @@ -114,6 +118,17 @@ public override Task<int> Execute(CommandLineApplication app)
}
}

public static void ContentDescriptionDev()
{
var dir = new DirectoryInfo(@"C:\Ecoacoustics\Output\Test\Test24HourRecording\TasmanIslandMez\Mez02\Towsey.Acoustic");
string baseName = "SM304256_0+1_20151114_011652";
var dictionary = ContentDescription.ReadIndexMatrices(dir, baseName);

// Draw the index matrices for check/debug purposes
var dir1 = new DirectoryInfo(@"C:\Ecoacoustics\Output\ContentDescription");
ContentDescription.DrawNormalisedIndexMatrices(dir1, baseName, dictionary);
}

public static void DrawClusterSequence()
{
for (int i = 1; i <= 60; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ namespace AudioAnalysisTools.ContentDescriptionTools
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using Acoustics.Shared;
using Acoustics.Shared.Csv;
using AudioAnalysisTools.DSP;
using AudioAnalysisTools.LongDurationSpectrograms;
using AudioAnalysisTools.StandardSpectrograms;
using TowseyLibrary;

public class ContentDescription
Expand All @@ -27,6 +33,34 @@ public class ContentDescription

public static string[] IndexNames { get; } = { "ACI", "ENT", "EVN", "BGN", "PMN" };

/// <summary>
/// Reads in all the index matrices whose keys are in the above array of IndexNames.
/// </summary>
/// <param name="dir">directory containing the index matrices.</param>
/// <param name="baseName">base name of the files.</param>
/// <returns>a Dictionary of matrices containing normalised index values.</returns>
public static Dictionary<string, double[,]> ReadIndexMatrices(DirectoryInfo dir, string baseName)
{
var dictionary = new Dictionary<string, double[,]>();

foreach (string key in IndexNames)
{
var indexBounds = IndexValueBounds[key];

// construct a path to the required matrix
var path = Path.Combine(dir.FullName, baseName + "__Towsey.Acoustic." + key + ".csv");

// read in the matrix
var indexMatrix = Csv.ReadMatrixFromCsv<double>(new FileInfo(path));

// normalise the matrix values
var normalisedMatrix = DataTools.NormaliseInZeroOne(indexMatrix, indexBounds[0], indexBounds[1]);
dictionary.Add(key, normalisedMatrix);
}

return dictionary;
}

/// <summary>
/// This method assumes that the start and end minute for reading from index matrices is first and last row respectively of matrices - assuming one minute per row.
/// </summary>
Expand Down Expand Up @@ -97,5 +131,46 @@ public class ContentDescription

return opMatrix;
}

public static void DrawNormalisedIndexMatrices(DirectoryInfo dir, string baseName, Dictionary<string, double[,]> dictionary)
{
var list = new List<Image>();
foreach (string key in IndexNames)
{
var bmp = ImageTools.DrawReversedMatrixWithoutNormalisation(dictionary[key]);

// need to rotate spectrogram to get correct orientation.
bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);

// draw grid lines and add axis scales
var xAxisPixelDuration = TimeSpan.FromSeconds(60);
var fullDuration = TimeSpan.FromTicks(xAxisPixelDuration.Ticks * bmp.Width);
var freqScale = new FrequencyScale(11025, 512, 1000);
SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp, TimeSpan.Zero, fullDuration, xAxisPixelDuration, freqScale);
const int trackHeight = 20;
var recordingStartDate = default(DateTimeOffset);
var timeBmp = ImageTrack.DrawTimeTrack(fullDuration, recordingStartDate, bmp.Width, trackHeight);
var array = new Image[2];
array[0] = bmp;
array[1] = timeBmp;
var image = ImageTools.CombineImagesVertically(array);

// add a header to the spectrogram
var header = new Bitmap(image.Width, 20);
Graphics g = Graphics.FromImage(header);
g.Clear(Color.LightGray);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawString(key, new Font("Tahoma", 9), Brushes.Black, 4, 4);
list.Add(ImageTools.CombineImagesVertically(new List<Image>(new[] { header, image })));
}

// save the image - the directory for the path must exist
var path = Path.Combine(dir.FullName, baseName + "__Towsey.Acoustic.GreyScaleImages.png");
var indexImage = ImageTools.CombineImagesInLine(list);
indexImage?.Save(path);

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,28 @@ public static Image DrawTitleBarOfGrayScaleSpectrogram(string title, int width)
return bmp;
}

/// <summary>
/// Assume calling method has done all the reality checks.
/// Assume the Index Calculation Duration = 60 seconds
/// </summary>
public static Image DrawGreyscaleSpectrogramOfIndex(string key, double[,] matrix)
{
var bmp = ImageTools.DrawReversedMatrixWithoutNormalisation(matrix);
var xAxisPixelDuration = TimeSpan.FromSeconds(60);
var fullDuration = TimeSpan.FromTicks(xAxisPixelDuration.Ticks * bmp.Width);
var freqScale = new FrequencyScale(11025, 512, 1000);

SpectrogramTools.DrawGridLinesOnImage((Bitmap)bmp, TimeSpan.Zero, fullDuration, xAxisPixelDuration, freqScale);
const int trackHeight = 20;
var recordingStartDate = default(DateTimeOffset);
var timeBmp = ImageTrack.DrawTimeTrack(fullDuration, recordingStartDate, bmp.Width, trackHeight);
var array = new Image[2];
array[0] = bmp;
array[1] = timeBmp;
var returnImage = ImageTools.CombineImagesVertically(array);
return returnImage;
}

public static Image DrawTitleBarOfFalseColourSpectrogram(string title, int width)
{
var bmp = new Bitmap(width, SpectrogramConstants.HEIGHT_OF_TITLE_BAR);
Expand Down

0 comments on commit d1d9f9f

Please sign in to comment.