Search code examples
javaimage-processingfeature-extractionglcm

How to compute the co-occurrence matrix in Java?


I have a question about the co-occurrence formula. How can I implement in Java the calculation of the GLCM of an image?

Concretely, I'm trying to figure out how to compute the number of times a pixel has intensity x and the pixel at its immediate right has intensity y. I also need to store the obtained value in the x-th row and y-th column of the resulting co-occurrence matrix.

The expected behavior is shown below:

GLCM Alghoritm

Here's what I got so far:

CODE (NOT complete yet)

public class MainClass {
final static int[][] matrix= {
        {2,4,1,3},
        {7,2,1,6},
        {1,1,2,2},
        {1,2,5,8}
};
static int i;
static int j;
static int x;
static int y;
static int c;
static int d;
static int maxValue = matrix[0][0];
static int minValue = matrix[0][0];

public static void main(String[] args) {
    // TODO Auto-generated method stub

    for(i = 0; i< matrix.length; i++) {
        for(j=0; j < matrix[i].length; j++) {
            System.out.print(matrix[i][j] + "");
            if(matrix[i][j] > maxValue) {
                maxValue=matrix[i][j];
            }
            else if(matrix[i][j] < minValue) {
                minValue=matrix[i][j];
            }                               
        }
        System.out.println();
    }       
    System.out.println("maxValue = "+ maxValue);

    int count = 0;
    for(int i=0; i< matrix.length; i++) {
        for (int j=0; j<matrix[i].length; j++) {
             int x = i;
             int y = j;
             if(matrix[x][y] == 1 & matrix[x][y+1] ==1) {
                 count ++;
             }
             System.out.println(matrix[x][y+1]);
        }
    }
}

OUTPUT (ERROR)

2413
7216
1122
1258
maxValue = 8
4
1
3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
 at main.MainClass.main(MainClass.java:45)

I would prefer not to use third-party libraries such as OpenCV or jfeaturelib.


Solution

  • This code gets the job done:

    public class MainClass {
    
        final static int[][] I = {
            {1, 1, 5, 6, 8},
            {2, 3, 5, 7, 1},
            {4, 5, 7, 1, 2},
            {8, 5, 1, 2, 5}
        };
    
        public static int getMaxValue(int[][] array) {
            int maxValue = array[0][0];
            for (int i = 0; i < array.length; i++) {
                for (int j = 0; j < array[i].length; j++) {
                    if (array[i][j] > maxValue) {
                        maxValue = array[i][j];
                    }
                }
            }
            return maxValue;
        }
    
        static int maxValue = getMaxValue(I);
    
        public static void main(String[] args) {
    
            System.out.println("I");
            for (int row = 0; row < I.length; row++) {
                for (int col = 0; col < I[row].length; col++) {
                    System.out.print(I[row][col] + " ");
                }
                System.out.println();
            }
    
            System.out.println("maxValue = " + maxValue);
    
            int[][] GLCM = new int[maxValue + 1][maxValue + 1];
    
            for (int row = 0; row < I.length; row++) {
                for (int col = 0; col < I[row].length - 1; col++) {
                    int x = I[row][col];
                    int y = I[row][col + 1];
                    GLCM[x][y]++;
                }
            }
    
            System.out.println("GLCM");
            for (int x = 1; x <= maxValue; x++) {
                for (int y = 1; y <= maxValue; y++) {
                    System.out.print(GLCM[x][y] + " ");
                }
                System.out.println();
            }
        }
    }
    

    Output

    I
    1 1 5 6 8 
    2 3 5 7 1 
    4 5 7 1 2 
    8 5 1 2 5 
    maxValue = 8
    GLCM
    1 2 0 0 1 0 0 0 
    0 0 1 0 1 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 1 0 0 0 
    1 0 0 0 0 1 2 0 
    0 0 0 0 0 0 0 1 
    2 0 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0
    

    Notes

    1. I'm assuming that the minimum intensity is 1. If you wish to consider pixels with an intensity value of 0 you should change the last two for loops like this:

      for (int x = 0; x <= maxValue; x++) {
          for (int y = 0; y <= maxValue; y++) {
      
    2. The proposed solution yields the cooccurrence matrix corresponding to the displacement vector "one pixel to the right". If you wish to compute the GLCM using a different displacement vector you'll need to tweak the code. For example, the following snippet returns the GLCM corresponding to "one pixel offset upwards":

      for (int row = 1; row < I.length; row++) {
          for (int col = 0; col < I[row].length; col++) {
              int x = I[row][col];
              int y = I[row - 1][col];
              GLCM[x][y]++;
          }
      }