From c5b4e3bf8c91a7b7713c5e24cc3c5cb397bcc825 Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Mon, 3 Nov 2025 05:53:32 -0500
Subject: [PATCH 1/6] depend on the snapshot version of mvr
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index e61cf40..1eab942 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,7 +120,7 @@
1.5.0
-->
- 7.0.7
+ 7.0.8-SNAPSHOT
1.0.2
1.6.5
From 27d0aee58b27c43a95a7c4a9181463054659971c Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Mon, 3 Nov 2025 05:55:55 -0500
Subject: [PATCH 2/6] Sync GUI features with multiview-reconstruction
7.0.8-SNAPSHOT
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Implement clearGroupingCheckboxes() to uncheck grouping UI when auto-disabled
- Update Help.html with all keyboard shortcuts including new selection features
- Add prominent usage information box about right-click functionality
Matches changes from multiview-reconstruction splitCorr branch:
- Selection dialog (+)
- History navigation (<, >)
- Auto-disable grouping for selection operations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude
---
.../stitcher/gui/StitchingExplorerPanel.java | 9 +++
src/main/resources/BigStitcher/Help.html | 59 ++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/preibisch/stitcher/gui/StitchingExplorerPanel.java b/src/main/java/net/preibisch/stitcher/gui/StitchingExplorerPanel.java
index 1cb5d87..5832e5a 100644
--- a/src/main/java/net/preibisch/stitcher/gui/StitchingExplorerPanel.java
+++ b/src/main/java/net/preibisch/stitcher/gui/StitchingExplorerPanel.java
@@ -265,6 +265,15 @@ public boolean illumsGrouped()
return true;
}
+ @Override
+ protected void clearGroupingCheckboxes()
+ {
+ if ( checkboxGroupChannels != null )
+ checkboxGroupChannels.setSelected( false );
+ if ( checkboxGroupIllums != null )
+ checkboxGroupIllums.setSelected( false );
+ }
+
void quitLinkExplorer()
diff --git a/src/main/resources/BigStitcher/Help.html b/src/main/resources/BigStitcher/Help.html
index 2101dca..57dc2f7 100644
--- a/src/main/resources/BigStitcher/Help.html
+++ b/src/main/resources/BigStitcher/Help.html
@@ -61,7 +61,19 @@ BigStitcher
For general help regarding usage of BigStitcher please go to the following
webpage: http://imagej.net/BigStitcher.
-
+
+
+
💡 Important Usage Information
+
+All functionality is available by right-clicking on the views you want to process.
+Simply select one or more views in the Stitching Explorer table, then right-click
+to access all processing options.
+
+
+For macro recording: Please use the Fiji BigStitcher plugins menu instead of the
+interactive explorer interface, as the explorer does not support macro recording.
+
+
Key Bindings for BigStitcher
@@ -79,8 +91,14 @@
Key Bindings for BigStitcher
+ | F1 |
+ Show this help window. |
+
| C |
Switch between fused mode and random coloring of image stacks. |
+
+ | V |
+ Toggle ViewSetup ID overlay in BigDataViewer (shows setup IDs on screen). |
| L |
Display links between images used for registation
@@ -88,6 +106,45 @@ Key Bindings for BigStitcher
|
| R |
Re-orient BigDataViewer onto the currently selected tiles. |
+
+ Cmd+A (Mac) Ctrl+A (Win/Linux) |
+ Select all views in the table. |
+
+ | + |
+ Open selection dialog to filter views by criteria (ranges, comma-separated values, AND/OR logic). |
+
+ | < or , |
+ Navigate backward in selection history (undo selection). |
+
+ | > or . |
+ Navigate forward in selection history (redo selection). |
+
+ | E |
+ Enable fly-through recording mode (Easter Egg). Once enabled, the following keys become active: |
+
+ | a |
+ Add current BDV view as keypoint for fly-through. |
+
+ | x |
+ Clear all keypoints. |
+
+ | d |
+ Delete last keypoint. |
+
+ | j |
+ Jump BDV to the last keypoint. |
+
+ | r |
+ Start recording fly-through animation. |
+
+ | s |
+ Save all keypoints to file. |
+
+ | l |
+ Load keypoints from file. |
+
+ | R |
+ Make a high-resolution screenshot with user-defined resolution. |
From 510e3b1a740fd83db28c55155b55fbd8ff88d8a2 Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Mon, 3 Nov 2025 06:30:21 -0500
Subject: [PATCH 3/6] fix according to changes with interest points and
prealignment (TODO: remove all interest point handling from BigStitcher
except ICP)
---
.../algorithm/globalopt/ExecuteGlobalOpt.java | 3 ++-
.../algorithm/globalopt/GlobalOptStitcher.java | 3 +++
.../algorithm/globalopt/TransformationTools.java | 1 +
.../stitcher/gui/popup/RefineWithICPPopup.java | 4 +++-
.../registration/TestGlobalOptTwoRound.java | 1 +
.../stitcher/plugin/Calculate_Pairwise_Shifts.java | 6 +++---
.../plugin/Global_Optimization_Stitching.java | 2 +-
.../preibisch/stitcher/process/ICPRefinement.java | 14 ++++++++++----
8 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
index f34e8a3..9e89249 100644
--- a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
+++ b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
@@ -76,7 +76,8 @@ public void run()
}
final boolean isSavedFaG = savedFiltering != null;
- final GlobalOptimizationParameters params = expertMode ? GlobalOptimizationParameters.askUserForParameters(!isSavedFaG) : GlobalOptimizationParameters.askUserForSimpleParameters();
+ final boolean preAlign = false; // no pre-align for ICP
+ final GlobalOptimizationParameters params = expertMode ? GlobalOptimizationParameters.askUserForParameters(!isSavedFaG, preAlign) : GlobalOptimizationParameters.askUserForSimpleParameters();
if ( params == null )
return;
diff --git a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/GlobalOptStitcher.java b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/GlobalOptStitcher.java
index 0f6ca51..84911e8 100644
--- a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/GlobalOptStitcher.java
+++ b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/GlobalOptStitcher.java
@@ -191,6 +191,7 @@ public List< ViewId > getDefaultFixedViews()
{
HashMap< ViewId, mpicbg.models.Tile< TranslationModel3D > > globalOptResults = GlobalOptTwoRound.computeTiles(
new TranslationModel3D(),
+ true,// preAlign
new ImageCorrelationPointMatchCreator( results ),
new SimpleIterativeConvergenceStrategy( Double.MAX_VALUE,
params.relativeThreshold, params.absoluteThreshold ),
@@ -222,6 +223,7 @@ else if ( params.method == GlobalOptType.ONE_ROUND_ITERATIVE)
{
HashMap< ViewId, mpicbg.models.Tile< TranslationModel3D > > globalOptResults = GlobalOptIterative.computeTiles(
new TranslationModel3D(),
+ true,// preAlign
new ImageCorrelationPointMatchCreator( results ),
new SimpleIterativeConvergenceStrategy( Double.MAX_VALUE,
params.relativeThreshold, params.absoluteThreshold ),
@@ -246,6 +248,7 @@ else if ( params.method == GlobalOptType.ONE_ROUND_ITERATIVE)
{
final HashMap< ViewId, mpicbg.models.Tile< TranslationModel3D > > globalOptResults = GlobalOpt.computeTiles(
new TranslationModel3D(),
+ true,// preAlign
new ImageCorrelationPointMatchCreator( results ),
new SimpleIterativeConvergenceStrategy( Double.MAX_VALUE,
params.relativeThreshold, params.absoluteThreshold ),
diff --git a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/TransformationTools.java b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/TransformationTools.java
index 6251185..0195835 100644
--- a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/TransformationTools.java
+++ b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/TransformationTools.java
@@ -750,6 +750,7 @@ public static void main( String[] args )
GlobalOpt.computeTiles(
new TranslationModel3D(),
+ true,// preAlign
new ImageCorrelationPointMatchCreator( results, 0.5 ),
new ConvergenceStrategy( 5.0 ),
fixedViews,
diff --git a/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java b/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
index ca6a393..bc4058b 100644
--- a/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
+++ b/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
@@ -229,6 +229,8 @@ public void actionPerformed( ActionEvent e )
// remember for macro recording
ICPRefinement.defaultRefinementChoice = icpType.ordinal();
+ final boolean preAlign = false;
+ GlobalOptimizationParameters.defaultPrealign = preAlign;
GlobalOptimizationParameters globalOptParams;
if ( icpType == ICPType.Expert )
@@ -243,7 +245,7 @@ public void actionPerformed( ActionEvent e )
if ( !ICPRefinement.getGUIParametersSimple( icpType, data, params, downsamplingChoice, thresholdChoice, distanceChoice ) )
return;
- globalOptParams = GlobalOptimizationParameters.getGlobalOptimizationParametersForSelection( GlobalOptimizationParameters.defaultSimple );
+ globalOptParams = GlobalOptimizationParameters.getGlobalOptimizationParametersForSelection( GlobalOptimizationParameters.defaultSimple, preAlign );
}
if ( globalOptParams == null )
diff --git a/src/main/java/net/preibisch/stitcher/headless/registration/TestGlobalOptTwoRound.java b/src/main/java/net/preibisch/stitcher/headless/registration/TestGlobalOptTwoRound.java
index 4dfe38e..333f0aa 100644
--- a/src/main/java/net/preibisch/stitcher/headless/registration/TestGlobalOptTwoRound.java
+++ b/src/main/java/net/preibisch/stitcher/headless/registration/TestGlobalOptTwoRound.java
@@ -148,6 +148,7 @@ public static void main( String[] args )
final HashMap< ViewId, TranslationModel3D > computeResults = GlobalOptTwoRound.computeModels(
new TranslationModel3D(),
+ true,// preAlign
pmc,
cs,
new MaxErrorLinkRemoval(),
diff --git a/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java b/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
index 19e2b15..6ebd63b 100644
--- a/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
+++ b/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
@@ -270,7 +270,7 @@ public static boolean processLucasKanade(
return true;
}
-
+ // TODO: remove interest points from BigStitcher entirely (except for ICP refinement)
public static boolean processInterestPoint(final SpimData2 data,
final SpimDataFilteringAndGrouping< SpimData2 > filteringAndGrouping,
boolean existingInterestPoints)
@@ -313,7 +313,7 @@ public static boolean processInterestPoint(final SpimData2 data,
new Font( Font.SANS_SERIF, Font.BOLD, 12 ) );
gd.addMessage( "" );
- brp.pwr.presetTransformationModel( new TransformationModelGUI( 0 ) );
+ //brp.pwr.presetTransformationModel( new TransformationModelGUI( 0 ) );
brp.pwr.addQuery( gd );
gd.showDialog();
@@ -419,7 +419,7 @@ public List< ViewId > getDefaultFixedViews()
data.getSequenceDescription().getViewDescriptions(),
ipMap,
brp.labelMap,
- new GlobalOptimizationParameters(Double.MAX_VALUE, Double.MAX_VALUE, GlobalOptType.ONE_ROUND_SIMPLE, false ),
+ new GlobalOptimizationParameters(Double.MAX_VALUE, Double.MAX_VALUE, GlobalOptType.ONE_ROUND_SIMPLE, true, false ),
false, //matchacrosslabels
true ) )
continue;
diff --git a/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java b/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
index f508e4a..dbad5c2 100644
--- a/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
+++ b/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
@@ -66,7 +66,7 @@ public void run(String arg)
final HashSet< Class< ? extends Entity > > defaultComparisonFactors = new HashSet<>();
defaultComparisonFactors.add( Tile.class );
- GlobalOptimizationParameters params = GlobalOptimizationParameters.askUserForParameters(true);
+ GlobalOptimizationParameters params = GlobalOptimizationParameters.askUserForParameters(true, true /*prealign*/);
if (params.showExpertGrouping)
grouping.askUserForGrouping(
diff --git a/src/main/java/net/preibisch/stitcher/process/ICPRefinement.java b/src/main/java/net/preibisch/stitcher/process/ICPRefinement.java
index 84ebfee..37ad286 100644
--- a/src/main/java/net/preibisch/stitcher/process/ICPRefinement.java
+++ b/src/main/java/net/preibisch/stitcher/process/ICPRefinement.java
@@ -436,7 +436,7 @@ public static void refine(
}
// load & transform all interest points
- final Map< ViewId, HashMap< String, List< InterestPoint > > > interestpoints =
+ final Map< ViewId, HashMap< String, Collection< InterestPoint > > > interestpoints =
TransformationTools.getAllTransformedInterestPoints(
params.viewIds,
data.getViewRegistrations().getViewRegistrations(),
@@ -519,7 +519,7 @@ public static void refine(
public static final HashMap< ViewId, mpicbg.models.Tile > pairSubset(
final SpimData2 spimData,
final Subset< ViewId > subset,
- final Map< ViewId, HashMap< String, List< InterestPoint > > > interestpoints,
+ final Map< ViewId, HashMap< String, Collection< InterestPoint > > > interestpoints,
final Map< ViewId, HashMap< String, Double > > labelMap,
final IterativeClosestPointParameters icpp,
final List< ViewId > fixedViews,
@@ -594,6 +594,7 @@ public static final HashMap< ViewId, mpicbg.models.Tile > pairSubset(
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOpt.computeTiles(
(Model)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new ConvergenceStrategy( icpp.getMaxDistance() ),
fixedViews,
@@ -603,6 +604,7 @@ else if ( globalOptParameters.method == GlobalOptType.ONE_ROUND_ITERATIVE )
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOptIterative.computeTiles(
(Model)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new SimpleIterativeConvergenceStrategy( icpp.getMaxDistance(), globalOptParameters.relativeThreshold, globalOptParameters.absoluteThreshold ),
new MaxErrorLinkRemoval(),
@@ -614,6 +616,7 @@ else if ( globalOptParameters.method == GlobalOptType.ONE_ROUND_ITERATIVE )
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOptTwoRound.computeTiles(
(Model & Affine3D)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new SimpleIterativeConvergenceStrategy( icpp.getMaxDistance(), globalOptParameters.relativeThreshold, globalOptParameters.absoluteThreshold ), // if it's simple, both will be Double.MAX
new MaxErrorLinkRemoval(),
@@ -635,7 +638,7 @@ else if ( globalOptParameters.method == GlobalOptType.ONE_ROUND_ITERATIVE )
public static HashMap< ViewId, mpicbg.models.Tile > groupedSubset(
final SpimData2 spimData,
final Subset< ViewId > subset,
- final Map< ViewId, HashMap< String, List< InterestPoint > > > interestpoints,
+ final Map< ViewId, HashMap< String, Collection< InterestPoint > > > interestpoints,
final Map< ViewId, HashMap< String, Double > > labelMap,
final IterativeClosestPointParameters icpp,
final List< ViewId > fixedViews,
@@ -646,7 +649,7 @@ public static HashMap< ViewId, mpicbg.models.Tile > groupedSubset(
final boolean matchAcrossLabels )
{
final List< Pair< Group< ViewId >, Group< ViewId > > > groupedPairs = subset.getGroupedPairs();
- final Map< Group< ViewId >, HashMap< String, List< GroupedInterestPoint< ViewId > > > > groupedInterestpoints = new HashMap<>();
+ final Map< Group< ViewId >, HashMap< String, Collection< GroupedInterestPoint< ViewId > > > > groupedInterestpoints = new HashMap<>();
final InterestPointGrouping< ViewId > ipGrouping = new InterestPointGroupingMinDistance<>( interestpoints );
if ( groupedPairs.size() <= 0 )
@@ -714,6 +717,7 @@ public static HashMap< ViewId, mpicbg.models.Tile > groupedSubset(
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOpt.computeTiles(
(Model)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new ConvergenceStrategy( icpp.getMaxDistance() ),
fixedViews,
@@ -723,6 +727,7 @@ else if ( globalOptParameters.method == GlobalOptType.ONE_ROUND_ITERATIVE )
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOptIterative.computeTiles(
(Model)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new SimpleIterativeConvergenceStrategy( icpp.getMaxDistance(), globalOptParameters.relativeThreshold, globalOptParameters.absoluteThreshold ),
new MaxErrorLinkRemoval(),
@@ -734,6 +739,7 @@ else if ( globalOptParameters.method == GlobalOptType.ONE_ROUND_ITERATIVE )
{
models = (HashMap< ViewId, mpicbg.models.Tile >)(Object)GlobalOptTwoRound.computeTiles(
(Model & Affine3D)(Object)icpp.getModel().copy(),
+ globalOptParameters.preAlign,
pmc,
new SimpleIterativeConvergenceStrategy( icpp.getMaxDistance(), globalOptParameters.relativeThreshold, globalOptParameters.absoluteThreshold ), // if it's simple, both will be Double.MAX
new MaxErrorLinkRemoval(),
From e68abecf8e75a733e6b5d4ec153b4b6edeb42f11 Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Mon, 3 Nov 2025 12:46:55 -0500
Subject: [PATCH 4/6] remove interest-ppint based processing
---
.../algorithm/globalopt/ExecuteGlobalOpt.java | 3 +-
.../popup/CalculatePCPopupExpertBatch.java | 5 +-
...airwiseInterestPointRegistrationPopup.java | 227 ------------------
.../gui/popup/RefineWithICPPopup.java | 5 +-
.../plugin/Calculate_Pairwise_Shifts.java | 227 +-----------------
.../plugin/Global_Optimization_Stitching.java | 3 +-
6 files changed, 17 insertions(+), 453 deletions(-)
delete mode 100644 src/main/java/net/preibisch/stitcher/gui/popup/PairwiseInterestPointRegistrationPopup.java
diff --git a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
index 9e89249..64ea31e 100644
--- a/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
+++ b/src/main/java/net/preibisch/stitcher/algorithm/globalopt/ExecuteGlobalOpt.java
@@ -76,8 +76,7 @@ public void run()
}
final boolean isSavedFaG = savedFiltering != null;
- final boolean preAlign = false; // no pre-align for ICP
- final GlobalOptimizationParameters params = expertMode ? GlobalOptimizationParameters.askUserForParameters(!isSavedFaG, preAlign) : GlobalOptimizationParameters.askUserForSimpleParameters();
+ final GlobalOptimizationParameters params = GlobalOptimizationParameters.askUserForSimpleParameters();
if ( params == null )
return;
diff --git a/src/main/java/net/preibisch/stitcher/gui/popup/CalculatePCPopupExpertBatch.java b/src/main/java/net/preibisch/stitcher/gui/popup/CalculatePCPopupExpertBatch.java
index c369cf5..74adaef 100644
--- a/src/main/java/net/preibisch/stitcher/gui/popup/CalculatePCPopupExpertBatch.java
+++ b/src/main/java/net/preibisch/stitcher/gui/popup/CalculatePCPopupExpertBatch.java
@@ -31,10 +31,10 @@
public class CalculatePCPopupExpertBatch extends JMenu implements ExplorerWindowSetable
{
+ private static final long serialVersionUID = 804355154792175254L;
final CalculatePCPopup phaseCorrSimple;
final CalculatePCPopup phaseCorr;
final CalculatePCPopup lucasKanade;
- final PairwiseInterestPointRegistrationPopup interestPoint;
boolean wizardMode;
public CalculatePCPopupExpertBatch( String description, boolean wizardMode )
@@ -50,13 +50,11 @@ public CalculatePCPopupExpertBatch( String description, boolean wizardMode )
phaseCorr = new CalculatePCPopup( wizardMode ? "Phase Correlation" : "Phase Correlation (expert)", false, Method.PHASECORRELATION, wizardMode );
lucasKanade = new CalculatePCPopup( "Lucas-Kanade", false, Method.LUCASKANADE, wizardMode );
- interestPoint = new PairwiseInterestPointRegistrationPopup( "Interest point based", wizardMode );
if(!wizardMode)
this.add(phaseCorrSimple);
this.add( phaseCorr );
this.add( lucasKanade );
- this.add( interestPoint );
}
@Override
@@ -66,7 +64,6 @@ public JComponent setExplorerWindow( ExplorerWindow< ? > panel )
this.phaseCorrSimple.setExplorerWindow( panel );
this.phaseCorr.setExplorerWindow( panel );
this.lucasKanade.setExplorerWindow( panel );
- this.interestPoint.setExplorerWindow( panel );
return this;
}
diff --git a/src/main/java/net/preibisch/stitcher/gui/popup/PairwiseInterestPointRegistrationPopup.java b/src/main/java/net/preibisch/stitcher/gui/popup/PairwiseInterestPointRegistrationPopup.java
deleted file mode 100644
index 1595308..0000000
--- a/src/main/java/net/preibisch/stitcher/gui/popup/PairwiseInterestPointRegistrationPopup.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*-
- * #%L
- * Multiview stitching of large datasets.
- * %%
- * Copyright (C) 2016 - 2025 Big Stitcher developers.
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program. If not, see
- * .
- * #L%
- */
-package net.preibisch.stitcher.gui.popup;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JComponent;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.event.MenuEvent;
-import javax.swing.event.MenuListener;
-
-import mpicbg.spim.data.sequence.Channel;
-import mpicbg.spim.data.sequence.Illumination;
-import mpicbg.spim.data.sequence.Tile;
-import mpicbg.spim.data.sequence.ViewId;
-import net.preibisch.legacy.io.IOFunctions;
-import net.preibisch.mvrecon.fiji.spimdata.SpimData2;
-import net.preibisch.mvrecon.fiji.spimdata.explorer.ExplorerWindow;
-import net.preibisch.mvrecon.fiji.spimdata.explorer.FilteredAndGroupedExplorerPanel;
-import net.preibisch.mvrecon.fiji.spimdata.explorer.GroupedRowWindow;
-import net.preibisch.mvrecon.fiji.spimdata.explorer.popup.ExplorerWindowSetable;
-import net.preibisch.mvrecon.fiji.spimdata.interestpoints.ViewInterestPoints;
-import net.preibisch.stitcher.algorithm.SpimDataFilteringAndGrouping;
-import net.preibisch.stitcher.gui.StitchingExplorerPanel;
-import net.preibisch.stitcher.gui.StitchingUIHelper;
-import net.preibisch.stitcher.plugin.Calculate_Pairwise_Shifts;
-
-public class PairwiseInterestPointRegistrationPopup extends JMenu implements ExplorerWindowSetable
-{
-
- private static final long serialVersionUID = -396274656320474433L;
- ExplorerWindow< ? > panel;
-
- private JMenuItem withDetection;
- private JMenuItem withoutDetection;
- private JCheckBoxMenuItem expertGrouping;
-
- private boolean wizardMode;
-
- public PairwiseInterestPointRegistrationPopup(String description, boolean wizardMode )
- {
- super( description );
- this.addActionListener( new MyActionListener(false) );
-
- this.wizardMode = wizardMode;
-
- withDetection = new JMenuItem( "With new Interest Points" );
- withoutDetection = new JMenuItem( "With existing Interest Points" );
- expertGrouping = new JCheckBoxMenuItem( "Show expert grouping Options", false );
-
- withDetection.addActionListener( new MyActionListener( false ) );
- withoutDetection.addActionListener( new MyActionListener( true ) );
-
- this.add( withDetection );
- this.add( withoutDetection );
- this.addSeparator();
- this.add( expertGrouping );
-
- this.addMenuListener( new MenuListener()
- {
- @Override
- public void menuSelected(MenuEvent e)
- {
- if (SpimData2.class.isInstance( panel.getSpimData() ))
- {
- final List< ViewId > selectedViews = ((GroupedRowWindow)panel).selectedRowsViewIdGroups().stream().reduce( new ArrayList<>(), (x,y) -> {x.addAll( y ); return x;} );
- boolean allHaveIPs = true;
- final ViewInterestPoints viewInterestPoints = ((SpimData2)panel.getSpimData()).getViewInterestPoints();
- for (ViewId vid : selectedViews)
- if (panel.getSpimData().getSequenceDescription().getMissingViews() != null &&
- !panel.getSpimData().getSequenceDescription().getMissingViews().getMissingViews().contains( vid ))
- {
- if (!viewInterestPoints.getViewInterestPoints().containsKey( vid ) ||
- viewInterestPoints.getViewInterestPoints().get( vid ).getHashMap().size() < 1)
- {
- allHaveIPs = false;
- break;
- }
- }
- withoutDetection.setEnabled( allHaveIPs );
- }
- }
-
- @Override
- public void menuDeselected(MenuEvent e){}
-
- @Override
- public void menuCanceled(MenuEvent e){}
-
- } );
- }
-
- @Override
- public JComponent setExplorerWindow( final ExplorerWindow< ? > panel )
- {
- this.panel = panel;
- return this;
- }
-
- public class MyActionListener implements ActionListener
- {
- private boolean existingInterestPoints;
-
- public MyActionListener(boolean existingInterestPoints)
- {
- this.existingInterestPoints = existingInterestPoints;
- }
-
- @Override
- public void actionPerformed(ActionEvent e)
- {
- if ( panel == null )
- {
- IOFunctions.println( "Panel not set for " + this.getClass().getSimpleName() );
- return;
- }
-
- if ( !SpimData2.class.isInstance( panel.getSpimData() ) )
- {
- IOFunctions.println( "Only supported for SpimData2 objects: " + this.getClass().getSimpleName() );
- return;
- }
-
- if (!GroupedRowWindow.class.isInstance( panel ))
- {
- IOFunctions.println( "Only supported for GroupedRowWindow panels: " + this.getClass().getSimpleName() );
- return;
- }
-
- new Thread( () ->
- {
- // get selected groups, filter missing views, get all present and selected vids
- final SpimData2 data = (SpimData2) panel.getSpimData();
- @SuppressWarnings("unchecked")
- FilteredAndGroupedExplorerPanel< SpimData2 > panelFG = (FilteredAndGroupedExplorerPanel< SpimData2 >) panel;
- SpimDataFilteringAndGrouping< SpimData2 > filteringAndGrouping = new SpimDataFilteringAndGrouping<>( (SpimData2) panel.getSpimData() );
-
- if (!expertGrouping.isSelected())
- {
- // use whatever is selected in panel as filters
- filteringAndGrouping.addFilters( panelFG.selectedRowsGroups().stream().reduce( new ArrayList<>(), (x,y ) -> {x.addAll( y ); return x;}) );
- }
- else
- {
- filteringAndGrouping.askUserForFiltering( panelFG );
- if (filteringAndGrouping.getDialogWasCancelled())
- return;
- }
-
- if (!expertGrouping.isSelected())
- {
- // get the grouping from panel and compare Tiles
- panelFG.getTableModel().getGroupingFactors().forEach( g -> filteringAndGrouping.addGroupingFactor( g ));
- filteringAndGrouping.addComparisonAxis( Tile.class );
-
- // compare by Channel if channels were ungrouped in UI
- if (!panelFG.getTableModel().getGroupingFactors().contains( Channel.class ))
- filteringAndGrouping.addComparisonAxis( Channel.class );
-
- // compare by Illumination if illums were ungrouped in UI
- if (!panelFG.getTableModel().getGroupingFactors().contains( Illumination.class ))
- filteringAndGrouping.addComparisonAxis( Illumination.class );
- }
- else
- {
- filteringAndGrouping.addComparisonAxis( Tile.class );
- filteringAndGrouping.askUserForGrouping( panelFG );
- if (filteringAndGrouping.getDialogWasCancelled())
- return;
- }
-
- boolean allViews2D = StitchingUIHelper.allViews2D( filteringAndGrouping.getFilteredViews() );
- if (allViews2D)
- {
- IOFunctions.println( "Interest point-based registration is currenty not supported for 2D: " + this.getClass().getSimpleName() );
- return;
- }
-
-
- if (Calculate_Pairwise_Shifts.processInterestPoint( data, filteringAndGrouping, existingInterestPoints ))
- if (wizardMode)
- {
- // ask user if they want to switch to preview mode
- if (panel instanceof StitchingExplorerPanel)
- {
- final int choice = JOptionPane.showConfirmDialog( (Component) panel, "Pairwise shift calculation done. Switch to preview mode?", "Preview Mode", JOptionPane.YES_NO_OPTION );
- if (choice == JOptionPane.YES_OPTION)
- {
- ((StitchingExplorerPanel< ? >) panel).setSavedFilteringAndGrouping( filteringAndGrouping );
- ((StitchingExplorerPanel< ? >) panel).togglePreviewMode(false);
- }
- }
- }
-
- }).start();
-
- panel.updateContent();
- }
- }
-
-}
diff --git a/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java b/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
index bc4058b..8a71b23 100644
--- a/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
+++ b/src/main/java/net/preibisch/stitcher/gui/popup/RefineWithICPPopup.java
@@ -32,6 +32,7 @@
import net.preibisch.legacy.io.IOFunctions;
import net.preibisch.mvrecon.fiji.plugin.interestpointregistration.global.GlobalOptimizationParameters;
+import net.preibisch.mvrecon.fiji.plugin.interestpointregistration.global.GlobalOptimizationParameters.PreAlign;
import net.preibisch.mvrecon.fiji.plugin.util.MouseOverPopUpStateChanger;
import net.preibisch.mvrecon.fiji.plugin.util.MouseOverPopUpStateChanger.StateChanger;
import net.preibisch.mvrecon.fiji.spimdata.SpimData2;
@@ -229,8 +230,6 @@ public void actionPerformed( ActionEvent e )
// remember for macro recording
ICPRefinement.defaultRefinementChoice = icpType.ordinal();
- final boolean preAlign = false;
- GlobalOptimizationParameters.defaultPrealign = preAlign;
GlobalOptimizationParameters globalOptParams;
if ( icpType == ICPType.Expert )
@@ -245,7 +244,7 @@ public void actionPerformed( ActionEvent e )
if ( !ICPRefinement.getGUIParametersSimple( icpType, data, params, downsamplingChoice, thresholdChoice, distanceChoice ) )
return;
- globalOptParams = GlobalOptimizationParameters.getGlobalOptimizationParametersForSelection( GlobalOptimizationParameters.defaultSimple, preAlign );
+ globalOptParams = GlobalOptimizationParameters.getGlobalOptimizationParametersForSelection( GlobalOptimizationParameters.defaultSimple, false );
}
if ( globalOptParams == null )
diff --git a/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java b/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
index 6ebd63b..c10c849 100644
--- a/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
+++ b/src/main/java/net/preibisch/stitcher/plugin/Calculate_Pairwise_Shifts.java
@@ -81,9 +81,7 @@ public class Calculate_Pairwise_Shifts implements PlugIn
private final static String[] methodChoices = {
"Phase Correlation",
- "Lucas-Kanade",
- "Interest-Point Registration (with existing Interest Points)",
- "Interest-Point Registration (with new Interest Points)"};
+ "Lucas-Kanade" };
private static boolean expertGrouping;
private static boolean expertAlgorithmParameters;
@@ -139,28 +137,20 @@ public void run(String arg)
grouping.getAxesOfComparison().addAll( defaultComparisonFactors );
}
- if (defaultMethodIdx >= 2)
+ grouping.askUserForGroupingAggregator();
+ final long[] ds = StitchingUIHelper.askForDownsampling( data, is2d );
+
+ if (defaultMethodIdx == 0) // Phase Correlation
{
- if (!processInterestPoint( data, grouping, defaultMethodIdx == 2 ))
+ PairwiseStitchingParameters params = expertAlgorithmParameters ? PairwiseStitchingParameters.askUserForParameters() : new PairwiseStitchingParameters();
+ if (!processPhaseCorrelation( data, grouping, params, ds ))
return;
}
- else
+ else if (defaultMethodIdx == 1) // Lucas-Kanade
{
- grouping.askUserForGroupingAggregator();
- final long[] ds = StitchingUIHelper.askForDownsampling( data, is2d );
-
- if (defaultMethodIdx == 0) // Phase Correlation
- {
- PairwiseStitchingParameters params = expertAlgorithmParameters ? PairwiseStitchingParameters.askUserForParameters() : new PairwiseStitchingParameters();
- if (!processPhaseCorrelation( data, grouping, params, ds ))
- return;
- }
- else if (defaultMethodIdx == 1) // Lucas-Kanade
- {
- LucasKanadeParameters params = expertAlgorithmParameters ? LucasKanadeParameters.askUserForParameters() : new LucasKanadeParameters( WarpFunctionType.TRANSLATION );
- if (!processLucasKanade( data, grouping, params, ds ))
- return;
- }
+ LucasKanadeParameters params = expertAlgorithmParameters ? LucasKanadeParameters.askUserForParameters() : new LucasKanadeParameters( WarpFunctionType.TRANSLATION );
+ if (!processLucasKanade( data, grouping, params, ds ))
+ return;
}
// update XML
@@ -269,199 +259,4 @@ public static boolean processLucasKanade(
return true;
}
-
- // TODO: remove interest points from BigStitcher entirely (except for ICP refinement)
- public static boolean processInterestPoint(final SpimData2 data,
- final SpimDataFilteringAndGrouping< SpimData2 > filteringAndGrouping,
- boolean existingInterestPoints)
- {
-
- // detect new interest points if requested
- if (!existingInterestPoints)
- {
- // by default the registration suggests what is selected in the dialog
- Interest_Point_Detection.defaultGroupTiles = filteringAndGrouping.getGroupingFactors().contains( Tile.class );
- Interest_Point_Detection.defaultGroupIllums = filteringAndGrouping.getGroupingFactors().contains( Illumination.class );
- new Interest_Point_Detection().detectInterestPoints( data, filteringAndGrouping.getFilteredViews() );
- }
-
- // by default the registration suggests what is selected in the dialog
- // (and was passed to filteringAndGrouping)
- Interest_Point_Registration.defaultGroupTiles = filteringAndGrouping.getGroupingFactors()
- .contains( Tile.class );
- Interest_Point_Registration.defaultGroupIllums = filteringAndGrouping.getGroupingFactors()
- .contains( Illumination.class );
- Interest_Point_Registration.defaultGroupChannels = filteringAndGrouping.getGroupingFactors()
- .contains( Channel.class );
-
- // which timepoints are part of the data (we dont necessarily need them,
- // but basicRegistrationParameters GUI wants them)
- List< ? extends ViewId > viewIds = filteringAndGrouping.getFilteredViews();
- final List< TimePoint > timepointToProcess = SpimData2.getAllTimePointsSorted( data, viewIds );
- final int nAllTimepoints = data.getSequenceDescription().getTimePoints().size();
-
- // query basic registration parameters
- final BasicRegistrationParameters brp = new Interest_Point_Registration().basicRegistrationParameters(
- timepointToProcess, nAllTimepoints, data, (List< ViewId >) viewIds );
- if ( brp == null )
- return false;
-
- // query algorithm parameters
- GenericDialog gd = new GenericDialog( "Registration Parameters" );
-
- gd.addMessage( "Algorithm parameters [" + brp.pwr.getDescription() + "]",
- new Font( Font.SANS_SERIF, Font.BOLD, 12 ) );
- gd.addMessage( "" );
-
- //brp.pwr.presetTransformationModel( new TransformationModelGUI( 0 ) );
- brp.pwr.addQuery( gd );
-
- gd.showDialog();
-
- if ( gd.wasCanceled() )
- return false;
- if ( !brp.pwr.parseDialog( gd ) )
- return false;
-
- // get all possible group pairs
- List< ? extends Pair< ? extends Group< ? extends ViewId >, ? extends Group< ? extends ViewId > > > pairs = filteringAndGrouping
- .getComparisons();
-
- // remove old results
- // this is just a cast of pairs to Group
- final List< ValuePair< Group< ViewId >, Group< ViewId > > > castPairs = pairs.stream().map( p -> {
- final Group< ViewId > vidGroupA = new Group<>(
- p.getA().getViews().stream().map( v -> (ViewId) v ).collect( Collectors.toSet() ) );
- final Group< ViewId > vidGroupB = new Group<>(
- p.getB().getViews().stream().map( v -> (ViewId) v ).collect( Collectors.toSet() ) );
- return new ValuePair<>( vidGroupA, vidGroupB );
- } ).collect( Collectors.toList() );
-
- for ( ValuePair< Group< ViewId >, Group< ViewId > > pair : castPairs )
- {
- // try to remove a -> b and b -> a, just to make sure
- data.getStitchingResults().getPairwiseResults().remove( pair );
- data.getStitchingResults().getPairwiseResults().remove( new ValuePair<>( pair.getB(), pair.getA() ) );
- }
-
- // remove non-overlapping comparisons
- final List< Pair< Group< ViewId >, Group< ViewId > > > removedPairs = TransformationTools
- .filterNonOverlappingPairs( (List< Pair< Group< ViewId >, Group< ViewId > > >) pairs,
- data.getViewRegistrations(), data.getSequenceDescription() );
- removedPairs
- .forEach( p -> System.out.println( "Skipping non-overlapping pair: " + p.getA() + " -> " + p.getB() ) );
-
- for ( final Pair< Group< ViewId >, Group< ViewId > > pair : (List< Pair< Group< ViewId >, Group< ViewId > > >) pairs )
- {
- // all views in group pair
- final HashSet< ViewId > vids = new HashSet< ViewId >();
- vids.addAll( pair.getA().getViews() );
- vids.addAll( pair.getB().getViews() );
-
- // simple PairwiseSetup with just two groups (fully connected to
- // each other)
- Set> groups = new HashSet<>();
- groups.add( pair.getA() );
- groups.add( pair.getB() );
- final PairwiseSetup< ViewId > setup = new PairwiseSetup< ViewId >( new ArrayList<>( vids ), groups )
- {
-
- @Override
- protected List< Pair< ViewId, ViewId > > definePairsAbstract()
- {
- // all possible links between groups
- final List< Pair< ViewId, ViewId > > res = new ArrayList<>();
- for ( final ViewId vidA : pair.getA() )
- for ( final ViewId vidB : pair.getB() )
- res.add( new ValuePair< ViewId, ViewId >( vidA, vidB ) );
- return res;
- }
-
- @Override
- public List< ViewId > getDefaultFixedViews()
- {
- // first group will remain fixed -> we get the transform to
- // align second group to this target
- return new ArrayList<>( pair.getA().getViews() );
- }
- };
-
- // prepare setup
- setup.definePairs();
- setup.detectSubsets();
-
- // get copies of view registrations (as they will be modified) and
- // interest points
- final Map< ViewId, ViewRegistration > registrationMap = new HashMap<>();
- final Map< ViewId, ViewInterestPointLists > ipMap = new HashMap<>();
- for ( ViewId vid : vids )
- {
- final ViewRegistration vrOld = data.getViewRegistrations().getViewRegistration( vid );
- final ViewInterestPointLists iplOld = data.getViewInterestPoints().getViewInterestPointLists( vid );
- registrationMap.put( vid, new ViewRegistration( vid.getTimePointId(), vid.getViewSetupId(),
- new ArrayList<>( vrOld.getTransformList() ) ) );
- ipMap.put( vid, iplOld );
- }
-
- final Interest_Point_Registration reg = new Interest_Point_Registration();
- // run the registration for this pair, skip saving results if it did not work
- if ( !reg.processRegistration(
- setup,
- data.getSequenceDescription().getViewSetups(),
- brp.pwr,
- InterestpointGroupingType.ADD_ALL,
- InterestPointOverlapType.ALL,
- 0.0,
- pair.getA().getViews(),
- null,
- null,
- registrationMap,
- data.getSequenceDescription().getViewDescriptions(),
- ipMap,
- brp.labelMap,
- new GlobalOptimizationParameters(Double.MAX_VALUE, Double.MAX_VALUE, GlobalOptType.ONE_ROUND_SIMPLE, true, false ),
- false, //matchacrosslabels
- true ) )
- continue;
-
- // get newest Transformation of groupB (the accumulative transform
- // determined by registration)
- final ViewTransform vtB = registrationMap.get( pair.getB().iterator().next() ).getTransformList().get( 0 );
-
- List< Pair< Pair< ViewId, ViewId >, ? extends PairwiseResult< ? > > > stats = reg.getStatistics();
-
- // TODO: is this correct?
- // since the grouped IP are split up again in the statistics, can we just sum inliers & candidates
- // to get the total cands/inliers. or are we counting some twice?
- double candidates = 0;
- double inliers = 0;
- for (final Pair< Pair< ViewId, ViewId >, ? extends PairwiseResult< ? > > stat : stats)
- {
- candidates += stat.getB().getCandidates().size();
- inliers += stat.getB().getInliers().size();
- }
-
-
- final AffineTransform3D result = new AffineTransform3D();
- result.set( vtB.asAffine3D().getRowPackedCopy() );
- IOFunctions.println( "resulting transformation: " + Util.printCoordinates( result.getRowPackedCopy() ) );
-
- // get Overlap Bounding Box, which we need for stitching results
- final List< List< ViewId > > groupListsForOverlap = new ArrayList<>();
- groupListsForOverlap.add( new ArrayList<>( pair.getA().getViews() ) );
- groupListsForOverlap.add( new ArrayList<>( pair.getB().getViews() ) );
- BoundingBoxMaximalGroupOverlap< ViewId > bbDet = new BoundingBoxMaximalGroupOverlap< ViewId >(
- groupListsForOverlap, data.getSequenceDescription(), data.getViewRegistrations() );
- BoundingBox bbOverlap = bbDet.estimate( "Max Overlap" );
-
- final double oldTransformHash = PairwiseStitchingResult.calculateHash(
- data.getViewRegistrations().getViewRegistration( pair.getA().getViews().iterator().next() ),
- data.getViewRegistrations().getViewRegistration( pair.getA().getViews().iterator().next() ) );
- data.getStitchingResults().getPairwiseResults().put( pair,
- new PairwiseStitchingResult<>( pair, bbOverlap, result, inliers/candidates, oldTransformHash ) );
- }
-
- return true;
- }
-
}
diff --git a/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java b/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
index dbad5c2..aef72d2 100644
--- a/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
+++ b/src/main/java/net/preibisch/stitcher/plugin/Global_Optimization_Stitching.java
@@ -35,6 +35,7 @@
import mpicbg.spim.data.sequence.ViewId;
import net.imglib2.util.Pair;
import net.preibisch.mvrecon.fiji.plugin.interestpointregistration.global.GlobalOptimizationParameters;
+import net.preibisch.mvrecon.fiji.plugin.interestpointregistration.global.GlobalOptimizationParameters.PreAlign;
import net.preibisch.mvrecon.fiji.plugin.queryXML.LoadParseQueryXML;
import net.preibisch.mvrecon.fiji.spimdata.SpimData2;
import net.preibisch.mvrecon.fiji.spimdata.XmlIoSpimData2;
@@ -66,7 +67,7 @@ public void run(String arg)
final HashSet< Class< ? extends Entity > > defaultComparisonFactors = new HashSet<>();
defaultComparisonFactors.add( Tile.class );
- GlobalOptimizationParameters params = GlobalOptimizationParameters.askUserForParameters(true, true /*prealign*/);
+ GlobalOptimizationParameters params = GlobalOptimizationParameters.askUserForParameters( true, PreAlign.ASK );
if (params.showExpertGrouping)
grouping.askUserForGrouping(
From 5d6a8d198d9ef30559ab0b1c2719d6a6774ee1c2 Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Wed, 5 Nov 2025 11:11:42 -0500
Subject: [PATCH 5/6] update multiview-reconstruction version to 8.1.0
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 1eab942..a09652f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,7 +120,7 @@
1.5.0
-->
- 7.0.8-SNAPSHOT
+ 8.1.0
1.0.2
1.6.5
From 067118b9fd44c19ae371bc399e0081b176c4c1b7 Mon Sep 17 00:00:00 2001
From: Stephan Preibisch
Date: Wed, 5 Nov 2025 13:24:54 -0500
Subject: [PATCH 6/6] use mvr 8.1.1
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index a09652f..a5487c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,7 +120,7 @@
1.5.0
-->
- 8.1.0
+ 8.1.1
1.0.2
1.6.5