Class AlgorithmEdgeNMSuppression

java.lang.Object
java.lang.Thread
gov.nih.mipav.model.algorithms.AlgorithmBase
gov.nih.mipav.model.algorithms.AlgorithmEdgeNMSuppression
All Implemented Interfaces:
AlgorithmInterface, ActionListener, WindowListener, Runnable, EventListener

public class AlgorithmEdgeNMSuppression extends AlgorithmBase implements AlgorithmInterface
Calculates the non-maximum suppression of an image at a scale defined by the user. This algorithm produces an edge map of the zero crossings of the non-maximum suppression for 2D images and 2.5D images. Edges are defined as the union of points for which the gradient magnitude assumes a maximum in the gradient direction. Introuduce a local orthonormal coordinate system (u,v) at any point P0, where the v-axis is parallel to the gradient direction at P0, and the u-axis is perpindicular. Iu = sin(a)*Ix - cos(a)*Iy Iv = cos(a)*Ix + sin(a)*Iy cos(a) = Ix/(sqrt(Ix*Ix + Iy*Iy)) evaluated at P0 sin(a) = Iy/(sqrt(Ix*Ix + Iy*Iy)) evaluated at P0 Iu = (Ix*Iy - Ix*Iy)/(sqrt(Ix*Ix + Iy*Iy)) = 0 Iv = (Ix*Ix + Iy*Iy)/(sqrt(Ix*Ix + Iy*Iy)) = sqrt(Ix*Ix + Iy*Iy) Iv*Iv = Ix*Ix + Iy*Iy Ivv = (cos(a)*Ix + sin(a)*Iy)(cos(a)*Ix + sin(a)*Iy) = cos(a)*cos(a)*Ixx + 2*cos(a)*sin(a)*Ixy + sin(a)*sin(a)*Iyy = (Ix*Ix*Ixx + 2*Ix*Iy*Ixy + Iy*Iy*Iyy)/(Ix*Ix + Iy*Iy) Iv*Iv*Ivv = Ix*Ix*Ixx + 2*Ix*Iy*Ixy + Iy*Iy*Iyy Ivvv = (cos(a)*cos(a)*Ixx + 2*cos(a)*sin(a)*Ixy + sin(a)*sin(a)*Iyy)(cos(a)*Ix + sin(a)*Iy) = cos(a)*cos(a)*cos(a)*Ixxx + 3*cos(a)*cos(a)*sin(a)*Ixxy + 3*cos(a)*sin(a)*sin(a)*Ixyy + sin(a)*sin(a)*sin(a)*Iyyy = (Ix*Ix*Ix*Ixxx + 3*Ix*Ix*Iy*Ixxy + 3*Ix*Iy*Iy*Ixyy + Iy*Iy*Iy*Iyyy)/((Ix*Ix + Iy*Iy)**3/2) Iv*Iv*Iv*Ivvv = Ix*Ix*Ix*Ixxx + 3*Ix*Ix*Iy*Ixxy + 3*Ix*Iy*Iy*Ixyy + Iy*Iy*Iy*Iyyy Assuming that the second and third-order directional derivatives of I in the v-direction are not simultaneously zero, a necessary and sufficient condition for P0 to be a gradient maximum in the gradient direction may be stated as: Ivv = 0, Ivvv invalid input: '<' 0. Since only the sign information is important, this condition can be restated as: Iv*Iv*Ivv = 0, Iv*Iv*Iv*Ivvv invalid input: '<' 0. Reference: Geometry-Driven Diffusion in Computer Vision, Bart M. ter Haar Romeny(Ed.), Chapter2:Linear Scale-Space II: Early Visual Operations by Tony Lindeberg and Bart M. ter Haar Romeny, Kluwer Academic Publishers, 1994, page 45.

For 3D a similar derivation: Iv = cos(a)*sin(b)*Ix + sin(a)*sin(b)*Iy + cos(b)*Iz where spherical coordinates are being used cos(a) = Ix/(sqrt(Ix*Ix + Iy*Iy)) evaluated at P0 sin(a) = Iy/(sqrt(Ix*Ix + Iy*Iy)) evaluated at P0 cos(b) = Iz/(sqrt(Ix*Ix + Iy*Iy + Iz*Iz)) evaluated at P0 sin(b) = sqrt(Ix*Ix + Iy*Iy)/(sqrt(Ix*Ix + Iy*Iy + Iz*Iz)) evaluated at P0 Iv = (Ix*Ix + Iy*Iy + Iz*Iz)/(sqrt(Ix*Ix + Iy*Iy + Iz*Iz)) = sqrt(Ix*Ix + Iy*Iy + Iz*Iz) Iv*Iv = Ix*Ix + Iy*Iy + Iz*Iz Ivv = (cos(a)*sin(b)*Ix + sin(a)*sin(b)*Iy + cos(b)*Iz)(cos(a)*sin(b)*Ix + sin(a)*sin(b)*Iy + cos(b)*Iz) = cos(a)*cos(a)*sin(b)*sin(b)*Ixx + 2*cos(a)*sin(a)*sin(b)*sin(b)*Ixy + 2*cos(a)*cos(b)*sin(b)*Ixz + sin(a)*sin(a)*sin(b)*sin(b)*Iyy + 2*sin(a)*cos(b)*sin(b)*Iyz + cos(b)*cos(b)*Izz = (Ix*Ix*Ixx + 2*Ix*Iy*Ixy + 2*Ix*Iz*Ixz + Iy*Iy*Iyy + 2*Iy*Iz*Iyz + Iz*Iz*Izz)/ (Ix*Ix + Iy*Iy + Iz*Iz) Iv*Iv*Ivv = Ix*Ix*Ixx + 2*Ix*Iy*Ixy + 2*Ix*Iz*Ixz + Iy*Iy*Iyy + 2*Iy*Iz*Iyz + Iz*Iz*Izz Ivvv = (cos(a)*cos(a)*sin(b)*sin(b)*Ixx + 2*cos(a)*sin(a)*sin(b)*sin(b)*Ixy + 2*cos(a)*cos(b)*sin(b)*Ixz + sin(a)*sin(a)*sin(b)*sin(b)*Iyy + 2*sin(a)*cos(b)*sin(b)*Iyz + cos(b)*cos(b)*Izz)(cos(a)*sin(b)*Ix + sin(a)*sin(b)*Iy + cos(b)*Iz) = cos(a)*cos(a)*cos(a)*sin(b)*sin(b)*sin(b)*Ixxx + 3*cos(a)*cos(a)*sin(a)*sin(b)*sin(b)*sin(b)*Ixxy + 3*cos(a)*cos(a)*cos(b)*sin(b)*sin(b)*Ixxz + 3*cos(a)*sin(a)*sin(a)*sin(b)*sin(b)*sin(b)*Ixyy + 6*cos(a)*sin(a)*cos(b)*sin(b)*sin(b)*Ixyz + 3*cos(a)*cos(b)*cos(b)*sin(b)*Ixzz + sin(a)*sin(a)*sin(a)*sin(b)*sin(b)*sin(b)*Iyyy + 3*sin(a)*sin(a)*cos(b)*sin(b)*sin(b)*Iyyz + 3*sin(a)*cos(b)*cos(b)*sin(b)*Iyzz + cos(b)*cos(b)*cos(b)*Izzz = (Ix*Ix*Ix*Ixxx + 3*Ix*Ix*Iy*Ixxy + 3*Ix*Ix*Iz*Ixxz + 3*Ix*Iy*Iy*Ixyy + 6*Ix*Iy*Iz*Ixyz + 3*Ix*Iz*Iz*Ixzz + Iy*Iy*Iy*Iyyy + 3*Iy*Iy*Iz*Iyyz + 3*Iy*Iz*Iz*Iyzz + Iz*Iz*Iz*Izzz)/ ((Ix*Ix + Iy*Iy + Iz*Iz)**1.5) Iv*Iv*Iv*Ivvv = Ix*Ix*Ix*Ixxx + 3*Ix*Ix*Iy*Ixxy + 3*Ix*Ix*Iz*Ixxz + 3*Ix*Iy*Iy*Ixyy + 6*Ix*Iy*Iz*Ixyz + 3*Ix*Iz*Iz*Ixzz + Iy*Iy*Iy*Iyyy + 3*Iy*Iy*Iz*Iyyz + 3*Iy*Iz*Iz*Iyzz + Iz*Iz*Iz*Izzz

  • Field Details

    • MARCHING_SQUARES

      public static final int MARCHING_SQUARES
      Perform zero crossing detection using the marching squares method.
      See Also:
    • OLD_DETECTION

      public static final int OLD_DETECTION
      Perform zero crossing detection using Matt's old method.
      See Also:
    • entireImage

      private boolean entireImage
      DOCUMENT ME!
    • GxData

      private float[] GxData
      DOCUMENT ME!
    • GxxData

      private float[] GxxData
      DOCUMENT ME!
    • GxxxData

      private float[] GxxxData
      DOCUMENT ME!
    • GxxyData

      private float[] GxxyData
      DOCUMENT ME!
    • GxxzData

      private float[] GxxzData
      DOCUMENT ME!
    • GxyData

      private float[] GxyData
      DOCUMENT ME!
    • GxyyData

      private float[] GxyyData
      DOCUMENT ME!
    • GxyzData

      private float[] GxyzData
      DOCUMENT ME!
    • GxzData

      private float[] GxzData
      DOCUMENT ME!
    • GxzzData

      private float[] GxzzData
      DOCUMENT ME!
    • GyData

      private float[] GyData
      DOCUMENT ME!
    • GyyData

      private float[] GyyData
      DOCUMENT ME!
    • GyyyData

      private float[] GyyyData
      DOCUMENT ME!
    • GyyzData

      private float[] GyyzData
      DOCUMENT ME!
    • GyzData

      private float[] GyzData
      DOCUMENT ME!
    • GyzzData

      private float[] GyzzData
      DOCUMENT ME!
    • GzData

      private float[] GzData
      DOCUMENT ME!
    • GzzData

      private float[] GzzData
      DOCUMENT ME!
    • GzzzData

      private float[] GzzzData
      DOCUMENT ME!
    • kExtents

      private int[] kExtents
      DOCUMENT ME!
    • sigmas

      private float[] sigmas
      DOCUMENT ME!
    • zeroDetectionType

      private int zeroDetectionType
      The type of zero crossing detection to use.
    • zXMask

      private ModelImage zXMask
      DOCUMENT ME!
    • outputBuffer

      private float[] outputBuffer
  • Constructor Details

    • AlgorithmEdgeNMSuppression

      public AlgorithmEdgeNMSuppression(ModelImage destImg, ModelImage srcImg, float[] sigmas, boolean maskFlag, boolean img25D)
      Creates a new AlgorithmEdgeNMSuppression object.
      Parameters:
      destImg - image model where result image is to stored
      srcImg - source image model
      sigmas - Gaussian's standard deviations in the each dimension
      maskFlag - Flag that indicates that the EdgeNMSup will be calculated for the whole image if equal to true
      img25D - Flag, if true, indicates that each slice of the 3D volume should be processed independently. 2D images disregard this flag.
  • Method Details

    • genLevelMask

      public static BitSet genLevelMask(int xDim, int yDim, float[] buffer, float level, int detectionType)
      Generates a zero crossing mask for a 2D function sets a Bitset object to 1 is a zero crossing is detected.
      Parameters:
      xDim - the buffer's x dimension
      yDim - the buffer's y dimension
      buffer - array in which to find zero crossing
      level - the level to find the crossing of (usually will be 0)
      detectionType - the type of zero crossing method to use
      Returns:
      DOCUMENT ME!
    • finalize

      public void finalize()
      Prepares this class for destruction.
      Overrides:
      finalize in class AlgorithmBase
    • genZeroXMask

      public void genZeroXMask(int slice, float[] buffer, float[] buffer2, int detectionType)
      Generates a zero crossing mask for a 2D function sets a ModelImage to 255 if a zero crossing is detected.
      Parameters:
      slice - DOCUMENT ME!
      buffer - array in which to find zero crossing
      buffer2 - array which ensures that zero crossing is only counted if buffer2 value at that position is less than zero
      detectionType - the type of zero crossing detection to perform
    • getZeroXMask

      public ModelImage getZeroXMask()
      Accessor to return mask indicating zero crossings.
      Returns:
      ModelImage of zero crossings (2D function); 255 = indicates zero crossing
    • runAlgorithm

      public void runAlgorithm()
      Starts the program.
      Specified by:
      runAlgorithm in class AlgorithmBase
    • calcStoreInDest2D

      private void calcStoreInDest2D(int nImages, int detectionType)
      This function produces the EdgeNMSup of input image.
      Parameters:
      nImages - number of images to be blurred. If 2D image then nImage = 1, if 3D image where each image is to processed independently then nImages equals the number of images in the volume.
      detectionType - the type of zero crossing detection to perform
    • calcStoreInDest3D

      private void calcStoreInDest3D(int detectionType)
      This function produces the Non-maximum suppression of input image.
      Parameters:
      detectionType - the type of zero crossing detection to perform
    • makeKernels2D

      private void makeKernels2D()
      Creates Gaussian derivative kernels.
    • makeKernels3D

      private void makeKernels3D()
      Creates Gaussian derivative kernels.
    • algorithmPerformed

      public void algorithmPerformed(AlgorithmBase algorithm)
      Description copied from interface: AlgorithmInterface
      Called after an algorithm this listener is registered to exits (maybe successfully, maybe not). If the algorithm is run in a separate thread, this call will be made within that thread. If not, this call will be made from that same, shared thread.
      Specified by:
      algorithmPerformed in interface AlgorithmInterface
      Parameters:
      algorithm - the algorithm which has just completed