Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
188 lines (148 sloc) 10.5 KB

⬅️

What the heck is GLCM? Code it to understand!

Hey!

Textural features in images has been for long in computer vision [1]. Understanding it and analyzing are useful for diverse applications, varying from geological sattelite pictures to medical imaging. Similarly, working on biomedical image analysis from time to time, I have recently stumbled upon a task to quantify texture given a region of interest. In different tissues, and statuses (healthy/abnormal), texture of segmented region of interest can vary, with some regions seem more uniform, while others are harsh. If further quantified, this parameter can be useful for classification purposes or monitoring of pharmacological treatment effectiveness. In the example given below, we consider MRI image of glioblastoma case. Image data is collected before operation is done, and afterwards. Even though, human can qualitatively see differences in the images between left and right, in research, people would rather go for quantitative approach.

MRI of Pre and Post operative

PrePostCancer

One may suggest intensity parameter as critical feature. I partly agree, however, there are several restrictions with using it. For example, scattering from media or varying illumination can affect grayscale image ranges a lot, and also, since it mostly depends on imaging modality used, it has to be tuned. With texture, intensity IS still important, however, texture analysis is fundamentally based on analysing neighbourhoods in general, which is derived from intensities. Specifically, more of interest are the frequency with which given gray level occurs in image, and the closeness of neighbour pixels with exactly same gray levels.

To analyze these kinds of things, GLCM, which stands for Gray-Level Co-Occurrence Matrix, is very convenient. Constructed GLCM matrix denotes occurences of pixels. And later, GLCM functions can be applied to examine spatial relationships of pixels in image in a statistical way. The results of these functions have certain numerical ranges. For uniform and harsh textures, these values usually take opposite ranges. So, there are basically to steps in texture analysis with GLCM:

  1. Calculate Gray-Level Co-Occurrence Matrix from image
  2. Get statistics of GLCM (ex: Contrast, Energy or Uniformity, Homogeneity)

So, let's advance into simple example:

1. Gray-Level Co-Occurrence Matrix

In our case, we will start from simple matrix, since every image, basically, can be analyzed as stack of 2D matrices. We have 4x5 matrix:

A = [1 1 5 6 8
    2 3 5 7 1
    4 5 7 1 2
    8 5 1 2 5];

[A_m, A_n] = size(A);

Let's find minimal and maximal values over all matrix:

A_max = max(A(:));
A_min = min(A(:));

In this matrix, min(A(:)) is 1 and max(A(:)) is 8. Therefore, our co-occurence matrix will be of size 8x8:

GLCM = zeros(A_max+1-A_min,A_max+1-A_min);
[m_length, n_length] = size(GLCM);

Now, we iterate through all rows and all columns to find neighbours the matching pairs. If matching pairs are found, they are accumulated into final value. That is how, GLCM matrix is created:

for m = 1:m_length 	% Iterate rows of GLCM
    for n = 1:n_length 	% Iterate cols of GLCM
        count_occ = 0; 	% Initialize co-occurences
        for i = 1:A_m 	% Iterate rows of original matrix
            for j = 1:A_n-1 	% Iterate cols of original matrix
                if (A(i,j) == m) & (A(i,j+1) == n) 	% If neighbours are matched pairs
                    count_occ = count_occ + 1; 	% Accumulate value of co-occurences
                end
            end
        end
        GLCM(m,n) = count_occ; 	% Insert value to corresponding position of GLCM 
    end
end

Let's check calculated GLCM:

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

So, to make sure calculated results are correct, we can compare our result with the output from built-in MATLAB function graycomatrix like this [2]:

glcms = graycomatrix(A,'GrayLimits',[]);

if glcms == GLCM
    disp('GLCM is correct!');
else
    disp('Hmm... Something went wrong!');
end

% If command window returns 'GLCM is correct!', you are perfectly fine!

2. Statistics of GLCM: Calculating contrast, energy (uniformity), homogeneity

By the rule, statistical features are calculated from normalized GLCM matrix. In this regards, we first create normalized version of GLCM:

GLCM_norm = zeros(size(GLCM));
GLCM_norm = GLCM./sum(GLCM(:));

After we get normalized GLCM matrix, we will request results of exactly same parameters from built-in MATLAB function graycoprops to compare later [2]:

stats = graycoprops(glcms,{'contrast','energy','homogeneity'});
tol = 0.0001;

In the table below, a few of the most popular GLCM features are listed with their definitions and formulas, that we will use in our code:

Parameter Definition Formula
Contrast Shows intensity contrast between a pixel and its neighbor over the all image. Contrast equals 0 for a constant image.

Energy (Uniformity) The sum of squared elements in the GLCM matrix. Energy equals 1 for a constant image.

Homogeneity Shows closeness of the distribution of elements in the GLCM to the diagonal of GLCM. Homogeneity equals 1 for a diagonal GLCM.

where is the -th entry of the normalized GLCM, that is where is the -th entry of the computed GLCM; is the total number of gray levels in the image

Contrast

contrast_ = 0;

for s = 1:m_length
    for p = 1:n_length
        contrast_ = contrast_ + ((s-p)^2)*GLCM_norm(s,p);
    end
end

%% Checking correctness:
areEssentiallyEqual = abs(contrast_ - stats.Contrast) < tol;

if areEssentiallyEqual
    disp('GLCM contrast is correct!');
else
    disp('Hmm... Something went wrong!');
end

% If command window returns 'GLCM contrast is correct!', you are perfectly fine!

Energy

%% Calculating Uniformity (Energy):
uniformity_ = 0;

for s = 1:m_length
    for p = 1:n_length
        uniformity_ = uniformity_ + GLCM_norm(s,p)^2;
    end
end

%% Checking correctness
areEssentiallyEqual = abs(uniformity_ - stats.Energy) < tol;

if areEssentiallyEqual
    disp('GLCM uniformity is correct!');
else
    disp('Hmm... Something went wrong!');
end

% If command window returns 'GLCM uniformity is correct!', you are perfectly fine!

Homogeneity

%% Calculating Homogeneity:
homogeneity_ = 0;

for s = 1:m_length
    for p = 1:n_length
        h_val = GLCM_norm(s,p)/(1+abs(s-p));
        homogeneity_ = homogeneity_ + h_val;
    end
end

%% Checking correctness
areEssentiallyEqual = abs(homogeneity_ - stats.Homogeneity) < tol;

if areEssentiallyEqual
    disp('GLCM homogeneity is correct!');
else
    disp('Hmm... Something went wrong!');
end

% If command window returns 'GLCM homogeneity is correct!', you are perfectly fine!

Conclusion

Here, we worked out how Gray-Level Co-Occurrence Matrix can be derived programmatically. We also briefly looked on the definition of statistical parameters of GLCM, such as, contrast, energy and homogeneity. After having mathematical concepts, MATLAB code is provided for calculation of these parameters. Finally, we made sure the correctness of the calculated parameters with our code by checking whether they are equal to the results, which can be obtained from built-in functions. If you feel you need more information, I recommend the following further reading materials [3].

Usefull references:

[1] This is a pioneering paper. Useful for general understanding.
Haralick (1973). Textual Features for Image Classification, IEEE Trans Syst Man Cybern

[2] Documentation of MATLAB functions to create gray-level co-occurrence matrix from image: graycomatrix, and to get its properties with graycoprops

[3] Additional material on the topic: [Link 1], [Link 2], [Link 3]

You can’t perform that action at this time.