Why binWidth changes the answer
Tonight · ~20 min · read + a tiny calculation · energy: low · setup: none
Change one number in your PyRadiomics config — binWidth, from 25 to 5 — and a
texture feature can move by a large fraction, on the same tumour. This lesson
shows why with a five-value example, so you never again treat discretisation as a
boring default.
The anchor: discretisation is the texture feature
Recall from lesson 3: texture matrices are built on
the discretised image. In PyRadiomics’ fixed-bin-width rule each voxel’s grey level
is floor(HU / binWidth), then shifted by a constant so the ROI’s minimum becomes 1
— a relabeling that does not change which voxels share a bin. So for the question
“how many distinct grey levels exist, and which HU values collapse together?”, the
floor(HU / binWidth) part is what decides it. The bin width decides how many
distinct grey levels exist, which decides the entire matrix, which decides every
feature. So binWidth is not a numerical-precision knob — it is part of the
definition of the feature.
A five-value demonstration
Take five HU values inside a small ROI — three lung-adjacent and two soft-tissue:
HU values: [ -987, -982, -978, -50, -30 ]Apply floor(HU / binWidth) for two choices of bin width:
| HU | binWidth = 5 |
binWidth = 25 |
|---|---|---|
| −987 | floor(−987/5) = −198 | floor(−987/25) = −40 |
| −982 | floor(−982/5) = −197 | floor(−982/25) = −40 |
| −978 | floor(−978/5) = −196 | floor(−978/25) = −40 |
| −50 | floor(−50/5) = −10 | floor(−50/25) = −2 |
| −30 | floor(−30/5) = −6 | floor(−30/25) = −2 |
Look at the lung triplet (−987, −982, −978):
- At
binWidth = 5they become three different grey levels (−198, −197, −196) — the fine HU differences survive as distinct bins, and a GLCM would see three co-occurring levels. - At
binWidth = 25they collapse into one grey level (−40) — all three HU values are now “the same”, and the GLCM sees a single level where there were three.
The whole lung region, which at binWidth = 5 had internal texture, becomes a
uniform blob at binWidth = 25. Every texture feature — Joint Entropy, Contrast,
run lengths, zone sizes — is now computed on a different matrix and gives a
different number, on identical anatomy.
Which way do features move?
The direction is usually predictable, which makes the effect auditable rather than mysterious:
- Smaller
binWidth→ more grey levels → a finer, more populated matrix → typically higher entropy (more disorder visible) and finer-grained contrast. - Larger
binWidth→ fewer grey levels → a coarser, sparser matrix → typically lower entropy and coarser contrast.
(PyRadiomics’ default binWidth is 25; do not leave it implicit — pin it in the
parameter file and report it with every result, as TRACE-CT does, because the
chosen value is feature-determining.)
The discipline this forces
Because binWidth rebuilds the matrix, two statements follow:
- A feature value is meaningless without its
binWidth(and resampling spacing, and interpolator). “JointEntropy = 2.3” tells you nothing; “JointEntropy = 2.3 atbinWidth = 25, 1 mm isotropic B-spline, HU clip[-1000, 400]” is a quantity. - You must not tune
binWidthto maximise a downstream metric — that is feature-fishing and invalidates validation. You pin it, report it, and keep it fixed.
This is why IBSI fixes a processing workflow and why TRACE-CT commits
configs/pyradiomics_params.yaml (binWidth 25, original, 3D, label 1) rather
than leaving defaults. The configuration is part of the measurement.
Bridge
The five-value table is the whole argument compressed: the same five voxels produce
either a textured or a uniform region depending on a single number in a config
file. When you internalise that, “report your preprocessing” stops being bureaucracy
and becomes obviously necessary — without binWidth, the number is not even
defined.
Stop and think — then reveal
You compute original_glcm_JointEntropy at binWidth = 25, then again at
binWidth = 5, on the same tumour. The value rises from 2.3 to 3.1. Has the tumour
become “more textured”?
No — the tumour is unchanged; you changed the definition of the feature. Smaller
binWidth preserves finer grey-level distinctions, populating more matrix cells and
raising entropy by construction. The 2.3 and the 3.1 are two different
quantities under two different pipelines, not a measurement of a change in the
tumour. This is exactly why comparing a feature across papers (or across your own
experiments) is invalid unless binWidth and the rest of the pipeline match.
What to retain
binWidthdiscretises HU into grey levels; it rebuilds the texture matrix, so it changes every texture feature on identical anatomy.- Smaller
binWidth→ more levels → higher entropy/finer contrast; larger → coarser → lower. The direction is usually predictable. - A feature value is undefined without its
binWidth(and spacing/interpolator). Pin it in the config, report it, never tune it to a metric. - This generalises: discretisation is part of the feature’s definition, which is why IBSI and TRACE-CT fix it rather than leave it to defaults.
Next: zoom out — everything that changes a feature,
of which binWidth is only the most dramatic.