public void GetRidgeSpectraVersion1(double[,] dbSpectrogramData, double ridgeThreshold) { int rowCount = dbSpectrogramData.GetLength(0); int colCount = dbSpectrogramData.GetLength(1); int spanCount = rowCount - 4; // 4 because 5x5 grid means buffer of 2 on either side double[,] matrix = dbSpectrogramData; //double[,] matrix = ImageTools.WienerFilter(dbSpectrogramData, 3); // returns a byte matrix of ridge directions // 0 = no ridge detected or below magnitude threshold. // 1 = ridge direction = horizontal or slope = 0; // 2 = ridge is positive slope or pi/4 // 3 = ridge is vertical or pi/2 // 4 = ridge is negative slope or 3pi/4. //byte[,] hits = RidgeDetection.Sobel5X5RidgeDetectionExperiment(matrix, ridgeThreshold); byte[,] hits = RidgeDetection.Sobel5X5RidgeDetectionVersion1(matrix, ridgeThreshold); //image for debugging //ImageTools.DrawMatrix(hits, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogram.png"); double[] spectrum = new double[colCount]; byte[] freqBin; //Now aggregate hits to get ridge info //note that the Spectrograms were passed in flat-rotated orientation. //Therefore need to assign ridge number to re-oriented values. // Accumulate info for the horizontal ridges for (int col = 0; col < colCount; col++) { // i.e. for each frequency bin freqBin = MatrixTools.GetColumn(hits, col); int count = freqBin.Count(x => x == 3); if (count < 2) { continue; // i.e. not a track. } spectrum[col] = count / (double)spanCount; } this.RhzSpectrum = spectrum; // accumulate info for the vertical ridges spectrum = new double[colCount]; for (int col = 0; col < colCount; col++) { // i.e. for each frequency bin freqBin = MatrixTools.GetColumn(hits, col); int count = freqBin.Count(x => x == 1); if (count < 2) { continue; // i.e. not a track. } spectrum[col] = count / (double)spanCount; } this.RvtSpectrum = spectrum; // accumulate info for the up slope ridges spectrum = new double[colCount]; for (int col = 0; col < colCount; col++) { // i.e. for each frequency bin freqBin = MatrixTools.GetColumn(hits, col); int count = freqBin.Count(x => x == 4); spectrum[col] = count / (double)spanCount; } this.RpsSpectrum = spectrum; // accumulate info for the down slope ridges spectrum = new double[colCount]; for (int col = 0; col < colCount; col++) { // i.e. for each frequency bin freqBin = MatrixTools.GetColumn(hits, col); int count = freqBin.Count(x => x == 2); spectrum[col] = count / (double)spanCount; } this.RngSpectrum = spectrum; }
public void GetRidgeSpectraVersion2(double[,] dbSpectrogramData) { int rowCount = dbSpectrogramData.GetLength(0); int colCount = dbSpectrogramData.GetLength(1); // calculate span = number of cells over which will take average of a feature. // -4 because 5x5 grid means buffer of 2 on either side int spanCount = rowCount - 4; double[,] matrix = dbSpectrogramData; //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\BIRD50\temp\SpectrogramBeforeWeinerFilter.png"); // DO NOT USE WIENER FILTERING because smooths the ridges and lose definition //matrix = ImageTools.WienerFilter(dbSpectrogramData, 3); //ImageTools.DrawMatrix(matrix, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogramAfterWeinerFilter.png"); // returns a byte matrix of ridge directions // 0 = ridge direction = horizontal or slope = 0; // 1 = ridge is positive slope or pi/4 // 2 = ridge is vertical or pi/2 // 3 = ridge is negative slope or 3pi/4. List <double[, ]> hits = RidgeDetection.Sobel5X5RidgeDetection_Version2(matrix); //image for debugging //ImageTools.DrawMatrix(hits[0], 0, 10.0, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogram0.png"); //ImageTools.DrawMatrix(hits[1], 0, 10.0, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogram1.png"); //ImageTools.DrawMatrix(hits[2], 0, 10.0, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogram2.png"); //ImageTools.DrawMatrix(hits[3], 0, 10.0, @"C:\SensorNetworks\Output\BIRD50\temp\hitsSpectrogram3.png"); double[] spectrum = new double[colCount]; double sum; //Now aggregate hits to get ridge info //note that the Spectrograms were passed in flat-rotated orientation. //Therefore need to assign ridge number to re-oriented values. // Accumulate info for the horizontal ridges var hitsMatrix = hits[2]; // for each frequency bin for (int col = 0; col < colCount; col++) { sum = 0; for (int row = 2; row < rowCount - 2; row++) { sum += hitsMatrix[row, col]; } spectrum[col] = sum / spanCount; } this.RhzSpectrum = spectrum; // accumulate info for the vertical ridges hitsMatrix = hits[0]; spectrum = new double[colCount]; for (int col = 0; col < colCount; col++) { // i.e. for each frequency bin sum = 0; for (int row = 2; row < rowCount - 2; row++) { sum += hitsMatrix[row, col]; } spectrum[col] = sum / spanCount; } this.RvtSpectrum = spectrum; // accumulate info for the positive/up-slope ridges hitsMatrix = hits[3]; spectrum = new double[colCount]; // for each frequency bin for (int col = 0; col < colCount; col++) { sum = 0; for (int row = 2; row < rowCount - 2; row++) { sum += hitsMatrix[row, col]; } spectrum[col] = sum / spanCount; } this.RpsSpectrum = spectrum; // accumulate info for the negative/down slope ridges hitsMatrix = hits[1]; spectrum = new double[colCount]; // for each frequency bin for (int col = 0; col < colCount; col++) { sum = 0; for (int row = 2; row < rowCount - 2; row++) { sum += hitsMatrix[row, col]; } spectrum[col] = sum / spanCount; } this.RngSpectrum = spectrum; }