Loading GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java +61 −27 Original line number Diff line number Diff line Loading @@ -53,13 +53,34 @@ public class DistanceAction extends ControlPanelAction { */ public DistanceAction(Canvas canvas, JTabbedPane topControlPanel) { super(canvas, topControlPanel); this.controlPanel = new DistancePanel(this, getSecondaryFeaturePoints().getFeaturePoints()); this.featurePointTypes = getSecondaryFeaturePoints().getFeaturePoints() // Calculate weighted Hausdorff distance for all feature points of the secondary face calculateHausdorffDistance( getSecondaryFeaturePoints().getFeaturePoints() .stream() .collect(Collectors.toMap( FeaturePoint::getFeaturePointType, featurePoint -> DrawableFeaturePoints.DEFAULT_SIZE)); featurePoint -> DrawableFeaturePoints.DEFAULT_SIZE)) ); this.featurePointTypes = visitor.getFeaturePointWeights() .get(getSecondaryDrawableFace().getHumanFace()) // Get FP weights for the secondary face .entrySet() .stream() .map(fpWeights -> Map.entry( fpWeights.getKey(), // For each FP type at the secondary face... fpWeights.getValue() // ... compute average FP weight over all its facets .values() .stream() .mapToDouble(weight -> weight) .average() .orElse(Double.NaN))) .filter(fpWeight -> !Double.isNaN(fpWeight.getValue())) // Filter out feature points with Double.NaN weight .collect(Collectors.toMap( Map.Entry::getKey, fpType -> DrawableFeaturePoints.DEFAULT_SIZE)); this.controlPanel = new DistancePanel(this, getSecondaryFeaturePoints().getFeaturePoints(), featurePointTypes.keySet()); this.visitor = null; // Place control panel to the topControlPanel topControlPanel.addTab(controlPanel.getName(), controlPanel.getIcon(), controlPanel); Loading @@ -75,7 +96,7 @@ public class DistanceAction extends ControlPanelAction { } } visitor = null; // recompute (position of faces could have been changed in registration) calculateHausdorffDistance(); updateHausdorffDistanceInformation(); getSecondaryDrawableFace().setRenderHeatmap(heatmapRender); renderScene(); } Loading @@ -90,7 +111,7 @@ public class DistanceAction extends ControlPanelAction { switch (action) { case DistancePanel.ACTION_COMMAND_SHOW_HIDE_HEATMAP: if (((JToggleButton) ae.getSource()).isSelected()) { calculateHausdorffDistance(); updateHausdorffDistanceInformation(); heatmapRender = true; } else { heatmapRender = false; Loading @@ -100,12 +121,12 @@ public class DistanceAction extends ControlPanelAction { case DistancePanel.ACTION_COMMAND_SET_DISTANCE_STRATEGY: strategy = (String) ((JComboBox) ae.getSource()).getSelectedItem(); this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_RELATIVE_ABSOLUTE_DIST: this.relativeDist = ((JToggleButton) ae.getSource()).isSelected(); this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_FEATURE_POINT_HIGHLIGHT: highlightFeaturePoint((LoadedActionEvent) ae); Loading @@ -115,11 +136,11 @@ public class DistanceAction extends ControlPanelAction { break; case DistancePanel.ACTION_COMMAND_WEIGHTED_DISTANCE: this.weightedDist = ((JToggleButton) ae.getSource()).isSelected(); calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_DISTANCE_RECOMPUTE: this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; default: // to nothing Loading @@ -131,7 +152,30 @@ public class DistanceAction extends ControlPanelAction { * (Re)calculates the Hausdorff distance and updates the heat map of the secondary face * as well as values of all appropriate GUI elements of {@link DistancePanel}. */ private void calculateHausdorffDistance() { private void updateHausdorffDistanceInformation() { if (visitor == null) { calculateHausdorffDistance(featurePointTypes); weightedHausdorffDistance = getWeightedDistance(); // Update GUI elements that display the calculated Hausdorff distance metrics setFeaturePointWeigths(); setHausdorffDistanceStatistics(); } getSecondaryDrawableFace().setHeatMap(weightedDist ? weightedHausdorffDistance : visitor.getDistances()); } /** * (Re)calculates the Hausdorff distance. * * @param featurePoints Types of feature points according to which the Hausdorff * distances will be prioritized together with * the radii of priority spheres around the feature * points of the corresponding type. * Must not be {@code null}. */ private void calculateHausdorffDistance(Map<FeaturePointType, Double> featurePoints) { final Strategy useStrategy; switch (strategy) { case DistancePanel.STRATEGY_POINT_TO_POINT: Loading @@ -144,22 +188,12 @@ public class DistanceAction extends ControlPanelAction { throw new UnsupportedOperationException(strategy); } if (visitor == null) { this.visitor = new HausdorffDistancePrioritized(getPrimaryDrawableFace().getModel(), featurePointTypes, featurePoints, useStrategy, relativeDist, true); getSecondaryDrawableFace().getHumanFace().accept(visitor); weightedHausdorffDistance = getWeightedDistance(); // Update GUI elements that display the calculated Hausdorff distance metrics setFeaturePointWeigths(); setHausdorffDistanceStatistics(); } getSecondaryDrawableFace().setHeatMap(weightedDist ? weightedHausdorffDistance : visitor.getDistances()); } /** Loading GUI/src/main/java/cz/fidentis/analyst/distance/DistancePanel.java +11 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import java.util.DoubleSummaryStatistics; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.ImageIcon; Loading Loading @@ -56,9 +57,14 @@ public class DistancePanel extends ControlPanel { /** * Constructor. * * @param action Action listener * @param featurePoints List of all feature points which can be used to calculate * the weighted Hausdorff distance * @param selectedFPs Set of feature point types which are initially selected * to be used to calculate the weighted Hausdorff distance */ public DistancePanel(ActionListener action, List<FeaturePoint> featurePoints) { public DistancePanel(ActionListener action, List<FeaturePoint> featurePoints, Set<FeaturePointType> selectedFPs) { this.setName(NAME); final ControlPanelBuilder builder = new ControlPanelBuilder(this); Loading Loading @@ -87,12 +93,13 @@ public class DistancePanel extends ControlPanel { featurePointStats = new HashMap<>(featurePoints.size()); for (int i = 0; i < featurePoints.size(); i++) { final FeaturePoint featurePoint = featurePoints.get(i); final FeaturePointType featurePointType = featurePoint.getFeaturePointType(); final JCheckBox checkBox = fpBuilder.addCheckBox( true, selectedFPs.contains(featurePointType), createListener(action, ACTION_COMMAND_DISTANCE_RECOMPUTE) ); checkBox.setText(featurePoint.getFeaturePointType().getName()); checkBox.setText(featurePointType.getName()); checkBox.addActionListener(createListener(action, ACTION_COMMAND_FEATURE_POINT_HIGHLIGHT, i)); final JTextField sliderInput = fpBuilder.addSliderOptionLine(null, null, 100, null); Loading @@ -112,7 +119,7 @@ public class DistancePanel extends ControlPanel { sliderInput.addActionListener(createListener(action, ACTION_COMMAND_FEATURE_POINT_RESIZE, i)); fpBuilder.addGap(); featurePointStats.put(featurePoint.getFeaturePointType(), fpBuilder.addLabelLine(null)); featurePointStats.put(featurePointType, fpBuilder.addLabelLine(null)); fpBuilder.addGap(); fpBuilder.addLine(); Loading Loading
GUI/src/main/java/cz/fidentis/analyst/distance/DistanceAction.java +61 −27 Original line number Diff line number Diff line Loading @@ -53,13 +53,34 @@ public class DistanceAction extends ControlPanelAction { */ public DistanceAction(Canvas canvas, JTabbedPane topControlPanel) { super(canvas, topControlPanel); this.controlPanel = new DistancePanel(this, getSecondaryFeaturePoints().getFeaturePoints()); this.featurePointTypes = getSecondaryFeaturePoints().getFeaturePoints() // Calculate weighted Hausdorff distance for all feature points of the secondary face calculateHausdorffDistance( getSecondaryFeaturePoints().getFeaturePoints() .stream() .collect(Collectors.toMap( FeaturePoint::getFeaturePointType, featurePoint -> DrawableFeaturePoints.DEFAULT_SIZE)); featurePoint -> DrawableFeaturePoints.DEFAULT_SIZE)) ); this.featurePointTypes = visitor.getFeaturePointWeights() .get(getSecondaryDrawableFace().getHumanFace()) // Get FP weights for the secondary face .entrySet() .stream() .map(fpWeights -> Map.entry( fpWeights.getKey(), // For each FP type at the secondary face... fpWeights.getValue() // ... compute average FP weight over all its facets .values() .stream() .mapToDouble(weight -> weight) .average() .orElse(Double.NaN))) .filter(fpWeight -> !Double.isNaN(fpWeight.getValue())) // Filter out feature points with Double.NaN weight .collect(Collectors.toMap( Map.Entry::getKey, fpType -> DrawableFeaturePoints.DEFAULT_SIZE)); this.controlPanel = new DistancePanel(this, getSecondaryFeaturePoints().getFeaturePoints(), featurePointTypes.keySet()); this.visitor = null; // Place control panel to the topControlPanel topControlPanel.addTab(controlPanel.getName(), controlPanel.getIcon(), controlPanel); Loading @@ -75,7 +96,7 @@ public class DistanceAction extends ControlPanelAction { } } visitor = null; // recompute (position of faces could have been changed in registration) calculateHausdorffDistance(); updateHausdorffDistanceInformation(); getSecondaryDrawableFace().setRenderHeatmap(heatmapRender); renderScene(); } Loading @@ -90,7 +111,7 @@ public class DistanceAction extends ControlPanelAction { switch (action) { case DistancePanel.ACTION_COMMAND_SHOW_HIDE_HEATMAP: if (((JToggleButton) ae.getSource()).isSelected()) { calculateHausdorffDistance(); updateHausdorffDistanceInformation(); heatmapRender = true; } else { heatmapRender = false; Loading @@ -100,12 +121,12 @@ public class DistanceAction extends ControlPanelAction { case DistancePanel.ACTION_COMMAND_SET_DISTANCE_STRATEGY: strategy = (String) ((JComboBox) ae.getSource()).getSelectedItem(); this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_RELATIVE_ABSOLUTE_DIST: this.relativeDist = ((JToggleButton) ae.getSource()).isSelected(); this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_FEATURE_POINT_HIGHLIGHT: highlightFeaturePoint((LoadedActionEvent) ae); Loading @@ -115,11 +136,11 @@ public class DistanceAction extends ControlPanelAction { break; case DistancePanel.ACTION_COMMAND_WEIGHTED_DISTANCE: this.weightedDist = ((JToggleButton) ae.getSource()).isSelected(); calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; case DistancePanel.ACTION_COMMAND_DISTANCE_RECOMPUTE: this.visitor = null; // recompute calculateHausdorffDistance(); updateHausdorffDistanceInformation(); break; default: // to nothing Loading @@ -131,7 +152,30 @@ public class DistanceAction extends ControlPanelAction { * (Re)calculates the Hausdorff distance and updates the heat map of the secondary face * as well as values of all appropriate GUI elements of {@link DistancePanel}. */ private void calculateHausdorffDistance() { private void updateHausdorffDistanceInformation() { if (visitor == null) { calculateHausdorffDistance(featurePointTypes); weightedHausdorffDistance = getWeightedDistance(); // Update GUI elements that display the calculated Hausdorff distance metrics setFeaturePointWeigths(); setHausdorffDistanceStatistics(); } getSecondaryDrawableFace().setHeatMap(weightedDist ? weightedHausdorffDistance : visitor.getDistances()); } /** * (Re)calculates the Hausdorff distance. * * @param featurePoints Types of feature points according to which the Hausdorff * distances will be prioritized together with * the radii of priority spheres around the feature * points of the corresponding type. * Must not be {@code null}. */ private void calculateHausdorffDistance(Map<FeaturePointType, Double> featurePoints) { final Strategy useStrategy; switch (strategy) { case DistancePanel.STRATEGY_POINT_TO_POINT: Loading @@ -144,22 +188,12 @@ public class DistanceAction extends ControlPanelAction { throw new UnsupportedOperationException(strategy); } if (visitor == null) { this.visitor = new HausdorffDistancePrioritized(getPrimaryDrawableFace().getModel(), featurePointTypes, featurePoints, useStrategy, relativeDist, true); getSecondaryDrawableFace().getHumanFace().accept(visitor); weightedHausdorffDistance = getWeightedDistance(); // Update GUI elements that display the calculated Hausdorff distance metrics setFeaturePointWeigths(); setHausdorffDistanceStatistics(); } getSecondaryDrawableFace().setHeatMap(weightedDist ? weightedHausdorffDistance : visitor.getDistances()); } /** Loading
GUI/src/main/java/cz/fidentis/analyst/distance/DistancePanel.java +11 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ import java.util.DoubleSummaryStatistics; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.ImageIcon; Loading Loading @@ -56,9 +57,14 @@ public class DistancePanel extends ControlPanel { /** * Constructor. * * @param action Action listener * @param featurePoints List of all feature points which can be used to calculate * the weighted Hausdorff distance * @param selectedFPs Set of feature point types which are initially selected * to be used to calculate the weighted Hausdorff distance */ public DistancePanel(ActionListener action, List<FeaturePoint> featurePoints) { public DistancePanel(ActionListener action, List<FeaturePoint> featurePoints, Set<FeaturePointType> selectedFPs) { this.setName(NAME); final ControlPanelBuilder builder = new ControlPanelBuilder(this); Loading Loading @@ -87,12 +93,13 @@ public class DistancePanel extends ControlPanel { featurePointStats = new HashMap<>(featurePoints.size()); for (int i = 0; i < featurePoints.size(); i++) { final FeaturePoint featurePoint = featurePoints.get(i); final FeaturePointType featurePointType = featurePoint.getFeaturePointType(); final JCheckBox checkBox = fpBuilder.addCheckBox( true, selectedFPs.contains(featurePointType), createListener(action, ACTION_COMMAND_DISTANCE_RECOMPUTE) ); checkBox.setText(featurePoint.getFeaturePointType().getName()); checkBox.setText(featurePointType.getName()); checkBox.addActionListener(createListener(action, ACTION_COMMAND_FEATURE_POINT_HIGHLIGHT, i)); final JTextField sliderInput = fpBuilder.addSliderOptionLine(null, null, 100, null); Loading @@ -112,7 +119,7 @@ public class DistancePanel extends ControlPanel { sliderInput.addActionListener(createListener(action, ACTION_COMMAND_FEATURE_POINT_RESIZE, i)); fpBuilder.addGap(); featurePointStats.put(featurePoint.getFeaturePointType(), fpBuilder.addLabelLine(null)); featurePointStats.put(featurePointType, fpBuilder.addLabelLine(null)); fpBuilder.addGap(); fpBuilder.addLine(); Loading