Every Python example in this course reads an image as a NumPy array. Its shape and indexing get used wrong at least once if the convention was never stated plainly. This short section states the convention once, so every later chapter's Python lab can lean on it without re-explaining.
NumPy stores an image exactly the way this course already agreed to think
about one: as a matrix, row number first. So when code asks for
image.shape, it is really asking "how many rows, then how many
columns." And "rows" means height, "columns" means width.
The mismatch that trips people up is this. When a person describes a
photo out loud, width comes first: "a 1920-by-1080 photo." But when the
computer reports that same photo's shape, height comes first instead.
Neither habit is wrong. They are just two equally standard habits that
happen to run in opposite orders. The fix is simply knowing which one you
are looking at: a spoken "width by height," versus a printed .shape
that reads "height, width."
A grayscale image loaded into NumPy is a 2D array with .shape == (H, W),
height first, width second. That is exactly the row-then-column order
Section 2 already fixed for matrix indexing. image[y, x] reads the
pixel at row y, column x. image.shape reports (H, W), not
(W, H). A color image adds a third axis, .shape == (H, W, 3), with
the channel axis last. image[y, x, c] reads channel c \in \{0, 1, 2\}
(red, green, blue, in that order, by the near-universal convention this
course follows throughout).
Two consequences surprise almost everyone once, so both are worth stating
plainly. First, image.shape[0] is the height, not the width, the
opposite of how a photo's dimensions are usually spoken aloud. A
"1920\times 1080 image" means 1920 wide and 1080 tall, but its
NumPy shape is (1080, 1920). Second, slicing image[100:200, 50:150]
crops rows 100–199 and columns 50–149, a 100\times 100 region,
using that same row-first order.
Shape, indexing, and (row, col) together
This is a 4x6 grayscale array. Its .shape is (4, 6) -- 4 rows, 6 columns. Click the cell at image[1, 4] (row 1, column 4) and check the value the readout reports.
Loading interactive…
Worked example
Cropping with the right slice order
-
1
An image
imghas.shape == (480, 640)(height 480, width 640). Write the slice that crops out the top-left 100\times 100 pixel square. Rows come first. "Top-left" means the smallest row indices and the smallest column indices. -
2\texttt{img[0:100, 0:100]}
rows 0–99 (the top 100 rows), columns 0–99 (the leftmost 100 columns): a 100\times 100 crop, matching
img[0:100, 0:100].shape == (100, 100).
Loading interactive…
Worked example
Reading a shape tuple out loud
-
1
The widget above has
.shape == (2, 3). State its height and width. The first entry is always height, the second is always width. -
2
Height =2, width =3 -- two rows, three columns, matching the picture.
Loading interactive…
Where this shows up
Document processing and OCR preprocessing
A document scanner that crops out a signature block or a form field before reading it uses exactly this slicing convention. Get the row-and-column order backwards and the crop silently grabs the wrong rectangle: right size, wrong spot. That bug is easy to miss by eye on one test document. It usually only shows up once the same steps run on a document shaped differently than the one first tested.
Check your understanding (counts toward your progress)
For a grayscale NumPy image array with .shape == (480, 640), what is the height?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
640 is the width -- the second entry of the shape tuple, not the first.
The product of the two numbers is the pixel count, not the height.
The shape tuple directly reports height first, width second -- it's fully determinable.
Why
NumPy reports an image's shape as (height, width), so the first entry, 480, is the height.
In image[y, x, c], what does the index c select?
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
Column is selected by x, the second index -- not c.
Row is selected by y, the first index -- not c.
The index c selects one SPECIFIC channel (a single number, 0, 1, or 2), not a count of all channels.
Why
By this course's convention, the third array index selects which color channel (red, green, or blue) to read.
Write the NumPy slice that crops the top-left 100\times 100 pixel square out of an image img with .shape == (480, 640).
AI grading isn't configured on this deployment.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
First mistake
Correct answer
Also accepted:
Why
Why
img[0:100, 0:100] -- rows 0 through 99 (the top 100 rows) and columns 0 through 99 (the leftmost 100 columns).
Practice: Shape and slicing (3 problems · doesn’t affect your progress)
A loaded image's .shape attribute prints (300, 400, 3). Read off its height, width, and channel count.
AI grading isn't configured on this deployment.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
First mistake
Correct answer
Also accepted:
Why
Why
Height =300, width =400, channels =3 -- the fixed height-width-channel order.
Write the NumPy slice that crops the bottom-right 50\times 50 square out of a 200\times 200 grayscale image.
AI grading isn't configured on this deployment.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
First mistake
Correct answer
Also accepted:
Why
Why
img[150:200, 150:200] -- the largest row indices and the largest column indices.
A colleague says: 'I resized my 600\times 400 photo (width by height) and now img.shape shows (400, 600, 3) -- is that a bug?' Explain why it isn't.
AI grading isn't configured on this deployment.
Right on try — credit. Right — the answer had already been shown, so no credit this time. Next try is worth Answer shown after three tries — this one no longer earns credit. You chose to see the answer — this one earns no credit.
First mistake
Correct answer
Also accepted:
Why
Why
Spoken dimensions run width-by-height, while .shape always reports height-then-width -- the two numbers are the same photo's dimensions, just in a different stated order.