Class AlgorithmFuzzyCMeans
- All Implemented Interfaces:
ActionListener,WindowListener,Runnable,EventListener
Segmentation divides an image into distinct classes or types, such as segmenting the brain into 3 tissue types: gray matter, white matter, and cerebrospinal fluid. There are 2 types of segmentation: hard and soft or fuzzy. In hard segmentation a pixel is simply assigned to 1 of the classes. However, often in medical images, there cannot be absolute classification of a pixel because of partial volume effects where multiple tissues contribute to a pixel or voxel causing intensity blurring across boundaries. Fuzzy segmentation allows for the uncertainty in the location of object boundaries. In fuzzy segmentation a membership function exists for each class at every pixel location. At each pixel location a class membership function will have a value of 0 if there is absolutely no chance of that pixel belonging to the class. At each pixel location a class membership function will have a value of 1 if the pixel belongs to the class with absolute certainty. Membership functions can vary from 0 to 1, with the constraint that at any pixel location the sum of the membership functions of all the classes must add up to 1. The fuzzy membership function reflects the similarity between the data value at that pixel and the value of the class centroid. As a pixel data value becomes closer to the class centroid, the class membership function approaches unity.
The fuzzy C-Means algorithm is an unsupervised method; it works without the use of training data. This algorithm, allowing for soft segmentation based on fuzzy set theory, generalizes the K-means algorithm. The technique clusters data by iteratively computing a fuzzy membrship function and mean value estimates for each tissue class. The algorithm works by minimizing the sum over all pixels j and all classes k of: (ujk**q) * ((yj - vk)**2)
nClass = number of classes. ujk is the membership value at pixel location j for class k such that that sum over k from k = 1 to k = nClass for ujk = 1. q is a weighing exponent on each membership value and determines the amount of "fuzziness" of the resulting segmentation. q is required to be greater than 1 and is typically set to 2. yj is the observed single channel image intensity at location j. vk is the centroid of class k.
The user provides initial centroid values or simply uses default evenly spread pixel values generated by:
for (i = 0; i invalid input: '<' nClass; i++)
centroid[i] = minimum + (maximum - minimum)*(i + 1)/(nClass + 1);
Minimization is achieved by an interative process which:
1.)Computes the membership functions using a current estimate of the centroids.
numerator = (yj - vk)**(-2/(q-1))
denominator = Sum over l from l = 1 to l = nClass of (yj - vl)**(-2/(q-1))
ujk = numerator/denominator for all pixels j and all classes k
2.) Computes the centroids using current estimates of the membership functions.
numerator = sum over all pixels j of (ujk**q) * yj
denominator = sum over all pixels j of (ujk**q)
vk = numerator/denominator for all classes k
The iteration continues until either the user specified maximum number of iterations has occcured or until convergence has been detected. Convergence occurs when all membership functions over all pixel locations j change by less than the tolerance value between 2 iterations. The default maximum iteration number is 100. The default tolerance is 0.01.
The initial dialog asks the user for a signal threshold value. The default value is the image minimum value. In the centroid calculation only those pixels whose values equal or exceed threshold are used in the centroid calculaton. In the hard segmentation pixels whose values are less than threshold or not in a selected VOI if the whole image is not used are set to a segmentation value of 0, meaning that these pixels are outside of the specified classes.
The initial dialog has a checkbox for Boundary noise cropping which is unchecked by default. This function finds the smallest bounding box outside of which all image pixel values are below the image threshold. Values inside the bounding box are copied to a smaller array to save space and calculations are performed with this reduced array. However, these pixels outside the box are restored for the production of the hard and fuzzy segmented images. In the hard and fuzzy segmentation cases values outside the box all have a value of 0. If the cropping checkbox is selected, the user is constrained to select whole image rather than VOI region(s).
There are 3 choices for produced output images:
1.) HARD ONLY
2.) FUZZY ONLY
3.) HARD invalid input: '&' FUZZY BOTH
Hard segmentation produces only 1 unsigned byte output image which assigns pixels which do not meet threshold requirements values of 0. The first class is assigned a value of 1, the second class is assigned a pixel value of 2, and so on. The last class has a value of nClass.
Fuzzy segmentation produces 1 image of floating point type for every segmentation class. The values ranges from 0.0 to 1.0. If boundary cropping is used, pixels outside the bounding box are all assigned the value 0.0.
The signal threshold value is entered on the initial dialog and the image centroids are entered on a later dialog.
Image Types:
This algorithm can be applied to 2D and 3D data sets that are not color or COMPLEX.
References: This code is a ported subset of C-code written and kindly provided by Dzung Pham. Note that our code
is not the adaptive fuzzy C-means segmentation, which the Dzung Pham code is. Our code is not adaptive - it does not
correct intensity inhomogeneities, also known as shading artifacts.
1.) Dzung L. Pham, Chenyang Xu, and Jerry L. Prince, "A Survey of Current Methods in Medical Image Segmentation",
Department of Electrical and Computer Engineering, The Johns Hopkins University, Baltimore, Maryland, 21218,
Technical Report JHU/ECE 99-01.
2.) Alberto F. Goldszal and Dzung L. Pham, "Volumetric Segmentation", Chapter 12, Academic Press, copyright 2000.
3.) Dzung L. Pham and Jerry L. Prince, "Adaptive Fuzzy Segmentation of Magnetic Resonance Images", IEEE Transactions
on Medical Imaging, Vol. 18, No. 9, September, 1999, pp. 737 - 752.
- Version:
- 0.1 June 15, 2000 conversion of Dzung Pham's C code
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class java.lang.Thread
Thread.Builder, Thread.State, Thread.UncaughtExceptionHandler -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final floatDOCUMENT ME!static final intpossible values for segmentation.private float[]DOCUMENT ME!private float[]DOCUMENT ME!private int[]DOCUMENT ME!private booleanDOCUMENT ME!private ModelImage[]Fuzzy images require 1 image for each class Hard images 1 image with assigned clusters.private intDOCUMENT ME!private double1/(qValue - 1).static final intDOCUMENT ME!static final intDOCUMENT ME!private intDOCUMENT ME!private intjacobiIters1 and jacobiIter2 are only used with gain correction.private intstatic final floatDOCUMENT ME!private floatDOCUMENT ME!private intDOCUMENT ME!private float[]DOCUMENT ME!private float[]DOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private BitSetDOCUMENT ME!private float[]DOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private booleanprivate booleanDOCUMENT ME!private intpyramidLevels is only used with gain correction.private doubleDOCUMENT ME!private float[]DOCUMENT ME!private byte[]DOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!private floatsmooth1 and smooth2 are only used with gain field correction.private floatprivate floatDOCUMENT ME!private floatDOCUMENT ME!private boolean[]DOCUMENT ME!private intDOCUMENT ME!private booleanwholeImage is constrained to be true if background cropping is selected.private intDOCUMENT ME!private intDOCUMENT ME!private intDOCUMENT ME!Fields inherited from class gov.nih.mipav.model.algorithms.AlgorithmBase
destFlag, image25D, mask, maxProgressValue, minProgressValue, multiThreadingEnabled, nthreads, progress, progressModulus, progressStep, runningInSeparateThread, separable, srcImage, threadStoppedFields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionAlgorithmFuzzyCMeans(ModelImage[] destImg, ModelImage srcImg, int _nClass, int _pyramidLevels, int _jacobiIters1, int _jacobiIters2, float _q, float _smooth1, float _smooth2, boolean _outputGainField, int _segmentation, boolean _cropBackground, float _threshold, int _max_iter, float _tolerance, boolean _wholeImage) Creates a new AlgorithmFuzzyCMeans object.AlgorithmFuzzyCMeans(ModelImage srcImg, int _nClass, int _pyramidLevels, int _jacobiIters1, int _jacobiIters2, float _q, float _smooth1, float _smooth2, boolean _outputGainField, int _segmentation, boolean _cropBackground, float _threshold, int _max_iter, float _tolerance, boolean _wholeImage) Creates a new AlgorithmFuzzyCMeans object. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidcleanUp()Cleans up the memory usage.private voidcMeans2()DOCUMENT ME!private voidcMeans3()cMeans3.private voidcomputeCentroids2D(float[] buffer, float[] centroids, float[] mems) Determines the centroids of each cluster given fuzzy membership values.private voidcomputeCentroids3D(float[] buffer) Determines the centroids of each cluster given fuzzy membership values.private voidcomputeMemberships2D(float[] buffer, float[] centroids, float[] mems, double exponent) Determines the membership of each feature vector in each cluster.private voidcomputeMemberships3D(float[] buffer) Determines the membership of each feature vector in each cluster.voidfinalize()Prepares this class for destruction.voidStarts the algorithm.voidsetCentroids(float[] cent) Accessor to set the centroids.Methods inherited from class gov.nih.mipav.model.algorithms.AlgorithmBase
actionPerformed, addListener, addProgressChangeListener, calculateImageSize, calculatePrincipleAxis, computeElapsedTime, computeElapsedTime, convertIntoFloat, delinkProgressToAlgorithm, delinkProgressToAlgorithmMulti, displayError, errorCleanUp, fireProgressStateChanged, fireProgressStateChanged, fireProgressStateChanged, fireProgressStateChanged, fireProgressStateChanged, generateProgressValues, getDestImage, getElapsedTime, getMask, getMaxProgressValue, getMinProgressValue, getNumberOfThreads, getProgress, getProgressChangeListener, getProgressChangeListeners, getProgressModulus, getProgressStep, getProgressValues, getSrcImage, isCompleted, isImage25D, isMultiThreadingEnabled, isRunningInSeparateThread, isThreadStopped, linkProgressToAlgorithm, linkProgressToAlgorithm, makeProgress, notifyListeners, removeListener, removeProgressChangeListener, run, setCompleted, setImage25D, setMask, setMaxProgressValue, setMinProgressValue, setMultiThreadingEnabled, setNumberOfThreads, setProgress, setProgressModulus, setProgressStep, setProgressValues, setProgressValues, setRunningInSeparateThread, setSrcImage, setStartTime, setThreadStopped, startMethod, windowActivated, windowClosed, windowClosing, windowDeactivated, windowDeiconified, windowIconified, windowOpenedMethods inherited from class java.lang.Thread
activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, isVirtual, join, join, join, join, ofPlatform, ofVirtual, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, sleep, start, startVirtualThread, stop, suspend, threadId, toString, yield
-
Field Details
-
BOTH_FUZZY_HARD
public static final int BOTH_FUZZY_HARDpossible values for segmentation.- See Also:
-
FUZZY_ONLY
public static final int FUZZY_ONLYDOCUMENT ME!- See Also:
-
HARD_ONLY
public static final int HARD_ONLYDOCUMENT ME!- See Also:
-
MAX_FLOAT
public static final float MAX_FLOATDOCUMENT ME!- See Also:
-
ALPHA
public static final float ALPHADOCUMENT ME!- See Also:
-
buffer2
private float[] buffer2DOCUMENT ME! -
centroids
private float[] centroidsDOCUMENT ME! -
classNumber
private int[] classNumberDOCUMENT ME! -
cropBackground
private boolean cropBackgroundDOCUMENT ME! -
destImage
Fuzzy images require 1 image for each class Hard images 1 image with assigned clusters. -
destNum
private int destNumDOCUMENT ME! -
exponent
private double exponent1/(qValue - 1). -
iterations
private int iterationsDOCUMENT ME! -
jacobiIters1
private int jacobiIters1jacobiIters1 and jacobiIter2 are only used with gain correction. -
jacobiIters2
private int jacobiIters2 -
maxChange
private float maxChangeDOCUMENT ME! -
maxIter
private int maxIterDOCUMENT ME! -
mems
private float[] memsDOCUMENT ME! -
memsBuffer
private float[] memsBufferDOCUMENT ME! -
memSize
private int memSizeDOCUMENT ME! -
nClass
private int nClassDOCUMENT ME! -
newSliceSize
private int newSliceSizeDOCUMENT ME! -
newXDim
private int newXDimDOCUMENT ME! -
newYDim
private int newYDimDOCUMENT ME! -
newZDim
private int newZDimDOCUMENT ME! -
objMask
DOCUMENT ME! -
oldMember
private float[] oldMemberDOCUMENT ME! -
oldX
private int oldXDOCUMENT ME! -
oldY
private int oldYDOCUMENT ME! -
oldZ
private int oldZDOCUMENT ME! -
orgSlice
private int orgSliceDOCUMENT ME! -
orgVol
private int orgVolDOCUMENT ME! -
orgXDim
private int orgXDimDOCUMENT ME! -
outputGainField
private boolean outputGainField -
powEIntFlag
private boolean powEIntFlagDOCUMENT ME! -
pyramidLevels
private int pyramidLevelspyramidLevels is only used with gain correction. -
qValue
private double qValueDOCUMENT ME! -
sCentroids
private float[] sCentroidsDOCUMENT ME! -
segBuffer
private byte[] segBufferDOCUMENT ME! -
segmentation
private int segmentationDOCUMENT ME! -
sliceSize
private int sliceSizeDOCUMENT ME! -
smooth1
private float smooth1smooth1 and smooth2 are only used with gain field correction. -
smooth2
private float smooth2 -
threshold
private float thresholdDOCUMENT ME! -
tolerance
private float toleranceDOCUMENT ME! -
unusedCentroids
private boolean[] unusedCentroidsDOCUMENT ME! -
volSize
private int volSizeDOCUMENT ME! -
wholeImage
private boolean wholeImagewholeImage is constrained to be true if background cropping is selected. -
xDim
private int xDimDOCUMENT ME! -
yDim
private int yDimDOCUMENT ME! -
zDim
private int zDimDOCUMENT ME!
-
-
Constructor Details
-
AlgorithmFuzzyCMeans
public AlgorithmFuzzyCMeans(ModelImage srcImg, int _nClass, int _pyramidLevels, int _jacobiIters1, int _jacobiIters2, float _q, float _smooth1, float _smooth2, boolean _outputGainField, int _segmentation, boolean _cropBackground, float _threshold, int _max_iter, float _tolerance, boolean _wholeImage) Creates a new AlgorithmFuzzyCMeans object.- Parameters:
srcImg- source image model_nClass- number of classes into which the image will be segmented_pyramidLevels- Not used in the present version of the code_jacobiIters1- Not used in the present version of the code_jacobiIters2- Not used in the present version of the code_q- a weighing exponent on each membership value and determines the amount of "fuzziness" of the resulting segmentation. q is required to be greater than 1 and is typically set to 2._smooth1- Not used in the present version of the code_smooth2- Not used in the present version of the code_outputGainField- Not used in the present version of the code_segmentation- possible values are hard only, fuzzy only, or both hard and fuzzy_cropBackground- unchecked by default. This function finds the smallest bounding box outside of which all image pixel values are below the image threshold. Values inside the bounding box are copied to a smaller array to save space and calculations are performed with this reduced array. However, these pixels outside the box are restored for the production of the hard and fuzzy segmented images. In the hard and fuzzy segmentation cases values outside the box all have a value of 0._threshold- The default value is the image minimum value. In the centroid calculation only those pixels whose values equal or exceed threshold are used in the centroid calculaton. In the hard segmentation pixels whose values are less than threshold or not in a selected VOI if the whole image is not used are set to a segmentation value of 0, meaning that these pixels are outside of the specified classes._max_iter- Maximum allowed iterations of main program loop_tolerance- The iteration continues until either the user specified maximum number of iterations has occcured or until convergence has been detected. Convergence occurs when all membership functions over all pixel locations j change byless than the tolerance value between 2 iterations._wholeImage- If true apply algorithm to the whole image - constrained to be true if background cropping is selected. If false, only apply to VOI regions.
-
AlgorithmFuzzyCMeans
public AlgorithmFuzzyCMeans(ModelImage[] destImg, ModelImage srcImg, int _nClass, int _pyramidLevels, int _jacobiIters1, int _jacobiIters2, float _q, float _smooth1, float _smooth2, boolean _outputGainField, int _segmentation, boolean _cropBackground, float _threshold, int _max_iter, float _tolerance, boolean _wholeImage) Creates a new AlgorithmFuzzyCMeans object.- Parameters:
destImg- list of image models where result image is to storedsrcImg- source image model_nClass- number of classes into which the image will be segmented_pyramidLevels- Not used in the present version of the code_jacobiIters1- Not used in the present version of the code_jacobiIters2- Not used in the present version of the code_q- a weighing exponent on each membership value and determines the amount of "fuzziness" of the resulting segmentation. q is required to be greater than 1 and is typically set to 2._smooth1- Not used in the present version of the code_smooth2- Not used in the present version of the code_outputGainField- Not used in the present version of the code_segmentation- possible values are hard only, fuzzy only, or both hard and fuzzy_cropBackground- unchecked by default. This function finds the smallest bounding box outside of which all image pixel values are below the image threshold. Values inside the bounding box are copied to a smaller array to save space and calculations are performed with this reduced array. However, these pixels outside the box are restored for the production of the hard and fuzzy segmented images. In the hard and fuzzy segmentation cases values outside the box all have a value of 0._threshold- The default value is the image minimum value. In the centroid calculation only those pixels whose values equal or exceed threshold are used in the centroid calculaton. In the hard segmentation pixels whose values are less than threshold or not in a selected VOI if the whole image is not used are set to a segmentation value of 0, meaning that these pixels are outside of the specified classes._max_iter- Maximum allowed iterations of main program loop_tolerance- The iteration continues until either the user specified maximum number of iterations has occcured or until convergence has been detected. Convergence occurs when all membership functions over all pixel locations j change byless than the tolerance value between 2 iterations._wholeImage- If true apply algorithm to the whole image - constrained to be true if background cropping is selected. If false, only apply to VOI regions.
-
-
Method Details
-
finalize
public void finalize()Prepares this class for destruction.- Overrides:
finalizein classAlgorithmBase
-
runAlgorithm
public void runAlgorithm()Starts the algorithm.- Specified by:
runAlgorithmin classAlgorithmBase
-
setCentroids
public void setCentroids(float[] cent) Accessor to set the centroids.- Parameters:
cent- Centroids to set.
-
cleanUp
private void cleanUp()Cleans up the memory usage. -
cMeans2
private void cMeans2()DOCUMENT ME! -
cMeans3
private void cMeans3()cMeans3. -
computeCentroids2D
private void computeCentroids2D(float[] buffer, float[] centroids, float[] mems) Determines the centroids of each cluster given fuzzy membership values.- Parameters:
buffer- DOCUMENT ME!centroids- DOCUMENT ME!mems- DOCUMENT ME!
-
computeCentroids3D
private void computeCentroids3D(float[] buffer) Determines the centroids of each cluster given fuzzy membership values.- Parameters:
buffer- DOCUMENT ME!
-
computeMemberships2D
private void computeMemberships2D(float[] buffer, float[] centroids, float[] mems, double exponent) Determines the membership of each feature vector in each cluster.- Parameters:
buffer- DOCUMENT ME!centroids- DOCUMENT ME!mems- DOCUMENT ME!exponent- DOCUMENT ME!
-
computeMemberships3D
private void computeMemberships3D(float[] buffer) Determines the membership of each feature vector in each cluster.- Parameters:
buffer- DOCUMENT ME!
-