📄 algorithms.fuzzycmeans.fuzzycmeansimageclustering.java
字号:
(numClusters*width*height*(2*numBands)) // Step 3 of method run() ); } /** * This method returns a measure of the progress of the algorithm. */ public long getPosition() { return position; } /** * This method returns true if the clustering has finished. */ public boolean isFinished() { return (position == getSize()); } /** * This method will return a rank image, i.e. an image which pixels are * the cluster centers of the Nth best choice for the classification. * For example, if the membership functions for a pixel of an image * clustered with six clusters are [0.10 0.25 0.40 0.20 0.03 0.02] and we * ask for the image with rank 2 (ranks starts with zero), for that pixel * the third best choice for cluster index will be selected (0.20) and the * centers of the cluster with index 3 will be used. * It is important to notice that this method can be called while the * clustering task (method run) is running, and the resulting image is not * guaranteed to be close to a clustered result. * @param rank the desired rank for the classification. * @return a TiledImage with the classification results considering that rank. */ public TiledImage getRankedImage(int rank) { // Create a SampleModel for the output data (same number of bands as the input image). SampleModel sampleModel = RasterFactory.createBandedSampleModel(DataBuffer.TYPE_INT,width,height,numBands); // Create a WritableRaster using that sample model. WritableRaster raster = RasterFactory.createWritableRaster(sampleModel,new Point(0,0)); // A pixel array will contain all bands for a specific x,y. int[] pixelArray = new int[numBands]; // For all pixels in the image... for(int h=0;h<height;h++) for(int w=0;w<width;w++) { // Get the class (cluster center) for that pixel with the specified rank. int aCluster = getRankedIndex(membership[w][h],rank); // Fill the array with that cluster center. for(int band=0;band<numBands;band++) pixelArray[band] = (int)clusterCenters[aCluster][band]; // Put it on the raster. raster.setPixel(w,h,pixelArray); } // Set the raster on the output image. TiledImage pOutput = new TiledImage(pInput,false); pOutput.setData(raster); return pOutput; } /** * This method will return a membership function image, i.e. an image which * pixels correspond to the membership functions for the cluster which is * the Nth best choice for the classification. * For example, if the membership functions for a pixel of an image * clustered with six clusters are [0.10 0.25 0.40 0.20 0.03 0.02] and we * ask for the membership function image with rank 2 (ranks starts with * zero), for that pixel the third best membership function will be * selected (0.20) and used (scaled by 255) as the pixel value. * It is important to notice that this method can be called while the * clustering task (method run) is running, and the resulting image is not * guaranteed to be close to a clustered result. * @param rank the desired rank for the classification. * @return a TiledImage with the membership function value results * considering that rank. */ public TiledImage getRankedMFImage(int rank) { // Create a SampleModel for the output data (1 band only). SampleModel sampleModel = RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width,height,1); // Create a compatible ColorModel. ColorModel colorModel = PlanarImage.createColorModel(sampleModel); // Create a WritableRaster. WritableRaster raster = RasterFactory.createWritableRaster(sampleModel,new Point(0,0)); // For all pixels in the image... for(int h=0;h<height;h++) for(int w=0;w<width;w++) { // Get the membership function (considering the rank) for that pixel. int aCluster = (int)(255*getRankedMF(membership[w][h],rank)); // Put it on the raster. raster.setPixel(w,h,new int[]{aCluster}); } // Set the raster on the output image. TiledImage pOutput = new TiledImage(0,0,width,height,0,0,sampleModel,colorModel); pOutput.setData(raster); return pOutput; } /** * This method returns the ranked index of a cluster from an array * containing the membership functions. * For example, if the array contains [0.10 0.25 0.40 0.20 0.03 0.02] * and we ask for index with rank 2 (ranks starts with zero), the third * best choice will be selected (0.20) and its index (3) will be returned. * @param data the array with the membership functions. * @param rank the rank of the cluster we want to get. * @return the index of the cluster. */ private int getRankedIndex(float[] data,int rank) { // Create temporary arrays for the indexes and the data. int[] indexes = new int[data.length]; float[] tempData = new float[data.length]; // Fill those arrays. for(int i=0;i<indexes.length;i++) { indexes[i] = i; tempData[i] = data[i]; } // Sort both arrays together, using data as the sorting key. for(int i=0;i<indexes.length-1;i++) for(int j=i;j<indexes.length;j++) { if (tempData[i] < tempData[j]) { int tempI= indexes[i]; indexes[i] = indexes[j]; indexes[j] = tempI; float tempD = tempData[i]; tempData[i] = tempData[j]; tempData[j] = tempD; } } // Return the cluster index for the rank we want. return indexes[rank]; } /** * This method returns the ranked membership function of a cluster from an * array containing the membership functions. * For example, if the array contains [0.10 0.25 0.40 0.20 0.03 0.02] and * we ask for the MF with rank 2 (ranks starts with zero), the third best * choice will be selected (0.20) and returned. * @param data the array with the membership functions. * @param rank the rank of the cluster we want to get. * @return the MF with that rank. */ private float getRankedMF(float[] data,int rank) { // Create temporary arrays for the indexes and the data. int[] indexes = new int[data.length]; float[] tempData = new float[data.length]; // Fill those arrays. for(int i=0;i<indexes.length;i++) { indexes[i] = i; tempData[i] = data[i]; } // Sort both arrays together, using data as the sorting key. for(int i=0;i<indexes.length-1;i++) for(int j=i;j<indexes.length;j++) { if (tempData[i] < tempData[j]) { int tempI= indexes[i]; indexes[i] = indexes[j]; indexes[j] = tempI; float tempD = tempData[i]; tempData[i] = tempData[j]; tempData[j] = tempD; } } // Return the cluster index for the rank we want. return tempData[rank]; } /** * This method returns the Partition Coefficient measure of cluster validity * (see Fuzzy Algorithms With Applications to Image Processing and Pattern * Recognition, Zheru Chi, Hong Yan, Tuan Pham, World Scientific, pp. 91) */ public double getPartitionCoefficient() { double pc = 0; // For all data values and clusters for(int h=0;h<height;h++) for(int w=0;w<width;w++) for(int c=0;c<numClusters;c++) pc += membership[w][h][c]*membership[w][h][c]; pc = pc/(height*width); return pc; } /** * This method returns the Partition Entropy measure of cluster validity * (see Fuzzy Algorithms With Applications to Image Processing and Pattern * Recognition, Zheru Chi, Hong Yan, Tuan Pham, World Scientific, pp. 91) */ public double getPartitionEntropy() { double pe = 0; // For all data values and clusters for(int h=0;h<height;h++) for(int w=0;w<width;w++) for(int c=0;c<numClusters;c++) pe += membership[w][h][c]*Math.log(membership[w][h][c]); pe = -pe/(height*width); return pe; } /** * This method returns the Compactness and Separation measure of cluster validity * (see Fuzzy Algorithms With Applications to Image Processing and Pattern * Recognition, Zheru Chi, Hong Yan, Tuan Pham, World Scientific, pp. 93) */ public double getCompactnessAndSeparation() { double cs = 0; // For all data values and clusters for(int h=0;h<height;h++) for(int w=0;w<width;w++) { // Get the current pixel data. int index = (h*width+w)*numBands; for(int b=0;b<numBands;b++) aPixel[b] = inputData[index+b]; for(int c=0;c<numClusters;c++) { // Calculate the distance between a pixel and a cluster center. float distancePixelToCluster = calcSquaredDistance(aPixel,clusterCenters[c]); cs += membership[w][h][c]*membership[w][h][c]* distancePixelToCluster*distancePixelToCluster; } } cs /= (height*width); // Calculate minimum distance between ALL clusters float minDist = Float.MAX_VALUE; for(int c1=0;c1<numClusters-1;c1++) for(int c2=c1+1;c2<numClusters;c2++) { float distance = calcSquaredDistance(clusterCenters[c1],clusterCenters[c2]); minDist = Math.min(minDist,distance); } cs = cs/(minDist*minDist); return cs; } /** * This method calculates the squared distance between two N-dimensional * vectors. * @param a1 the first data vector. * @param a2 the second data vector. * @return the squared distance between those vectors. */ private float calcSquaredDistance(float[] a1,float[] a2) { float distance = 0f; for(int e=0;e<a1.length;e++) distance += (a1[e]-a2[e])*(a1[e]-a2[e]); return (float)distance; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -