Files
scikit-image/skimage/feature/greycomatrix.py
T

113 lines
3.6 KiB
Python

"""
Compute grey level co-occurrence matrices (GLCM) to characterize
image textures.
"""
import numpy as np
import skimage.util
def glcm(image, distances, angles, levels=256, symmetric=False,
normal=False):
"""Calculate the grey-level co-occurrence matrix of a grey-level
image.
A grey level co-occurence matrix is a histogram of co-occuring
greyscale values at a given offset over an image. It can be used to
extract features from textured areas of an image.
Parameters
----------
image : (M,N) ndarray
Input image. The input image is converted to the uint8 data
type.
distances : (K,) ndarray
Histogram distance offsets
angles : (L,) ndarray
Histogram angles in radians
levels : int
The input image should contain integers in [0, levels-1],
where levels indicate the number of grey-levels counted
(typically 256 for an 8-bit image).
symmetric : bool
If True, the output matrix P is symmetric. This is accomplished
by ignoring the order of value pairs, so both (i, j) and (j, i)
are accumulated when (i, j) is encountered.
normal : bool
If True, normalize the result by dividing by the number of
possible outcomes
Returns
-------
P : 4-dimensional ndarray
The grey-level co-occurrence histogram. The value
P[i,j,d,theta] is the number of times that grey-level j
occurs at a distance d and at an angle theta from
grey-level i.
Examples
--------
Compute 2 GLCMs: One for a 1-pixel offset to the right, and one
for a 1-pixel offset upwards.
>>> image = np.array([[0, 0, 1, 1],
... [0, 0, 1, 1],
... [0, 2, 2, 2],
... [2, 2, 3, 3]], dtype=np.uint8)
>>> result = glcm(image, [1], [0, np.pi/2], 4)
>>> result[:, :, 0, 0]
array([[2, 2, 1, 0],
[0, 2, 0, 0],
[0, 0, 3, 1],
[0, 0, 0, 1]], dtype=uint32)
>>> result[:, :, 0, 1]
array([[3, 0, 2, 0],
[0, 2, 2, 0],
[0, 0, 1, 2],
[0, 0, 0, 0]], dtype=uint32)
"""
image = skimage.util.img_as_ubyte(image)
assert image.ndim == 2
assert image.min() >= 0
assert image.max() < levels
distances = np.asarray(distances)
angles = np.asarray(angles)
assert distances.ndim == 1
assert angles.ndim == 1
rows, cols = image.shape
out = np.zeros((levels, levels, len(distances), len(angles)),
dtype=np.uint32)
for a_idx, angle in enumerate(angles):
for d_idx, distance in enumerate(distances):
for r in range(rows):
for c in range(cols):
i = image[r, c]
# compute the location of the offset pixel
row = r + int(np.round(np.sin(angle) * distance))
col = c + int(np.round(np.cos(angle) * distance))
# make sure the offset is within bounds
if row >= 0 and row < rows and \
col >= 0 and col < cols:
j = image[row, col]
if i >= 0 and i < levels and \
j >= 0 and j < levels:
out[i, j, d_idx, a_idx] += 1
if symmetric:
out[j, i, d_idx, a_idx] += 1
# normalize
if normal:
out = out.astype(np.float64) / out.sum()
return out
if __name__ == "__main__":
import doctest
doctest.testmod()