mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
Getting DelphinID working
This commit is contained in:
parent
9b77a97a17
commit
7ee8562c0c
@ -4,7 +4,7 @@
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<name>Pamguard</name>
|
||||
<version>2.02.11b</version>
|
||||
<version>2.02.11c</version>
|
||||
<description>Pamguard using Maven to control dependencies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
<organization>
|
||||
@ -18,6 +18,7 @@
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA</exclude>
|
||||
<exclude>**/*.java</exclude>
|
||||
<exclude>jars/*.*</exclude>
|
||||
</excludes>
|
||||
@ -92,16 +93,6 @@
|
||||
</transformer>
|
||||
<transformer />
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -109,6 +100,16 @@
|
||||
<transformers>
|
||||
<transformer />
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
@ -191,5 +192,8 @@
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<javafx.version>21</javafx.version>
|
||||
<jaxb.runtime.version>2.4.0-b180830.0438</jaxb.runtime.version>
|
||||
<jaxb.xjc.version>2.4.0-b180830.0438</jaxb.xjc.version>
|
||||
<jaxb.api.version>2.4.0-b180830.0359</jaxb.api.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -214,7 +214,7 @@ public class PairBearingLocaliser implements BearingLocaliser {
|
||||
private boolean resetArray(long timeMillis){
|
||||
|
||||
if (this.timeMillis!=timeMillis && currentArray.getHydrophoneLocator().isChangeable()){
|
||||
System.out.println("Reset PairBearingLocaliser");
|
||||
// System.out.println("Reset PairBearingLocaliser");
|
||||
prepare(this.arrayElements, timeMillis, this.timingError);
|
||||
return true;
|
||||
}
|
||||
|
@ -178,7 +178,9 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
|
||||
|
||||
|
||||
/**Classification thresholds etc to set.**/
|
||||
Label classiferInfoLabel2 = new Label("Binary Classification Threshold");
|
||||
Label classiferInfoLabel2 = new Label("Decision Threshold");
|
||||
classiferInfoLabel2.setTooltip(new Tooltip("Set the minimum prediciton value for selected classes. If a prediction exceeds this value "
|
||||
+ "a detection will be saved."));
|
||||
classiferInfoLabel2.setFont(font);
|
||||
|
||||
//PamGuiManagerFX.titleFont2style(classiferInfoLabel2);
|
||||
|
@ -1,5 +1,8 @@
|
||||
package rawDeepLearningClassifier.dlClassification.delphinID;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import rawDeepLearningClassifier.DLControl;
|
||||
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
|
||||
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
|
||||
@ -34,6 +37,17 @@ public class DelphinIDWorker extends DLModelWorker<DelphinIDPrediction>{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float[][][] dataUnits2ModelInput(ArrayList<? extends PamDataUnit> dataUnits, float sampleRate, int iChan){
|
||||
//Our data units are groups of whistles.
|
||||
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,121 @@
|
||||
package rawDeepLearningClassifier.dlClassification.delphinID;
|
||||
|
||||
import org.jamdev.jdl4pam.transforms.FreqTransform;
|
||||
import org.jamdev.jpamutils.spectrogram.SpecTransform;
|
||||
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.paint.Color;
|
||||
import rawDeepLearningClassifier.segmenter.SegmenterDetectionGroup;
|
||||
|
||||
/**
|
||||
* Transform whistles to an image.
|
||||
*
|
||||
* Here we extend the FreqTransform class because it contains lots of image
|
||||
* transforms that are useful once the whistles have been converted into an
|
||||
* image.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class Whistles2Image extends FreqTransform {
|
||||
|
||||
/**
|
||||
* Create an image transform from a whistleGroup.
|
||||
* @param whistleGroup
|
||||
* @param params
|
||||
*/
|
||||
public Whistles2Image(SegmenterDetectionGroup whistleGroup, Number[] params) {
|
||||
super(null, params);
|
||||
double[] freqLimits = new double[] {params[0].doubleValue(), params[1].doubleValue()};
|
||||
double[] size = new double[] {params[2].doubleValue(), params[3].doubleValue()};
|
||||
|
||||
SpecTransform specTransform = whistleGroupToImage( whistleGroup, freqLimits, size);
|
||||
|
||||
this.setSpecTransfrom(specTransform);
|
||||
this.setFreqlims(freqLimits);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a group of whistles
|
||||
* @param whistleGroup - the whistle groups
|
||||
* @param freqLimits - the frequency limits
|
||||
* @return the spectrogram transform.
|
||||
*/
|
||||
private SpecTransform whistleGroupToImage(SegmenterDetectionGroup whistleGroup, double[] freqLimits, double[] size) {
|
||||
|
||||
SpecTransform specTransform = new SpecTransform();
|
||||
|
||||
/*
|
||||
* All time-frequency points are saved as a scatterplot with x-axis spanning 0-4
|
||||
* seconds in time and y-axis spanning 0-20 kHz in frequency. - Matplotlib was
|
||||
* used to produce plot (matplotlib.pyplot.scatter) (Point size set at 5 and all
|
||||
* other values kept at default, including figure size which is saved as 6.4 x
|
||||
* 4.8 inches as default, axes removed before saving using plt.axes(‘off’))
|
||||
**/
|
||||
|
||||
double[][] points = whistContours2Points(whistleGroup);
|
||||
|
||||
Canvas canvas = makeScatterImage(points, size, new double[]{0, whistleGroup.getDurationInMilliseconds()}, freqLimits, 5.);
|
||||
|
||||
WritableImage image = canvas.getGraphicsContext2D().getCanvas().snapshot(null, null);
|
||||
|
||||
double[][] imaged = new double[(int) size[0]][(int) size[1]];
|
||||
|
||||
Color color;
|
||||
for (int i=0; i<imaged.length; i++) {
|
||||
for (int j=0; j<imaged[0].length; j++) {
|
||||
color = image.getPixelReader().getColor(i, j);
|
||||
imaged[i][j] = color.getRed();
|
||||
}
|
||||
}
|
||||
|
||||
specTransform.setSpecData(imaged);
|
||||
specTransform.setSampleRate((float) (freqLimits[1]*2));
|
||||
|
||||
return specTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of whistle contours to a list of time and frequency points.
|
||||
* @param whistleGroup - list of whistle contours within a detection group.
|
||||
* @return an array with time (milliseconds from start of group) and frequency (Hz)
|
||||
*/
|
||||
private double[][] whistContours2Points(SegmenterDetectionGroup whistleGroup) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a scatter image from points
|
||||
* @param points - the points are time (milliseconds from 0) and frequency
|
||||
* @param size - the width and height of the image in pixels
|
||||
* @param xlims - the minimum and maximum time in milliseconds from 0;
|
||||
* @param ylims - the minimum and maximum frequency in Hz
|
||||
* @param markerSize - the marker size in pixels
|
||||
* @return an image with y axis as frequency and x axis as time.
|
||||
*/
|
||||
private Canvas makeScatterImage(double[][] points, double[] size, double[] xlims, double[] ylims, double markerSize) {
|
||||
|
||||
Canvas canvas = new Canvas(size[0], size[1]);
|
||||
|
||||
double x, y;
|
||||
for (int i=0; i<points.length; i++) {
|
||||
canvas.getGraphicsContext2D().setFill(Color.BLACK);
|
||||
|
||||
//Calculate x and y in pixels.
|
||||
x = ((points[i][0]-xlims[0])/(xlims[1]-xlims[0]))*size[0];
|
||||
y = ((points[i][0]-xlims[0])/(xlims[1]-xlims[0]))*size[0];
|
||||
|
||||
canvas.getGraphicsContext2D().fillOval(x+markerSize/2, y-markerSize/2, markerSize/2, markerSize/2);
|
||||
}
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -348,7 +348,7 @@ public class DLSettingsPane extends SettingsPane<RawDLParams>{
|
||||
//only show the data selector box for detec tion data.
|
||||
if (sourcePane.getSource() == null) this.dataSelectorPane.setVisible(false);
|
||||
|
||||
if (sourcePane.getSource().getDataSelectCreator() instanceof NullDataSelectorCreator) {
|
||||
else if (sourcePane.getSource().getDataSelectCreator() instanceof NullDataSelectorCreator) {
|
||||
//^bit messy but cannot think of a better way to do it.
|
||||
this.dataSelectorPane.setVisible(false);
|
||||
}
|
||||
|
@ -4,14 +4,21 @@ import Localiser.detectionGroupLocaliser.GroupDetection;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
|
||||
/**
|
||||
* A group of detection which are within a particular segment. This is used to pass detection groups straight to
|
||||
*
|
||||
*
|
||||
* * @author Jamie Macaulay
|
||||
* A group of detection which are within a particular segment. This is used to pass detection groups straight to a classifier.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class SegmenterDetectionGroup extends GroupDetection<PamDataUnit> {
|
||||
|
||||
/**
|
||||
* Constructor for a group of detections within a detection. Note that some
|
||||
* longer detections (e.g. whistles) may have sections outside the segment.
|
||||
*
|
||||
* @param timeMilliseconds - this is the start of the SEGMENT - Note that the
|
||||
* @param channelBitmap - channels of all detections
|
||||
* @param startSample - the stratSample of the SEGMENT.
|
||||
* @param duration - the duration of the SEGMENT.
|
||||
*/
|
||||
public SegmenterDetectionGroup(long timeMilliseconds, int channelBitmap, long startSample, long duration) {
|
||||
super(timeMilliseconds, channelBitmap, startSample, duration);
|
||||
// TODO Auto-generated constructor stub
|
||||
|
@ -11,10 +11,11 @@ public class WMAlarmParameters extends DataSelectParams implements Cloneable, Se
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
|
||||
public double minFreq, maxFreq;
|
||||
public double minAmplitude;
|
||||
public double minLengthMillis;
|
||||
public boolean superDetOnly;
|
||||
public double minFreq = 0.;
|
||||
public double maxFreq = 30000.;
|
||||
public double minAmplitude = 90.;
|
||||
public double minLengthMillis = 0.0;
|
||||
public boolean superDetOnly = false;
|
||||
|
||||
@Override
|
||||
public WMAlarmParameters clone() {
|
||||
|
@ -1,15 +1,9 @@
|
||||
package whistlesAndMoans.dataSelector;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import alarm.AlarmParameters;
|
||||
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
|
||||
import whistlesAndMoans.ConnectedRegionDataUnit;
|
||||
import whistlesAndMoans.WhistleMoanControl;
|
||||
import whistlesAndMoans.alarm.WMAlarmParameters;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamView.dialog.PamDialogPanel;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
@ -24,6 +18,11 @@ public class WMDDataSelector extends DataSelector {
|
||||
|
||||
private WMAlarmParameters wmAlarmParameters = new WMAlarmParameters();
|
||||
|
||||
/**
|
||||
* JavaFX pane.
|
||||
*/
|
||||
private WMDSelectPaneFX wmdSelectPaneFX;
|
||||
|
||||
public WMDDataSelector(WhistleMoanControl wmControl, PamDataBlock pamDataBlock, String selectorName,
|
||||
boolean allowScores) {
|
||||
super(pamDataBlock, selectorName, allowScores);
|
||||
@ -94,8 +93,10 @@ public class WMDDataSelector extends DataSelector {
|
||||
|
||||
@Override
|
||||
public DynamicSettingsPane<Boolean> getDialogPaneFX() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
if (wmdSelectPaneFX == null) {
|
||||
wmdSelectPaneFX = new WMDSelectPaneFX(this);
|
||||
}
|
||||
return wmdSelectPaneFX;
|
||||
}
|
||||
|
||||
}
|
||||
|
151
src/whistlesAndMoans/dataSelector/WMDSelectPaneFX.java
Normal file
151
src/whistlesAndMoans/dataSelector/WMDSelectPaneFX.java
Normal file
@ -0,0 +1,151 @@
|
||||
package whistlesAndMoans.dataSelector;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
|
||||
import whistlesAndMoans.alarm.WMAlarmParameters;
|
||||
|
||||
/**
|
||||
* JavaFX settings pane for the whsitle and moan detector data selector.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class WMDSelectPaneFX extends DynamicSettingsPane<Boolean> {
|
||||
|
||||
private Pane mainPane;
|
||||
|
||||
private WMDDataSelector wmdDataSelector;
|
||||
|
||||
private Spinner<Double> minFreq;
|
||||
|
||||
private Spinner<Double> maxFreq;
|
||||
|
||||
private Spinner<Double> minAmplitude;
|
||||
|
||||
private Spinner<Double> minLength;
|
||||
|
||||
private PamToggleSwitch superDetOnly;
|
||||
|
||||
public WMDSelectPaneFX(WMDDataSelector wmdDataSelector) {
|
||||
super(wmdDataSelector);
|
||||
this.wmdDataSelector = wmdDataSelector;
|
||||
// TODO Auto-generated constructor stub
|
||||
mainPane = createPane();
|
||||
}
|
||||
|
||||
|
||||
private Pane createPane() {
|
||||
|
||||
PamVBox mainPane = new PamVBox();
|
||||
mainPane.setSpacing(5.);
|
||||
|
||||
PamGridPane gridPane = new PamGridPane();
|
||||
gridPane.setHgap(5.);
|
||||
gridPane.setVgap(5.);
|
||||
|
||||
int row = 0;
|
||||
int column = 0;
|
||||
|
||||
minFreq = new Spinner<Double>(0.,Double.MAX_VALUE, 100., 100.);
|
||||
minFreq.setEditable(true);
|
||||
|
||||
gridPane.add(new Label("Min. frequency"), column, row);
|
||||
column++;
|
||||
gridPane.add(minFreq, column, row);
|
||||
column++;
|
||||
gridPane.add(new Label("Hz"), column, row);
|
||||
|
||||
maxFreq = new Spinner<Double>(0.,Double.MAX_VALUE, 30000., 100.);
|
||||
maxFreq.setEditable(true);
|
||||
|
||||
row++;
|
||||
column=0;
|
||||
gridPane.add(new Label("Max. frequency"), column, row);
|
||||
gridPane.add(maxFreq, ++column, row);
|
||||
gridPane.add(new Label("Hz"), ++column, row);
|
||||
|
||||
minAmplitude = new Spinner<Double>(0.,1000., 90., 1.);
|
||||
minAmplitude.setEditable(true);
|
||||
|
||||
row++;
|
||||
column=0;
|
||||
gridPane.add(new Label("Min. amplitude"), column, row);
|
||||
gridPane.add(minAmplitude, ++column, row);
|
||||
gridPane.add(new Label("dB"), ++column, row);
|
||||
|
||||
minLength = new Spinner<Double>(0.,Double.MAX_VALUE, 0., 1.);
|
||||
minLength.setEditable(true);
|
||||
|
||||
row++;
|
||||
column=0;
|
||||
gridPane.add(new Label("Min. length"), column, row);
|
||||
gridPane.add(minLength, ++column, row);
|
||||
gridPane.add(new Label("milliseconds"), ++column, row);
|
||||
|
||||
row++;
|
||||
column=0;
|
||||
superDetOnly = new PamToggleSwitch("Only whistles with super-detections");
|
||||
gridPane.add(superDetOnly, column, row);
|
||||
GridPane.setColumnSpan(superDetOnly, 3);
|
||||
|
||||
mainPane.getChildren().add(gridPane);
|
||||
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getParams(Boolean currParams) {
|
||||
|
||||
WMAlarmParameters wmAlarmParameters = wmdDataSelector.getWmAlarmParameters().clone();
|
||||
try {
|
||||
wmAlarmParameters.minFreq = minFreq.getValue();
|
||||
wmAlarmParameters.maxFreq = maxFreq.getValue();
|
||||
wmAlarmParameters.minAmplitude = minAmplitude.getValue();
|
||||
wmAlarmParameters.minLengthMillis = minLength.getValue();
|
||||
wmAlarmParameters.superDetOnly = superDetOnly.isSelected();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
wmdDataSelector.setWmAlarmParameters(wmAlarmParameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(Boolean input) {
|
||||
|
||||
WMAlarmParameters wmAlarmParameters = wmdDataSelector.getWmAlarmParameters();
|
||||
|
||||
minFreq.getValueFactory().setValue(wmAlarmParameters.minFreq);
|
||||
maxFreq.getValueFactory().setValue(wmAlarmParameters.maxFreq);
|
||||
minAmplitude.getValueFactory().setValue(wmAlarmParameters.minAmplitude);
|
||||
minLength.getValueFactory().setValue(wmAlarmParameters.minLengthMillis);
|
||||
|
||||
superDetOnly.setSelected(wmAlarmParameters.superDetOnly);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "WMD Data Selector";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user