← Francesco Vigni

Endoscopy · acquisition shortcuts

You can tell which hospital a colonoscopy frame came from without looking at the anatomy.

An endoscope hands you tissue inside a frame the equipment drew: black letterboxing, an octagonal field-of-view mask, the exam date burned into the pixels, the processor's settings. None of it is anatomy. All of it identifies the machine — and the machine correlates with the answer. Five public colonoscopy datasets, three centres.

The same endoscopic frame shown through each preprocessing pipeline: as acquired, resized, cropped to the field of view and padded, and reduced to the inscribed square
The same frame through each pipeline. Left to right, progressively less of the canvas the equipment drew — and progressively less of the tissue with it.

1 · A frame announces where it came from

Nine descriptors of the canvas geometry — aspect ratio, mask area fraction, letterbox extents, centroid offset — and no anatomy pixels at all. A classifier on those nine numbers picks the right dataset out of five:

as acquired0.961
resize only0.899
crop to the field of view + pad — the standard recipe0.859
inscribed square — geometry removed0.477
chance0.200

The standard fix barely works. Cropping to the imaging area and padding to a square — what most pipelines do — moves it 0.90 to 0.86, because padding preserves the aspect ratio deliberately, so as not to distort anatomy, and carries the signature along with it.

Bar chart of source identification accuracy per preprocessing pipeline for geometry, border and anatomy feature sets

2 · Self-supervision makes it structural

A contrastive loss pushes apart different images. If the source is identifiable, the cheapest way to push two images apart is to notice they came from different equipment — so the pretext task gets solved on the letterbox. And self-supervision exists in order to pool sources, so the exposure grows with the very thing that makes it worth doing.

A small encoder pretrained on pooled frames, frozen, then linearly probed:

pipelinesource identity
chance 0.33
polyp presence
chance 0.78
resize only0.9570.895
crop to the field of view + pad0.9370.889
inscribed square0.8910.873

The learned encoder recovers almost everything cropping removed: 0.86 to 0.48 for hand-made features, but only 0.96 to 0.89 here. It reads colour, illumination and texture — not border shape. Removing the geometry does not remove the confound, it moves it.

Source identity and polyp-presence accuracy from a frozen self-supervised encoder across the three pipelines
Utility falls a little; source identity falls much less. The gap is the cost nobody reports.

3 · The non-anatomical part predicts the diagnosis

HyperKvasir, restricted to the lower GI tract so that scope type cannot act as a confound:

geometry only0.488
border pixels — no anatomy0.674
anatomy colour statistics0.666
majority class0.172

The border region beats the anatomy's own colour statistics. What leaks is the session — dye, illumination settings, timestamp — and the session correlates with why the procedure was done in the first place. Upper against lower GI is 99.5% predictable from geometry alone.

4 · Removing the shortcut does not buy generalisation

This is the part that did not work, and it is the most informative one. Polyp segmentation trained on the Norwegian data, Dice on frames that contain a polyp:

pipelineKvasir
same centre
CVC-
ClinicDB
CVC-
ColonDB
Polyp-
Gen
resize only0.8200.6810.5370.448
crop + pad0.8190.7290.5400.456
inscribed square0.7190.6180.4940.491

Crop-and-pad is free and mildly helpful. The inscribed square removes the most signature, loses 10 Dice in-distribution, and wins only on the most heterogeneous target.

Three explanations fit, and this experiment separates none of them. The model may never have used the shortcut. Losing 24% of the imaged area may simply cost more than the shortcut was worth. Or — found only afterwards — the crop removes the polyp entirely from 6.3% of Kvasir and 15.3% of PolypGen frames, so part of the training is on corrupted labels. The last explanation is the dullest and probably the largest.

Polyp segmentation Dice per pipeline across four target datasets

A curation confound underneath all of it

datasetdistinct
resolutions
median
coverage
Kvasir-SEG · Norway · n=1,000980.825
HyperKvasir · Norway · n=10,662580.935
CVC-ClinicDB · Barcelona · n=61210.720
CVC-ColonDB · Barcelona · n=38010.837
PolypGen · multi-centre · n=2,22580.834

Kvasir keeps the native acquisition resolution; the CVC sets were normalised to exactly one before release. That is curation, not biology, and it is baked into every benchmark that trains on one and tests on the other.

What this does not show

That any published model took the shortcut — every result here is correlational. Three centres, not six. One training centre for the segmentation arm. The self-supervised encoder is small and trained from scratch, not a foundation model. No clinical claim of any kind.

Reproduce it

Everything runs from public data: five colonoscopy datasets, a single command per experiment, 29 tests in CI on Python 3.11–3.13. The negative result in section 4 is in the repository with the code that produced it.

Full background hello@francescovigni.com GitHub