88 * it under the terms of the GNU General Public License as
99 * published by the Free Software Foundation, either version 3 of the
1010 * License, or (at your option) any later version.
11- *
11+ *
1212 * This program is distributed in the hope that it will be useful,
1313 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1414 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515 * GNU General Public License for more details.
16- *
16+ *
1717 * You should have received a copy of the GNU General Public
1818 * License along with this program. If not, see
1919 * <http://www.gnu.org/licenses/gpl-3.0.html>.
2323
2424import static fiji .plugin .trackmate .tracking .overlap .OverlapTrackerFactory .BASE_ERROR_MESSAGE ;
2525
26+ import java .awt .Color ;
2627import java .util .ArrayList ;
2728import java .util .Arrays ;
2829import java .util .Collections ;
@@ -213,7 +214,7 @@ public boolean process()
213214 for ( final Spot target : targetGeometries .keySet () )
214215 {
215216 final Polygon2D targetPoly = targetGeometries .get ( target );
216- futures .add ( executors .submit ( new FindBestSourceTask ( target , targetPoly , sourceGeometries , minIoU ) ) );
217+ futures .add ( executors .submit ( new FindBestSourceTask ( target , targetPoly , sourceGeometries , minIoU , enlargeFactor , logger ) ) );
217218 }
218219
219220 // Get results.
@@ -345,12 +346,18 @@ private static final class FindBestSourceTask implements Callable< IoULink >
345346
346347 private final double minIoU ;
347348
348- public FindBestSourceTask ( final Spot target , final Polygon2D targetPoly , final Map < Spot , Polygon2D > sourceGeometries , final double minIoU )
349+ private final double scale ;
350+
351+ private final Logger logger ;
352+
353+ public FindBestSourceTask ( final Spot target , final Polygon2D targetPoly , final Map < Spot , Polygon2D > sourceGeometries , final double minIoU , final double scale , final Logger logger )
349354 {
350355 this .target = target ;
351356 this .targetPoly = targetPoly ;
352357 this .sourceGeometries = sourceGeometries ;
353358 this .minIoU = minIoU ;
359+ this .scale = scale ;
360+ this .logger = logger ;
354361 }
355362
356363 @ Override
@@ -362,7 +369,36 @@ public IoULink call() throws Exception
362369 for ( final Spot spot : sourceGeometries .keySet () )
363370 {
364371 final Polygon2D sourcePoly = sourceGeometries .get ( spot );
365- final double intersection = Math .abs ( Polygons2D .intersection ( targetPoly , sourcePoly ).area () );
372+ double intersection ;
373+ try
374+ {
375+ intersection = Math .abs ( Polygons2D .intersection ( targetPoly , sourcePoly ).area () );
376+ }
377+ catch ( final NullPointerException e )
378+ {
379+ /*
380+ * Sometimes the intersection computation fails with NPE.
381+ * The code crashes here:
382+ *
383+ * https://github.com/ChristianLutz/gpcj/blob/master/gpcj/
384+ * src/main/java/com/seisw/util/geom/Clip.java#L1604
385+ *
386+ * The issue is not with the polygons, they are good. It's a
387+ * bug in the Clip algorithm that doesn't handle certain
388+ * edge cases.
389+ *
390+ * When this happens, we catch the error, and compute an
391+ * approximation of the intersection with the bounding
392+ * boxes.
393+ */
394+ logger .log ( "Error trying to compute intersection between spots "
395+ + spot .ID () + " and " + target .ID () + "\n "
396+ + "Approximating with the bounding box.\n " , Color .ORANGE .darker () );
397+ final Rectangle2D sourceRectangle = toBoundingBox ( spot , scale );
398+ final Rectangle2D targetRectangle = toBoundingBox ( target , scale );
399+ final Polygon2D approxIntersection = Polygons2D .intersection ( sourceRectangle , targetRectangle );
400+ intersection = Math .abs ( approxIntersection .area () );
401+ }
366402 if ( intersection == 0. )
367403 continue ;
368404
0 commit comments