Class AlgorithmEdgeNMSuppression

  • All Implemented Interfaces:
    AlgorithmInterface, java.awt.event.ActionListener, java.awt.event.WindowListener, java.lang.Runnable, java.util.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 < 0. Since only the sign information is important, this condition can be restated as: Iv*Iv*Ivv = 0, Iv*Iv*Iv*Ivvv < 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 Detail

      • MARCHING_SQUARES

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

        public static final int OLD_DETECTION
        Perform zero crossing detection using Matt's old method.
        See Also:
        Constant Field Values
      • 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.
      • outputBuffer

        private float[] outputBuffer
    • Constructor Detail

      • 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 Detail

      • genLevelMask

        public static java.util.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
      • 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