001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009package Ch23_Image_Matching; 010 011import ij.IJ; 012import ij.ImagePlus; 013import ij.gui.GenericDialog; 014import ij.plugin.filter.PlugInFilter; 015import ij.process.FloatProcessor; 016import ij.process.ImageProcessor; 017import imagingbook.common.ij.DialogUtils; 018import imagingbook.common.ij.IjUtils; 019import imagingbook.common.image.matching.DistanceTransform; 020import imagingbook.core.jdoc.JavaDocHelp; 021import imagingbook.sampleimages.GeneralSampleImage; 022 023/** 024 * <p> 025 * Demonstrates the use of the {@link DistanceTransform} class. See Sec. 23.2.3 of [1] for details. Optionally opens a 026 * sample image if no image is currently open. The active image is assumed to be binary (not checked). 027 * </p> 028 * <p> 029 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing – An Algorithmic Introduction</em>, 3rd ed, Springer 030 * (2022). 031 * </p> 032 * 033 * @author WB 034 * @version 2022/12/13 035 * @see DistanceTransform 036 */ 037public class Show_Distance_Map implements PlugInFilter, JavaDocHelp { 038 039 private static DistanceTransform.DistanceType distanceNorm = DistanceTransform.DistanceType.L1; 040 041 private ImagePlus im; 042 043 /** 044 * Constructor, asks to open a predefined sample image if no other image is currently open. 045 */ 046 public Show_Distance_Map() { 047 if (IjUtils.noCurrentImage()) { 048 DialogUtils.askForSampleImage(GeneralSampleImage.RhinoSmallInv); 049 } 050 } 051 052 @Override 053 public int setup(String arg, ImagePlus im) { 054 this.im = im; 055 return DOES_8G + NO_CHANGES; 056 } 057 058 @Override 059 public void run(ImageProcessor ip) { 060 IJ.log("run"); 061 if (!runDialog()) { 062 return; 063 } 064 065 DistanceTransform dt = new DistanceTransform(ip, distanceNorm); 066 FloatProcessor dtIp = new FloatProcessor(dt.getDistanceMap()); 067 (new ImagePlus("Distance Transform of " + im.getShortTitle(), dtIp)).show(); 068 } 069 070 private boolean runDialog() { 071 GenericDialog gd = new GenericDialog(this.getClass().getSimpleName()); 072 gd.addHelp(getJavaDocUrl()); 073 if (im.isInvertedLut()) { 074 gd.setInsets(0, 0, 0); 075 gd.addMessage("NOTE: Image has inverted LUT (0 = white)!"); 076 } 077 gd.addEnumChoice("Distance norm", distanceNorm); 078 079 gd.showDialog(); 080 if (gd.wasCanceled()) 081 return false; 082 083 distanceNorm = gd.getNextEnumChoice(DistanceTransform.DistanceType.class); 084 return true; 085 } 086 087}