Pixels are measurements with a contract
Foundation01 / The story
Maya helps a community archive scan painted theatre posters. One morning, the blue costumes appear red in the new catalogue. The files open normally, so the team first blames the screen. Maya instead follows one known blue patch through each processing step.
She discovers that the loader stores blue first, while the next step reads the first value as red. She writes down the order, image size and value range, then corrects the colour conversion. The costume becomes blue again. The team now checks those simple agreements before asking a model to recognise anything. The same numbers can describe different colours when their meaning is not shared.
02 / The concept
A digital image is a grid of small measurements called pixels. A grey image stores one number at each row and column. A colour image often stores three numbers there: red, green and blue, abbreviated RGB. A channel is one of these colour lists. An array is simply an organised table of numbers; a tensor is an array with one or more axes.
A shape such as (4, 6, 3) means four rows, six columns and three channels. Python counts from zero, so image[0, 1] selects the first row and second column. Some tools store blue first (BGR). Moving the channel axis does not swap the colour meanings.
Scaling divides a byte value by 255 to put it between 0 and 1. Standardization then subtracts a chosen centre and divides by a positive spread. A negative result means below that centre, not an impossible colour. Use exactly the input rules that a model was trained with.
Words to know
- Pixel
- One position in an image grid.
- Channel
- One measurement type at every pixel, such as red.
- Shape
- The sizes of an array along its axes.
03 / Put the concept to work
Start a vision pipeline with a tiny diagnostic image whose colours and locations you know. Inspect shape, type, minimum and maximum values, and one selected pixel after each conversion. Apply normalization using the statistics specified by the pretrained weights, or training-only estimates when designing your own pipeline. Keep the unmodified input available so that visualization does not accidentally display standardized values as ordinary colours.
04 / How others use it
OpenCV's Basic Operations on Images tutorial makes pixel access, array properties and channel manipulation visible rather than treating an image as an opaque file. TorchVision's transforms documentation explains transformations across images and structured targets. Together they illustrate the practical boundary that the archive story exposes: representation choices are part of the computation, and must remain consistent before learned inference begins.
05 / The formula, unpacked
z = (v / 255 − μ) / σ HWC → CHW: (H, W, C) → (C, H, W)
v is an eight-bit channel value between zero and 255. Dividing by 255 maps it to the unit interval; μ and σ are the chosen mean and positive standard deviation on that same scale. z is the standardized value and can be negative. H, W and C denote height, width and channel count. HWC and CHW describe axis order only, not whether the channels mean red, green or blue. This equation assumes the stated byte scale; a floating image already in the unit interval should not be divided again.
06 / Work through the numbers
Use a synthetic channel value v = 153 with μ = 0.5 and σ = 0.25. First scale: 153 / 255 = 0.6. Then centre: 0.6 − 0.5 = 0.1. Finally divide by the standard deviation: z = 0.4.
If the value 0.6 had already been scaled, another division by 255 would instead produce approximately −1.9906 after standardization. The shape offers a separate check: a 4-by-6 RGB image has shape (4, 6, 3), and moving its channel axis first gives (3, 4, 6), still containing 72 numbers. Neither operation by itself converts BGR to RGB. Compare both numeric values and channel semantics before declaring the input correct.
Let us work through it
Why can a correctly sized image still look wrong?
The three channels can have the wrong meaning. Interpreting BGR as RGB swaps red and blue.
What is the middle step for v = 153?
153/255 = 0.6. Subtracting 0.5 gives 0.1 before division by 0.25.
Should an input of 0.6 be divided again?
Only if 0.6 is on the byte scale. If it is already scaled to 0–1, dividing again corrupts the agreed input range.
Run a complete example · 01
Follow one channel
A list represents one known blue pixel. No image file or trained model is needed.
bgr = [255, 0, 0]
rgb = list(reversed(bgr))
value = 153
scaled = value / 255
standardized = (scaled - 0.5) / 0.25
print("RGB:", rgb)
print(f"scaled={scaled:.1f}; standardized={standardized:.1f}")
print("stored numbers:", 4 * 6 * 3)
Run it locally
python pixels-contracts-pixel-scale.py
Expected output
RGB: [0, 0, 255] scaled=0.6; standardized=0.4 stored numbers: 72
Read the code step by step
The first line stores blue, green, red. reversed changes their order and list stores the result. The next three lines scale 153, subtract 0.5, and divide by 0.25. The f-string prints one decimal place. The final multiplication counts 72 channel values, not 72 separate pixels. This checks data conventions; it does not recognize an object.
Where you can use this
Known-colour check
Change bgr to [0, 0, 255]. RGB should become [255, 0, 0], a red pixel. Explain why the number of entries remains three.
Different image size
A 2 by 5 RGB image has 10 pixels and 30 channel values. Change the final multiplication and check both counts separately.
Before learning from pixels, establish their axes, colour meaning, scale and normalization contract at every boundary.