} //Execute_Spr_Match() public static Tuple <double> Execute_One_Spr_Match(char[,] template, double[,] dataMatrix, double dBThreshold) { int lineLength = 10; int templateFrames = template.GetLength(0); // time axis - SPR template is same orientation as the sonogram data matrix int templateFreqBins = template.GetLength(1); // freq axis int cellCount = templateFrames * templateFreqBins; int positiveCount = SprTools.CountTemplateChars(template); int negativeCount = cellCount - positiveCount; Log.WriteLine("TEMPLATE: Number of POS cells/total = {0}/{1}", positiveCount, cellCount); char[,] charogram = SprTools.Target2SymbolicTracks(dataMatrix, dBThreshold, lineLength); FileTools.WriteMatrix2File(charogram, "C:\\SensorNetworks\\Output\\FELT_LewinsRail1\\charogram.txt"); //view the char-ogram double onSum = 0.0; double offSum = 0.0; // calculate onSum and offSum // freq axis for (int j = 0; j < templateFreqBins; j++) { for (int i = 0; i < templateFrames; i++) { if (charogram[i, j] == '-') { continue; } else if (template[i, j] == '-') { offSum += dataMatrix[i, j]; } else { //char ColumnLeft = charogram[i, j]; //char ColumnRight = template[i, j]; //int difference = (int)ColumnLeft - (int)ColumnRight; int diff = SprTools.SymbolDifference(charogram[i, j], template[i, j]); //LoggedConsole.WriteLine("{0},{1} diff={2}", i,j, diff); onSum += (90 - diff) / (double)90 * dataMatrix[i, j]; } } } // calculate similarity //following line yields score = av of PosCells - av of NegCells. double similarity = (onSum / positiveCount) - (offSum / negativeCount); var tuple = Tuple.Create(similarity); return(tuple); } //Execute_One_Spr_Match()
/// <summary> /// Use this method to find match in sonogram to a symbolic definition of a bird call. /// That is, the template should be matrix of binary or trinary values. /// </summary> public static Tuple <double[]> Execute_Spr_Match(char[,] template, SpectrogramStandard sonogram, List <AcousticEvent> segments, int minHz, int maxHz, double dBThreshold) { int lineLength = 10; //dBThreshold = 9; Log.WriteLine("SEARCHING FOR EVENTS LIKE TARGET (SPR)."); if (segments == null) { return(null); } int minBin = (int)(minHz / sonogram.FBinWidth); int maxBin = (int)(maxHz / sonogram.FBinWidth); int templateFrames = template.GetLength(0); // time axis - SPR template is same orientation as the sonogram data matrix int templateFreqBins = template.GetLength(1); // freq axis int cellCount = templateFrames * templateFreqBins; int positiveCount = SprTools.CountTemplateChars(template); int negativeCount = cellCount - positiveCount; Log.WriteLine("TEMPLATE: Number of POS cells/total cells = {0}/{1}", positiveCount, cellCount); // Log.WriteLine("TEMPLATE: Number of NEG cells/total cells = {0}/{1}", negativeCount, cellCount); char[,] charogram = SprTools.Target2SymbolicTracks(sonogram.Data, dBThreshold, lineLength); //var m = DataTools.MatrixTranspose(charogram); FileTools.WriteMatrix2File(charogram, "C:\\SensorNetworks\\Output\\FELT_MultiOutput_5templates\\char_ogram.txt"); //view the char-ogram double[] scores = new double[sonogram.FrameCount]; foreach (AcousticEvent av in segments) { Log.WriteLine("SEARCHING SEGMENT."); int startRow = (int)Math.Floor(av.TimeStart * sonogram.FramesPerSecond); int endRow = (int)Math.Floor(av.TimeEnd * sonogram.FramesPerSecond); if (endRow >= sonogram.FrameCount) { endRow = sonogram.FrameCount; } int stopRow = endRow - templateFrames - 1; if (stopRow <= startRow) { stopRow = startRow + 1; //want minimum of one row } for (int r = startRow; r < stopRow; r++) { double maxSimilarity = -double.MaxValue; int binBuffer = 10; // calculate similarity at one frame position for (int bin = -binBuffer; bin < +binBuffer; bin++) { int c = minBin + bin; if (c < 0) { c = 0; } double onSum = 0.0; double offSum = 0.0; // calculate onSum and offSum // freq axis for (int j = 0; j < templateFreqBins; j++) { for (int i = 0; i < templateFrames; i++) { if (charogram[r + i, c + j] == '-') { continue; } else if (template[i, j] == '-') { offSum += sonogram.Data[r + i, c + j]; } else { //char ColumnLeft = charogram[r + i, c + j]; //char ColumnRight = template[i, j]; //int difference = (int)ColumnLeft - (int)ColumnRight; int diff = SprTools.SymbolDifference(charogram[r + i, c + j], template[i, j]); onSum += (90 - diff) / (double)90 * sonogram.Data[r + i, c + j]; } } } // calculate similarity double similarity = (onSum / positiveCount) - (offSum / negativeCount); if (similarity > maxSimilarity) { maxSimilarity = similarity; } } // end freq bins //following line yields score = av of PosCells - av of NegCells. scores[r] = maxSimilarity; //if (r % 100 == 0) { LoggedConsole.WriteLine("{0} - {1:f3}", r, scores[r]); } //if (scores[r] >= dBThreshold) { LoggedConsole.WriteLine("r={0} score={1}.", r, scores[r]); } if (r % 100 == 0) { LoggedConsole.Write("."); } if (scores[r] < dBThreshold) { r += 3; //skip where score is low } } // end of rows in segment LoggedConsole.WriteLine("\nFINISHED SEARCHING SEGMENT FOR ACOUSTIC EVENT."); } // foreach (AcousticEvent av in segments) var tuple = Tuple.Create(scores); return(tuple); } //Execute_Spr_Match()