DelphinID training script

This commit is contained in:
Jamie Mac 2024-05-17 16:34:45 +01:00
parent f9b13da1d1
commit 7df04d58a2
6 changed files with 128 additions and 36 deletions

View File

@ -65,7 +65,9 @@ public class DelphinIDTest {
String whistleContourPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_contours.mat"; String whistleContourPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_contours.mat";
//the path to the model //the path to the model
String modelPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_2/whistle_4s_415.zip"; // String modelPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_2/whistle_4s_415.zip";
String modelPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_3/whistle_4s_415_f5.zip";
//the path to the model //the path to the model
String matImageSave = "C:/Users/Jamie Macaulay/MATLAB Drive/MATLAB/PAMGUARD/deep_learning/delphinID/whistleimages.mat"; String matImageSave = "C:/Users/Jamie Macaulay/MATLAB Drive/MATLAB/PAMGUARD/deep_learning/delphinID/whistleimages.mat";

View File

@ -224,28 +224,34 @@ public class DelphinIDUtils {
//segment the whistle detections //segment the whistle detections
ArrayList<SegmenterDetectionGroup> segments = DelphinIDUtils.segmentWhsitleData(whistles, whistles.get(0).getTimeMilliseconds(), segLen, segHop); ArrayList<SegmenterDetectionGroup> segments = DelphinIDUtils.segmentWhsitleData(whistles, whistles.get(0).getTimeMilliseconds(), segLen, segHop);
float[][][] images = worker.dataUnits2ModelInput(segments, (float) sampleRate, 0); float[][][] images = worker.dataUnits2ModelInput(segments, (float) sampleRate, 0);
float[][] image; float[][] image;
BufferedImage bfImage; BufferedImage bfImage;
double density;
for (int k=0; k<images.length; k++) { for (int k=0; k<images.length; k++) {
if (segments.get(k).getSubDetectionsCount()<1) {
continue;
}
image = images[k]; image = images[k];
bfImage = new BufferedImage(image.length, image[0].length, BufferedImage.TYPE_INT_RGB); bfImage = new BufferedImage(image[0].length, image.length, BufferedImage.TYPE_INT_RGB);
// System.out.println("Max of image: " + PamArrayUtils.minmax(image)[1]); // System.out.println("Max of image: " + PamArrayUtils.minmax(image)[1]);
for(int i = 0; i < image.length; i++) { for(int i = 0; i < image.length; i++) {
for(int j = 0; j < image[0].length; j++) { for(int j = 0; j < image[0].length; j++) {
Color myRGB = new Color(image[i][j], image[i][j], image[i][j]); Color myRGB = new Color(image[i][j], image[i][j], image[i][j]);
int rgb = myRGB.getRGB(); int rgb = myRGB.getRGB();
bfImage.setRGB(i, j, rgb); bfImage.setRGB(j,i, rgb);
} }
} }
density = getDensity(segments.get(k));
//now save the image //now save the image
String outputPath = outName + "_" + k + ".png"; String outputPath = String.format("%s_d%.2f_%d.png", outName, density, k);
File outputfile = new File(outputPath); File outputfile = new File(outputPath);
@ -255,30 +261,51 @@ public class DelphinIDUtils {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
}
/**
* Calculate the density of whistles for a segmenter group in the absence of a known fft length and hop.
* @param group - the group
* @return
*/
private static double getDensity(SegmenterDetectionGroup group) {
//number of whistle bins/number of time bins
ArrayList<double[][]> contour = Whistles2Image.whistContours2Points(group);
//time bin length from the first contour
double[] times = new double[contour.get(0).length-1];
for (int i=0; i<times.length; i++) {
times[i]=1000.*(contour.get(0)[i+1][0] - contour.get(0)[i][0]);
}
double timebinMillis = PamArrayUtils.mean(times);
double nBins = group.getSegmentDuration()/timebinMillis;
double nwhistleBins = 0;
for (int i=0; i<contour.size(); i++) {
nwhistleBins+=contour.get(i).length;
}
// System.out.println("nwhistleBins: " +nwhistleBins + "nBins: " + nBins + " timebinMillis: " + timebinMillis);
return nwhistleBins/nBins;
} }
public static void main(String[] args) { /**
* Generate training images for DelphinID
//the whsitle contours as csv files. * @param modelPath
String whistlefolder = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD"; * @param whistlefolder
* @param imageFolder
//the image folder to save to. * @param lineWidth - the line width in pixels to use
String imageFolder = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD_Images"; */
private static void generateTrainingData(String modelPath, String whistlefolder, String imageFolder, double lineWidth) {
//the path to the model DelphinIDWorkerTest model = DelphinIDUtils.prepDelphinIDModel(modelPath);
String modelPath = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_2/whistle_4s_415.zip";
//prepare the model - this loads the zip file and loads the correct transforms.
DelphinIDWorkerTest model;
model = DelphinIDUtils.prepDelphinIDModel(modelPath);
model.setEnableSoftMax(false); model.setEnableSoftMax(false);
model.getWhistleImageParams().lineWidth=lineWidth;
FileList filelist = new FileList(); FileList filelist = new FileList();
File folder = new File(whistlefolder); File folder = new File(whistlefolder);
@ -291,12 +318,17 @@ public class DelphinIDUtils {
System.out.println("Directory " + listOfFiles[i].getName()); System.out.println("Directory " + listOfFiles[i].getName());
File outFolder = new File(imageFolder + File.separator + listOfFiles[i].getName());
outFolder.mkdir();//make the out folder directory
try { try {
File file = new File(listOfFiles[i].getPath() + File.separator + "whistles.mat"); File file = new File(listOfFiles[i].getPath() + File.separator + "whistles.mat");
if (!file.exists()) {
System.out.println("No whistles.mat for " + listOfFiles[i].getName());
continue;
}
Mat5File matFile = Mat5.readFromFile(file); Mat5File matFile = Mat5.readFromFile(file);
Struct whistlesStruct = matFile.getStruct("whistles"); Struct whistlesStruct = matFile.getStruct("whistles");
@ -307,11 +339,15 @@ public class DelphinIDUtils {
List<String> fieldNames = whistlesStruct.getFieldNames(); List<String> fieldNames = whistlesStruct.getFieldNames();
File outFolder = new File(imageFolder + File.separator + listOfFiles[i].getName());
outFolder.mkdir();//make the out folder directory
Struct whistecontours; Struct whistecontours;
for (String name: fieldNames) { for (String name: fieldNames) {
System.out.println("Generating images for recording " + name + " from " + listOfFiles[i].getName()); System.out.println("Generating images for recording " + name + " from " + listOfFiles[i].getName() + " " + lineWidth);
if (!name.equals("fftlen") && !name.equals("ffthop") && !name.equals("samplerate")) { if (!name.equals("fftlen") && !name.equals("ffthop") && !name.equals("samplerate")) {
whistecontours = whistlesStruct.get(name); whistecontours = whistlesStruct.get(name);
generateImages( whistecontours, (outFolder + File.separator + name) , model, fftLen, fftHop, sampleRate); generateImages( whistecontours, (outFolder + File.separator + name) , model, fftLen, fftHop, sampleRate);
} }
} }
@ -327,4 +363,32 @@ public class DelphinIDUtils {
} }
} }
public static void main(String[] args) {
// double[] density = new double[] {0.15 - 1.5};
//number of whistle bins/number of time bins; either 16 or 21
//the e contours as csv files.
// String whistlefolder = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD";
// String whistlefolder = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD_examples/contours";
String whistlefolder = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD/contours";
//the image folder to save to.
// String imageFolder = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD_Images";
// String imageFolder = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/training/WMD_examples/images";
String imageFolder = "C:/Users/Jamie Macaulay/Desktop/Tristan_training_images/contour_images";
//the path to the model
// String modelPath = "/Users/au671271/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_2/whistle_4s_415.zip";
String modelPath = "D:/Dropbox/PAMGuard_dev/Deep_Learning/delphinID/testencounter415/whistle_model_2/whistle_4s_415.zip";
double[] lineWidths = new double[] {6, 7, 10, 15, 20};
for (double lineWidth:lineWidths) {
String imageFolderWidth = (imageFolder + "_"+ String.format("%d",(int)lineWidth));
new File(imageFolderWidth).mkdir();
generateTrainingData( modelPath, whistlefolder, imageFolderWidth, lineWidth);
}
}
} }

View File

@ -42,6 +42,15 @@ public class DelphinIDWorker extends ArchiveModelWorker {
*/ */
private Whistle2ImageParams whistleImageParams; private Whistle2ImageParams whistleImageParams;
/**
* Get the whislte to image parameters.
*
* @return
*/
public Whistle2ImageParams getWhistleImageParams() {
return whistleImageParams;
}
@Override @Override
public void prepModel(StandardModelParams dlParams, DLControl dlControl) { public void prepModel(StandardModelParams dlParams, DLControl dlControl) {
@ -87,10 +96,12 @@ public class DelphinIDWorker extends ArchiveModelWorker {
freqLimits[1] = jsonObjectParams.getFloat("maxfreq"); freqLimits[1] = jsonObjectParams.getFloat("maxfreq");
size[0] = jsonObjectParams.getInt("widthpix"); size[0] = jsonObjectParams.getInt("widthpix");
size[1] = jsonObjectParams.getInt("heightpix"); size[1] = jsonObjectParams.getInt("heightpix");
double lineWidth = jsonObjectParams.getDouble("linewidthpix");
Whistle2ImageParams whistle2ImageParmas = new Whistle2ImageParams(); Whistle2ImageParams whistle2ImageParmas = new Whistle2ImageParams();
whistle2ImageParmas.freqLimits = freqLimits; whistle2ImageParmas.freqLimits = freqLimits;
whistle2ImageParmas.size = size; whistle2ImageParmas.size = size;
whistle2ImageParmas.lineWidth = lineWidth;
return whistle2ImageParmas; return whistle2ImageParmas;
} }

View File

@ -36,7 +36,7 @@ public class Whistles2Image extends FreqTransform {
// double[] freqLimits = new double[] {params[0].doubleValue(), params[1].doubleValue()}; // double[] freqLimits = new double[] {params[0].doubleValue(), params[1].doubleValue()};
// double[] size = new double[] {params[2].doubleValue(), params[3].doubleValue()}; // double[] size = new double[] {params[2].doubleValue(), params[3].doubleValue()};
SpecTransform specTransform = whistleGroupToImage( whistleGroup, params.freqLimits, params.size); SpecTransform specTransform = whistleGroupToImage( whistleGroup, params.freqLimits, params.size, params.lineWidth);
this.setSpecTransfrom(specTransform); this.setSpecTransfrom(specTransform);
this.setFreqlims(params.freqLimits); this.setFreqlims(params.freqLimits);
@ -50,7 +50,7 @@ public class Whistles2Image extends FreqTransform {
* @param freqLimits - the frequency limits * @param freqLimits - the frequency limits
* @return the spectrogram transform. * @return the spectrogram transform.
*/ */
private SpecTransform whistleGroupToImage(SegmenterDetectionGroup whistleGroup, double[] freqLimits, double[] size) { private SpecTransform whistleGroupToImage(SegmenterDetectionGroup whistleGroup, double[] freqLimits, double[] size, double lineWidth) {
SpecTransform specTransform = new SpecTransform(); SpecTransform specTransform = new SpecTransform();
@ -65,7 +65,7 @@ public class Whistles2Image extends FreqTransform {
ArrayList<double[][]> points = whistContours2Points(whistleGroup); ArrayList<double[][]> points = whistContours2Points(whistleGroup);
//does not work becaue it has to be on the AWT thread. //does not work becaue it has to be on the AWT thread.
BufferedImage canvas = makeScatterImage(points, size, new double[]{0, whistleGroup.getSegmentDuration()/1000.}, freqLimits, 10.); BufferedImage canvas = makeScatterImage(points, size, new double[]{0, whistleGroup.getSegmentDuration()/1000.}, freqLimits, lineWidth);
double[][] imaged = new double[(int) size[0]][(int) size[1]]; double[][] imaged = new double[(int) size[0]][(int) size[1]];
@ -90,9 +90,9 @@ public class Whistles2Image extends FreqTransform {
/** /**
* Convert a list of whistle contours to a list of time and frequency points. * Convert a list of whistle contours to a list of time and frequency points.
* @param whistleGroup - list of whistle contours within a detection group. * @param whistleGroup - list of whistle contours within a detection group.
* @return an array with time (milliseconds from start of group) and frequency (Hz) * @return an array with time (seconds from start of group) and frequency (Hz)
*/ */
private ArrayList<double[][]> whistContours2Points(SegmenterDetectionGroup whistleGroup) { public static ArrayList<double[][]> whistContours2Points(SegmenterDetectionGroup whistleGroup) {
ArrayList<double[][]> contours = new ArrayList<double[][]>(); ArrayList<double[][]> contours = new ArrayList<double[][]>();
@ -212,7 +212,12 @@ public class Whistles2Image extends FreqTransform {
*/ */
public double[] freqLimits; public double[] freqLimits;
public double[] size; public double[] size;
/**
* The line width to draw in pixels
*/
public double lineWidth = 10;
} }

View File

@ -35,6 +35,9 @@ import rawDeepLearningClassifier.defaultModels.DLModel;
*/ */
public class DefaultModelPane extends PamBorderPane{ public class DefaultModelPane extends PamBorderPane{
private static final double PREF_WIDTH = 200;
/** /**
* Reference to the deafult model manager that contains the default models. * Reference to the deafult model manager that contains the default models.
*/ */
@ -74,7 +77,7 @@ public class DefaultModelPane extends PamBorderPane{
// vBox.setPrefWidth(120); // vBox.setPrefWidth(120);
hidingPaneContent= new PamBorderPane(); hidingPaneContent= new PamBorderPane();
hidingPaneContent.setPrefWidth(150); hidingPaneContent.setPrefWidth(PREF_WIDTH);
hidingPane = new HidingPane(Side.RIGHT, hidingPaneContent, vBox, true, 0); hidingPane = new HidingPane(Side.RIGHT, hidingPaneContent, vBox, true, 0);
PamButton button; PamButton button;
@ -101,12 +104,15 @@ public class DefaultModelPane extends PamBorderPane{
} }
hidingPane.setStyle("-fx-background-color: -fx-base"); hidingPane.setStyle("-fx-background-color: -fx-base");
hidingPane.setPrefWidth(PREF_WIDTH);
// this.setStyle("-fx-background-color: -fx-base"); // this.setStyle("-fx-background-color: -fx-base");
PamStackPane mainHolder = new PamStackPane(); PamStackPane mainHolder = new PamStackPane();
mainHolder.getChildren().addAll(vBox, hidingPane); mainHolder.getChildren().addAll(vBox, hidingPane);
StackPane.setAlignment(hidingPane, Pos.TOP_RIGHT); StackPane.setAlignment(hidingPane, Pos.TOP_RIGHT);
mainHolder.setPrefWidth(PREF_WIDTH);
return mainHolder; return mainHolder;
} }

View File

@ -50,6 +50,10 @@ public class SegmenterDetectionGroup extends GroupDetection<PamDataUnit> {
return segMillis; return segMillis;
} }
/**
* Get the segment duration in milliseconds.
* @return the segment duration in millis.
*/
public double getSegmentDuration() { public double getSegmentDuration() {
return segDuration; return segDuration;
} }