Shipped

GLCM Texture Analysis

Image texture features built from scratch, and reused years later in a Mars hazard map.

From scratchGrey-level co-occurrence matrices written in NumPy
Period
2024 to 2025
Areas
ML
NumPyCo-occurrence matrices implemented directly, not imported
ReusedFeeds the SkyScout hazard map

Problem

Two patches of a photograph can have exactly the same average brightness and be completely different surfaces. One is smooth sand, one is broken rock. Brightness alone cannot tell them apart. Texture can.

Approach

A grey-level co-occurrence matrix, or GLCM, counts how often a pixel of one brightness sits next to a pixel of another brightness, at a chosen distance and direction. Smooth regions put their counts on the diagonal, because neighbours are similar. Rough regions spread the counts out.

I built the matrices in NumPy rather than calling a library, then derived the standard features from them. Pillow loads the images, Matplotlib draws the surfaces, and Flask puts a small interface in front of it. There is no computer vision library in this project at all, which was the point.

Results

Writing it by hand is why it was still useful later. When SkyScout needed to tell a hazardous surface from a drivable one from above, I already had texture features I understood well enough to trust, and to debug.

Limits, and what I would do next

GLCM features depend on the distance and direction you pick, and on the number of grey levels you quantise to. Those choices are part of the result, and they need reporting alongside it.

Texture also depends on scale. Gravel from two metres up and boulders from twenty metres up can produce the same numbers, which is a real risk for an aerial hazard map.

Stack

  • NumPy
  • Pillow
  • Flask