Skip to content

Commit

Permalink
Fix faulty logic when drawing LDFC colour matrices
Browse files Browse the repository at this point in the history
Fix faulty logic when drawing LDFC colour matrices. However note that errors are shown in gray because this is a most unlikely colour in LDFC spectrograms.

Closes #154
  • Loading branch information
towsey authored and atruskie committed Jan 31, 2019
1 parent e000fde commit 0d0b482
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 21 deletions.
44 changes: 23 additions & 21 deletions src/AudioAnalysisTools/LongDurationSpectrograms/LDSpectrogramRGB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ public Dictionary<string, IndexProperties> GetSpectralIndexProperties()

/// <summary>
/// This method sets default indices to use if passed Dictionary = null.
/// This may not be a good idea. Trying it out. Maybe better to crash!
/// This may not be a good idea. Trying it out. Maybe better to crash!.
/// </summary>
public void SetSpectralIndexProperties(Dictionary<string, IndexProperties> dictionaryOfSpectralIndexProperties)
{
Expand Down Expand Up @@ -552,7 +552,7 @@ public void DrawGreyScaleSpectrograms(DirectoryInfo opdir, string opFileName, st
/// </summary>
public Image DrawGreyscaleSpectrogramOfIndex(string key)
{
double[,] matrix = this.GetNormalisedSpectrogramMatrix(key);
var matrix = this.GetNormalisedSpectrogramMatrix(key);
if (matrix == null)
{
return null;
Expand Down Expand Up @@ -1081,7 +1081,8 @@ public static Image FrameLDSpectrogram(Image bmp1, Image titleBar, LDSpectrogram
{
// draw extra time scale with absolute start time. AND THEN Do SOMETHING WITH IT.
timeBmp2 = ImageTrack.DrawTimeTrack(fullDuration, cs.RecordingStartDate, bmp1.Width, trackHeight);
suntrack = SunAndMoon.AddSunTrackToImage(bmp1.Width, dateTimeOffset, cs.SunriseDataFile);

//suntrack = SunAndMoon.AddSunTrackToImage(bmp1.Width, dateTimeOffset, cs.SunriseDataFile);
}

if (cs.FreqScale == null)
Expand All @@ -1096,10 +1097,10 @@ public static Image FrameLDSpectrogram(Image bmp1, Image titleBar, LDSpectrogram

// draw the composite bitmap
var imageList = new List<Image> { titleBar, timeBmp1, bmp1, timeBmp2 };
if (suntrack != null)
{
imageList.Add(suntrack);
}
//if (suntrack != null)
//{
// imageList.Add(suntrack);
//}

var compositeBmp = (Bitmap)ImageTools.CombineImagesVertically(imageList);
return compositeBmp;
Expand Down Expand Up @@ -1166,9 +1167,15 @@ public static Image DrawTitleBarOfFalseColourSpectrogram(string title, int width
return bmp;
}

/// <summary>
/// This method assumes that all the passed matrices are normalised and of the same dimensions.
/// The method implements a hack to enhance the blue colour because the human eye is less sensitive to blue.
/// If there is a problem with one or more of the three rgb values, a gray pixel is substituted not a black pixel.
/// Black is a frequent colour in LDFC spectrograms, but gray is highly unlikely,
/// and therefore its presence stands out as indicating an error in one or more of the rgb values.
/// </summary>
public static Image DrawRgbColourMatrix(double[,] redM, double[,] grnM, double[,] bluM, bool doReverseColour)
{
// assume all matricies are normalised and of the same dimensions
int rows = redM.GetLength(0); //number of rows
int cols = redM.GetLength(1); //number

Expand All @@ -1184,28 +1191,23 @@ public static Image DrawRgbColourMatrix(double[,] redM, double[,] grnM, double[,
var d2 = grnM[row, column];
var d3 = bluM[row, column];

// blank indices painted grey.
if (double.IsNaN(d1))
// if any of the indices is blank/NaN then render as grey.
if (double.IsNaN(d1) || double.IsNaN(d2) || double.IsNaN(d3))
{
d1 = 0.5;
}

if (double.IsNaN(d2))
{
d2 = 0.5;
}

if (double.IsNaN(d3))
{
d3 = 0.5;
}

// enhance blue colour - it is difficult to see on a black background
// This is a hack - there should be a principled way to do this.
if (d1 < 0.1 && d2 < 0.1 && d3 > 0.2)
// This is a hack - there should be a principled way to do this!
// The effect is to create a more visible cyan colour.
if (d1 < 0.1 && d2 < 0.1 && d3 > 0.1)
{
d2 += 0.7 * d3;
d3 += 0.2;

// check for values over 1.0
d2 = Math.Min(1.0, d2);
d3 = Math.Min(1.0, d3);
}
Expand Down Expand Up @@ -1407,7 +1409,7 @@ public static Tuple<Image, string>[] DrawSpectrogramsFromSpectralIndices(
cs1.SiteName = siteDescription?.SiteName;
cs1.Latitude = siteDescription?.Latitude;
cs1.Longitude = siteDescription?.Longitude;
cs1.SunriseDataFile = sunriseDataFile;
//cs1.SunriseDataFile = sunriseDataFile;
cs1.ErroneousSegments = segmentErrors;

// calculate start time by combining DatetimeOffset with minute offset.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,41 @@ public void TestChromelessImage()
Assert.That.ImageRegionIsColor(Rectangle.FromLTRB(0, 0, 60, 256), Color.Black, (Bitmap)image);
}
}

[TestMethod]
public void TestDrawRgbColourMatrix()
{
// init three matrices
double[,] redM = new double[5, 5];
double[,] grnM = new double[5, 5];
double[,] bluM = new double[5, 5];

//convert some values to null or NaN
redM[1, 1] = double.NaN;
grnM[1, 1] = double.NaN;
bluM[1, 1] = double.NaN;

redM[2, 2] = 1.0;
grnM[2, 2] = 1.0;
bluM[2, 2] = double.NaN;

redM[3, 3] = 0.01;
grnM[3, 3] = 0.01;
bluM[3, 3] = 0.11;

var image = (Bitmap)LDSpectrogramRGB.DrawRgbColourMatrix(redM, grnM, bluM, true);

Assert.That.PixelIsColor(new Point(1, 1), Color.DarkGray, image);
Assert.That.PixelIsColor(new Point(2, 2), Color.DarkGray, image);

// To intensify the blue, this method adds 0.7 * d3 to the green value;
// and it adds 0.2 to the blue value;
// The effect is to create a more visible cyan colour.
int r = (int)(redM[3, 3] * 255);
int g = (int)((grnM[3, 3] * 255) + (0.7 * bluM[3, 3]));
int b = (int)((bluM[3, 3] + 0.2) * 255);
var cyanColour = Color.FromArgb(r, g, b);
Assert.That.PixelIsColor(new Point(3, 3), cyanColour, image);
}
}
}

0 comments on commit 0d0b482

Please sign in to comment.