001 /* 002 * MatrixCreator 003 * 004 * Copyright (c) 2001, 2002, 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.analysis; 009 010 import net.sourceforge.jiu.data.Gray8Image; 011 import net.sourceforge.jiu.data.IntegerImage; 012 import net.sourceforge.jiu.data.Paletted8Image; 013 import net.sourceforge.jiu.color.data.CoOccurrenceMatrix; 014 import net.sourceforge.jiu.color.data.CoOccurrenceFrequencyMatrix; 015 import net.sourceforge.jiu.color.data.MemoryCoOccurrenceMatrix; 016 import net.sourceforge.jiu.color.data.MemoryCoOccurrenceFrequencyMatrix; 017 018 /** 019 * This class creates and initializes co-occurrence matrices and co-occurrence 020 * frequency matrices. 021 * @author Marco Schmidt 022 */ 023 public class MatrixCreator 024 { 025 private MatrixCreator() 026 { 027 } 028 029 public static CoOccurrenceMatrix createCoOccurrenceMatrix(Gray8Image image) 030 { 031 return createCoOccurrenceMatrix(image, 0); 032 } 033 034 public static CoOccurrenceMatrix createCoOccurrenceMatrix(Paletted8Image image) 035 { 036 return createCoOccurrenceMatrix(image, 0); 037 } 038 039 public static CoOccurrenceMatrix createCoOccurrenceMatrix(IntegerImage image, int channelIndex) 040 { 041 if (image == null) 042 { 043 throw new IllegalArgumentException("The image must non-null."); 044 } 045 if (channelIndex < 0) 046 { 047 throw new IllegalArgumentException("The channel index must be zero or larger."); 048 } 049 if (channelIndex >= image.getNumChannels()) 050 { 051 throw new IllegalArgumentException("The channel index must be smaller than the number of channels in the image (" + image.getNumChannels() + ")."); 052 } 053 int dim = image.getMaxSample(channelIndex) + 1; 054 MemoryCoOccurrenceMatrix matrix = new MemoryCoOccurrenceMatrix(dim); 055 initCoOccurrenceMatrix(image, channelIndex, matrix); 056 return matrix; 057 } 058 059 /** 060 * Initializes a co-occurrence matrix from the input image, using the <em>direct</em> 061 * four neighbor pixels. 062 * The number of entries in the palette of the argument image must be equal to the dimension 063 * of the argument matrix. 064 * @param image the image that will be used to initialize the matrix 065 * @param matrix the matrix that will first be cleared and then initialized from the image 066 * @throws IllegalArgumentException if at least one of the arguments is null or if the 067 * palette size is not equal to the matrix dimension 068 */ 069 public static void initCoOccurrenceMatrix(IntegerImage image, int channelIndex, CoOccurrenceMatrix matrix) 070 { 071 if (image == null) 072 { 073 throw new IllegalArgumentException("The image must non-null."); 074 } 075 if (channelIndex < 0) 076 { 077 throw new IllegalArgumentException("The channel index must be zero or larger."); 078 } 079 if (channelIndex >= image.getNumChannels()) 080 { 081 throw new IllegalArgumentException("The channel index must be smaller than the number of channels in the image (" + image.getNumChannels() + ")."); 082 } 083 int dim = image.getMaxSample(channelIndex) + 1; 084 if (matrix == null) 085 { 086 throw new IllegalArgumentException("The matrix must non-null."); 087 } 088 if (matrix.getDimension() != dim) 089 { 090 throw new IllegalArgumentException("Dimension of matrix (" + 091 matrix.getDimension() + " must be exactly one larger than " + 092 "maximum sample value (" + (dim - 1) + ")."); 093 } 094 matrix.clear(); 095 int maxX = image.getWidth() - 1; 096 int maxY = image.getHeight() - 1; 097 for (int y = 0; y <= maxY; y++) 098 { 099 for (int x = 0; x <= maxX; x++) 100 { 101 int index = image.getSample(channelIndex, x, y); 102 if (x > 0) 103 { 104 int leftNeighbor = image.getSample(channelIndex, x - 1, y); 105 matrix.incValue(index, leftNeighbor); 106 } 107 if (x < maxX) 108 { 109 int rightNeighbor = image.getSample(channelIndex, x + 1, y); 110 matrix.incValue(index, rightNeighbor); 111 } 112 if (y > 0) 113 { 114 int topNeighbor = image.getSample(channelIndex, x, y - 1); 115 matrix.incValue(index, topNeighbor); 116 } 117 if (y < maxY) 118 { 119 int bottomNeighbor = image.getSample(channelIndex, x, y + 1); 120 matrix.incValue(index, bottomNeighbor); 121 } 122 } 123 } 124 } 125 126 /** 127 * Creates a new co-occurrence frequency with the same dimension as the argument co-occurrence 128 * matrix, calls {@link #initCoOccurrenceFrequencyMatrix} with them to initialize the new matrix, 129 * then returns it. 130 * A {@link MemoryCoOccurrenceFrequencyMatrix} is created. 131 * @param A the co-occurrence matrix from which the resulting matrix will be initialized 132 * @return the newly-created co-occurrence frequency matrix 133 * @throws IllegalArgumentException if the argument matrix is null 134 */ 135 public static CoOccurrenceFrequencyMatrix createCoOccurrenceFrequencyMatrix(final CoOccurrenceMatrix A) 136 { 137 if (A == null) 138 { 139 throw new IllegalArgumentException("Matrix argument must be non-null."); 140 } 141 int dimension = A.getDimension(); 142 MemoryCoOccurrenceFrequencyMatrix matrix = new MemoryCoOccurrenceFrequencyMatrix(dimension); 143 initCoOccurrenceFrequencyMatrix(A, matrix); 144 return matrix; 145 } 146 147 /** 148 * Initializes a co-occurrence frequency matrix from a co-occurrence matrix. 149 * The two argument matrices must be non-null and have the same dimension. 150 * @param A co-occurrence matrix used as input 151 * @param cofm co-occurrence matrix, will be initialized by this method 152 * @throws IllegalArgumentException if either matrix is null or if the dimensions are not equal 153 */ 154 public static void initCoOccurrenceFrequencyMatrix(final CoOccurrenceMatrix A, CoOccurrenceFrequencyMatrix cofm) 155 { 156 if (A == null) 157 { 158 throw new IllegalArgumentException("Co-occurrence matrix A argument must not be null."); 159 } 160 if (cofm == null) 161 { 162 throw new IllegalArgumentException("Co-occurrence frequency matrix cofm argument must not be null."); 163 } 164 final int DIMENSION = A.getDimension(); 165 if (DIMENSION != cofm.getDimension()) 166 { 167 throw new IllegalArgumentException("Dimension of matrices A (" + 168 DIMENSION + ") and cofm (" + cofm.getDimension() + ") must " + 169 "be equal."); 170 } 171 cofm.clear(); 172 double totalSum = 0.0; 173 for (int i = 0; i < DIMENSION; i++) 174 { 175 // first sum up A[i, k], k = 0..dimension-1 176 double sum = 0.0; 177 for (int k = 0; k < DIMENSION; k++) 178 { 179 sum += A.getValue(i, k); 180 } 181 totalSum += sum; 182 for (int j = 0; j < DIMENSION; j++) 183 { 184 double value = A.getValue(i, j); 185 double result; 186 if (sum == 0.0) 187 { 188 result = 0.0; 189 } 190 else 191 { 192 result = value / sum; 193 } 194 cofm.setValue(i, j, result); 195 } 196 } 197 cofm.computeStatistics(); 198 } 199 }