Interactive course · about 3 hours

Computer Vision

A camera hands a computer a grid of numbers. There are no objects in it, no edges, no faces and no cars. There is a number for how bright each little square is, and that is the whole of what arrives. Everything a machine ever says about a picture is worked out from those numbers. The first part builds that work from arithmetic: filtering, edges, blobs and tracking. The later steps turn to learned vision. They explain how a trained model represents a picture, how it takes a request in words or with a pointed finger, and how it fails when the world changes. The small labs expose the calculation behind each idea. They do not imitate the output of a large model.

How this works

The pictures here are small, between eight and twenty squares across, and each has a Numbers button beside it. Press it and the picture becomes the grid of numbers it always was. Rest the pointer on any picture and it reads out the number under your fingertip. None of the pictures came from a camera or a file. Each one is worked out by a rule, so there is no step where you have to take a number on trust. One image engine sits underneath all of them, and every count, average and centre you see was computed by it while you watched. The learned-vision labs count tokens, compare vectors and weigh up adapters and test scores. They show you the contract a model offers. They do not pretend to run a big trained model in the browser.

What you need to know first

Adding, subtracting, multiplying and dividing whole numbers, and what an average is. That is all of it. Where a normal course reaches for matrix notation, this one draws the nine numbers and adds them up. Where one reaches for calculus, this one subtracts the left neighbour from the right one. No programming and no earlier course.

The steps

Step 1

A picture is a grid of numbers

Hold a magnifying glass to a screen and the picture breaks into tiny squares, like a mosaic made of thousands of little tiles. Each tile is a pixel, short for picture element, and each one holds a number saying how bright it is. Zero is black, 255 is white, and everything in between is a shade of grey. A picture is a grid of those numbers, in rows, and there is nothing else in the file.

That last sentence is the one to hang on to, because everything in this course follows from it. A camera does not send objects. It sends a number per pixel. If a machine is going to say something about what is in the picture, it has to work that out from the numbers. The only tools it has are the ones you would use on any other numbers. The first lab is a paint-by-numbers puzzle running in both directions at once. Paint a square and you have written a number. Change a number and you have painted a square.

Why does it stop at 255, and not 100 or 1000?

Because a computer stores numbers in fixed lumps, and the smallest useful lump is a byte: eight switches, each on or off. Eight switches can be arranged 256 different ways, so one byte can hold any whole number from 0 to 255. One pixel of grey is one byte. That has been the standard since the 1970s because it is enough. Most people cannot reliably tell one shade from the next along.

It matters for a reason that turns up in the next step. There is no room above 255 and none below 0. Arithmetic that asks for a number outside that range does not get it, and what happens instead is the subject of Step 2.

What about colour? Everything here is grey.

A colour picture is three of these grids stacked up: how much red each pixel has, how much green, how much blue. Each of the three is a grid of numbers from 0 to 255, exactly like the grey ones here. A colour picture is three times the work and no new ideas.

A great deal of real vision work throws two of them away, or mixes all three into one grey grid, before doing anything else. Edges, shapes and movement are nearly all visible in brightness alone, and one grid is a third of the arithmetic. Colour comes back when it is the thing you actually need, for finding a red ball or a yellow line.

Lab 1 · Painting with numbers
Try this firstDrag the pen brightness up to about 220, then click squares in the pad. Each square you click takes that number, and the picture beside the pad redraws. Then try to land the average of all sixty four numbers between 120 and 136, which the pill under the picture reports after every click.
Notice that the picture and the numbers are never two different things. There is nothing in the picture that is not in the pad, and nothing in the pad that does not show up in the picture. Notice too what the average does not know. Two completely different pictures with the same total brightness give exactly the same average, so any answer built only on the average cannot tell them apart.

Reading a picture out of a table of numbers is something you can do, slowly, by looking for where the large numbers are. A machine has no choice in the matter, because the table is all it ever gets. The next lab makes you do it the machine's way once.

Lab 2 · Reading a picture out of the numbers
Try this firstDecide what the grid shows before you press anything. Look for where the numbers above 200 sit and where the ones below 60 sit. Then press the description you think fits, and press Picture at the top to see whether you were right.
Notice how much easier the picture is than the table, and that no information was added. Your eye is doing a job that took millions of years to evolve, and it does it on the same hundred numbers. Everything in the rest of this course is an attempt to do a small part of that job with arithmetic.
A camera sends a computer a picture that is 1920 pixels across and 1080 down, in grey. How much of what is in that picture does the computer know before it does any work?
Two million numbers and their positions. 1920 multiplied by 1080 is 2073600, and every one of those is a brightness between 0 and 255. There is no list of objects, no outline and no label. Anything a machine says about the picture later is worked out from those numbers, which is why a course on vision is mostly a course on arithmetic.
Step 2

Add the same number to every pixel, and lose some of them

The simplest thing you can do to a picture is do the same thing to every number in it. Add 40 to all of them and the picture gets brighter. That is what a brightness control is: one addition, repeated once per pixel, and nothing else.

Contrast is nearly as simple. Pick a middle grey, say 128, and push every number further away from it. A pixel at 160 is 32 above the middle, so multiplying that gap by two puts it at 192. A pixel at 100 is 28 below, so it goes to 44. Darks get darker, brights get brighter, and the middle does not move. That is the whole operation.

Both of them run into the two walls from Step 1. There is nothing above 255 and nothing below 0. When the arithmetic asks for 300, the pixel gets 255, and when it asks for minus 12 the pixel gets 0. Squashing a number onto the nearest end like that is called clipping, and it is not a rounding error. It is the loss of the difference between two pixels that used to be different.

Why push away from 128 rather than from zero?

Because multiplying from zero changes the brightness as well as the contrast. Doubling every number takes a mid grey of 128 to 255, so the whole picture washes out white before any of it has gained contrast. Pushing away from the middle keeps the picture's overall level roughly where it was and spreads the values out around it.

The number you push away from does not have to be 128. Photo software often uses the average brightness of the picture itself, which is a better middle for a picture that is mostly dark or mostly bright. The idea is unchanged: contrast means multiplying the distance from some agreed middle.

What does the spread number under these pictures mean?

It answers one question: how far is a typical pixel from the average of the picture. Work out the average, then for each pixel find how far it is from that average, and average those distances in a particular way. A flat grey picture has a spread of zero, because every pixel is the average. A picture of black and white stripes has a large one.

It is worth having because it measures contrast as a number rather than as an impression. A blurred picture has a smaller spread than a sharp one, which is how Step 4 shows that averaging works. The same number tells you whether a contrast slider actually did anything.

Lab 3 · The two sliders every photo app has
Try this firstPush the multiply slider up to about ×2.5 and watch the two pills that count squashed pixels. They stay at zero for a while and then start climbing. Then bring the slider back to ×1.00 and check whether the picture on the right matches the one on the left again.
Notice that the line under the pictures is the whole operation. One subtraction, one multiplication, one addition, then rounding and the two walls, applied to each of 256 numbers in turn. There is no clever part. What makes this worth a step is the walls, and what they take away when the numbers reach them.
Lab 4 · Multiply, divide by the same amount, and see what came back
Try this firstLeave the factor at ×3.00 and read the pill counting pixels that came back wrong. Multiplying and then dividing by the same number should undo itself perfectly. Then drag the factor down towards ×1.00 and find the point where the count reaches zero.
Notice that nothing went wrong and the picture is still damaged. Both operations were correct. The loss happened in between, when several different bright pixels all became 255 and stopped being distinguishable. This is why photographers care about a blown-out sky, and why a picture should be edited from the original rather than from an already brightened copy.
A photograph of a snowy field comes out too dark, so it is brightened by adding 70 to every pixel and saved. The next day someone decides it is now too bright and subtracts 70 from every pixel. What do they have?
The bright areas are flat now. Snow is mostly bright pixels, so adding 70 pushed a lot of them past 255, and every one of those was stored as 255. The difference between a pixel that wanted to be 260 and one that wanted to be 320 is not written down anywhere any more. Subtracting 70 brings them all back to 185, together. This is why editing software keeps the original and applies the changes to a copy.
Step 3

Slide a three by three window across the grid

Step 2 treated every pixel as though it were alone. That can change how a picture looks, but it can never find anything in it, because finding things is about how a pixel compares with the ones around it. A bright pixel next to bright pixels is part of a bright region. A bright pixel next to dark ones is something else entirely.

So look at a pixel together with its neighbours. Take the eight squares touching it, which with the pixel itself makes a three by three window. Work out one new number from those nine, and that new number becomes this pixel's value in a second picture. Then move the window one pixel along and do it again, all the way across and all the way down. Before any of that gets a name, do it once yourself, in the lab below.

Lab 5 · One output pixel, worked out by hand
Try this firstAdd up the nine numbers shown below the grid, divide by nine, round to the nearest whole number and type it in. Use a pencil if you like. You can also drag the dashed window to any spot you fancy. Press Check my answer and the full working appears, along with what the machine gets when it does the same sum 256 times.
Notice that you have now done exactly what the computer does, at the same level of detail. There is no extra machinery underneath. The only difference between your one answer and the finished picture is patience. The machine will do that sum 256 times without getting bored, and on a real photograph about twelve million times.

What you just did has a proper name, and the name matters because you will meet it everywhere. You gave each of the nine numbers a weight, all ones this time. You multiplied, added up, and divided by the total of the weights. That little grid of weights is called a kernel. Sliding a kernel over a picture, doing that sum at every stop, is called convolution. It is the single most used operation in this whole subject, and it is nine multiplications and eight additions.

Why write the answer into a second picture instead of back into the first?

Because the window has to read the picture it was given, not a picture it is half way through changing. Suppose the answers were written back into the same grid. By the time the window reached the middle of the second row, three of its nine numbers would already be answers rather than original pixels.

The result would still be a picture, and it would look nearly right, which is what makes the mistake hard to spot. It would just be the answer to a question nobody asked. Every convolution in every image library writes into a fresh grid for this reason.

Is a kernel the same thing as a filter?

Near enough, in ordinary use. The kernel is the little grid of weights. The filter is the operation of sliding it over a picture. People say "apply a blur filter" and "the blur kernel is nine ones", and both are normal.

The word filter comes from the same idea as a filter on a sound. A blur lets the slow, broad changes in a picture through and holds back the fast, fine ones. A filter on a loudspeaker does the same to sound: the bass gets through, the treble is held back. That is not a loose analogy, it is the same arithmetic applied to a grid instead of to a sequence.

Lab 6 · Walking the window across the whole picture
Try this firstPress Forward one a dozen times and watch two things at once. The dashed square moves across the input a pixel at a time, and one square of the output picture gets filled in each time. The line underneath shows the sum about to be done. You can also drag the dashed square yourself. Then press Play the sweep and watch the whole picture get written.
Notice the order the output fills in: left to right, then down a row, like reading. Nothing about convolution requires that order, and a graphics card does thousands of these windows at the same moment, because no window depends on the answer from any other window. That independence is why image work runs so well on hardware built for doing the same small sum in parallel.
A three by three averaging window is run over a picture of a plain grey wall, where every pixel holds 130. What does the output picture look like?
Nothing changes. The average of nine numbers that are all 130 is 130. A blur only does something where neighbours disagree, which is at the edges of things and wherever there is fine detail. This is worth holding on to: the interesting behaviour of every kernel in this course happens where the picture changes, and nowhere else.
Step 4

Blur a picture by averaging its neighbours

Set all nine weights to one and divide by nine. Every pixel becomes the plain average of itself and its eight neighbours. That is a blur, and there is nothing else in it.

It is worth knowing why it helps rather than only that it does. A real sensor gives you the true brightness plus a small error, different for every pixel and as likely to be above as below. That error is called noise. Average nine of them and the errors partly cancel, because the positive ones and the negative ones eat each other. The true brightness, which is much the same across all nine, does not cancel. So the picture comes out closer to the truth.

The bill arrives at the edges of things. A pixel on the boundary between a dark object and a bright background has neighbours of both kinds, and averaging them gives something in between. Blur does not know the difference between an error you want gone and an edge you want kept. It softens both.

Why does averaging cancel errors but not the picture?

Because the errors disagree with each other and the picture agrees with itself. Nine neighbouring pixels on the same patch of wall are all near 130, so their average is near 130 whatever you do. Their nine errors are scattered either side of zero. Adding them up gets you a number much smaller than any single one of them, and dividing by nine makes it smaller still.

The rule of thumb is that averaging a group of independent errors shrinks them by the square root of how many you averaged. Nine of them, so the noise ends up about three times smaller. Averaging twenty five shrinks it five times, and blurs the picture correspondingly more.

Why do real blurs weight the middle more heavily?

Because the pixel you are standing on is better evidence about itself than the corner pixel diagonally away from it. The usual small version uses weights of one, two and four, with the four in the middle. It is called a Gaussian blur, after the bell-shaped curve those weights are sampled from.

The visible difference is that a flat average leaves faint square-shaped artefacts behind when it is repeated, because every neighbour counted the same regardless of distance. A weighted one does not. Try both in the lab and watch the spread: the weighted one softens the picture less for the same window, which is often exactly what you want.

Lab 7 · Averaging away the grain
Try this firstMove the passes slider from 0 to 1 and read the two pills for spread and average error. Both fall. Now keep going to 4 and watch them part company: the spread keeps falling while the error against the clean picture starts climbing again.
Notice that more blur is not more truth. The first pass removes much more noise than picture. By the fourth, the picture is smoother than it has any right to be and further from the original than it was after one pass. A smooth result and a correct result are different goals, and only one of them is measurable from the picture alone.
Lab 8 · Nine weights of your own
Try this firstPress sharpen and look at what those weights are: a five in the middle and four minus ones around it. They add to one, so the brightness stays put while the differences grow. Then type your own nine numbers and watch the pill that compares the average brightness before and after.
Notice the rule that decides whether a kernel is a softener. If the weights add to the number you divide by, a flat area comes out unchanged and the picture keeps its brightness. If they add to zero, flat areas come out as nothing at all and only the places where the picture changes survive. That second family is Step 6, and it is where edge detection comes from.
A security camera picture is grainy, so an engineer runs a three by three average over it eight times to clean it up. The grain does disappear. What else is likely to have happened?
The small things have gone with the grain. Each pass mixes a pixel with its immediate neighbours, so eight passes reach eight pixels out in every direction. Anything smaller than that has been averaged into whatever surrounds it. This is the trade in every noise reduction by averaging. The filter cannot distinguish grain from image detail at the same spatial scale, so it removes some of both.
Step 5

Four ways to invent the neighbours a border does not have

The window in Step 3 needs nine numbers. A pixel in the top left corner of the picture has only four, because the other five would be outside the frame. There is no such pixel, and the arithmetic still wants a number for it.

This is not a small detail to be tidied away. Every picture has a border, every convolution meets it, and there is no correct answer, only four common choices. Pretend everything outside is black. Repeat the outermost row and column outwards for ever. Take the missing pixels from the opposite side of the picture. Or refuse to invent anything and hand back a smaller picture.

How many pixels are actually affected by this?

For a single three by three window, just the outermost ring: 60 pixels of a sixteen by sixteen picture, which is nearly a quarter of it. On a photograph 4000 pixels across it is about 16000 pixels of 16 million, which is a tenth of one per cent and easy to dismiss.

Two things stop you dismissing it. Each pass reaches one ring further in, so five passes of a three by three window affect five rings. And a machine looking for shapes does not care what fraction of the picture something is. One bright ring around the edge is one more shape in the list, and Step 9 will count it.

Which one should I use?

Repeating the outermost row outwards is the sensible default and is what most image libraries do unless told otherwise. Its guess is that the picture carries on doing whatever it was doing at the edge, which is usually closer to the truth than any of the alternatives.

Taking pixels from the opposite side is right for something that really does repeat, such as a tiled texture or a signal that goes round a circle. For a photograph it is quietly wrong. Assuming black is the fastest and the most likely to cause the problem in the second lab below. Cropping is the only one that invents nothing, and it is used where the answer has to be trustworthy rather than the same size as the input.

Lab 9 · The same blur, four different borders
Try this firstPress pretend it is black and read the pill for what the outer ring now averages. Compare it with the pill above for what the outer ring averaged before. Then press repeat the last row and read the same two pills again.
Notice that the dark frame is a picture of the assumption. Nothing near the edge of this scene is dark. The border went dark because five passes of averaging mixed in an imaginary black surround, a little more each time. It looks like a vignette from a cheap lens, and it is entirely manufactured by the choice of what lies outside.
Lab 10 · An edge round the whole picture that was never there
Try this firstLook at the two pictures before touching the slider: the left one has a bright ring all the way round and the right one does not. The scene is the same in both. Then drag the counting level up and down and watch how many of the 60 border pixels each choice calls an edge.
Notice that this is a defect a browser sweep would never find. Both pictures render, neither throws an error, and the left one arguably looks more interesting. It is simply wrong, and the wrongness is a perfect rectangle round the outside, which anything counting shapes later will report as the biggest object in the scene.
A program blurs a picture with a five by five window and hands back a picture two pixels smaller in each direction rather than the same size. What has it done?
It cropped rather than guessed. The pixels it dropped are exactly the ones whose window would have hung outside the frame. This is the honest option and it is common in scientific work, where a made-up border pixel could turn into a made-up measurement. The cost is that the output no longer lines up with the input, so anything that compares the two has to account for the shift.
Step 6

Find an edge by subtracting one neighbour from another

Find a shadow on the floor and run your finger across its boundary. You can feel nothing, but your eye snaps to the exact line where bright stops and dark starts. That line is an edge: a place in a picture where the brightness changes quickly. The side of a dark door against a pale wall is an edge. The middle of the wall is not, however bright it is. Brightness on its own says nothing about edges, and that is the useful part. Change is what matters, not level.

Change between two neighbours is a subtraction. Take the pixel to the right and subtract the pixel to the left. On flat ground, however dark or bright, the two are equal and the answer is zero. At a place where the picture jumps from 40 to 200, the answer is 160. Drag the edge about in the lab below and watch that subtraction find it, wherever you put it.

Lab 11 · Right neighbour minus left neighbour
Try this firstDrag the edge to a different column, with the slider or by dragging on the picture itself, and watch the answers move with it. The pill for flat ground stays at zero wherever you put the edge. Then press an edge across the picture, which is just as obvious to your eye, and read the pills again.
Notice that this rule is completely blind in one direction. Every answer on the horizontal edge is zero, because left and right are the same everywhere along it. The rule is not weak there, it is measuring something that does not change at all. One question gets one answer, and the fix is a second rule asking the other question.

That subtraction is a kernel, like the ones from Step 3: three weights in a row, minus one, zero, one. Its answer can be negative, when the picture gets darker to the right instead of brighter, and it can be larger than 255. Both of those are real and neither is a mistake, so this kernel's output is not stored the way a picture is. The number it produces is called a gradient: how steeply the brightness is changing, and which way.

What does a negative pixel value mean?

Here it means the picture is getting darker in the direction you measured. Going from 200 down to 40 gives minus 160, exactly as far from zero as going from 40 up to 200, and pointing the other way. The size tells you how strong the edge is, and the sign tells you which side is the bright one.

To draw it, the widget maps zero to mid grey, so flat ground is grey, a bright-to-dark edge is dark and a dark-to-bright edge is light. Press Numbers and the real signed values are there. Nothing has been quietly turned positive on the way to the screen.

Why does Sobel use six weights when three would do?

Because three weights only ever look at one row, so a single noisy pixel in that row is the whole answer. Sobel does the same left-minus-right subtraction on the row above and the row below as well, and counts the middle row twice. The weights are minus one, minus two and minus one down the left, and one, two, one down the right.

So it is a difference and a small blur in the same nine numbers. It gives the same answer on a clean edge and a far steadier one on a real photograph, at no extra cost, since it is nine multiplications either way. It is named after Irwin Sobel, who described it in 1968.

Why square the two answers and take the square root?

Because the two kernels are measuring two directions at right angles. Putting them together is the same problem as finding the length of a sloping line, given how far it goes across and how far it goes up. Square each, add them, take the square root. That is Pythagoras, and it is the reason an edge at 45 degrees comes out about as strong as a vertical one rather than half as strong.

Real code often adds the two sizes together instead, ignoring the signs. Addition is much cheaper than a square root, and the answer is close enough to steer a decision. That approximation is one of the small dishonesties that makes vision run at thirty frames a second.

Lab 12 · Two directions, combined into one number
Try this firstDrag the angle slowly from 0 to 90 degrees and watch the two middle pictures trade places. The across answer fades as the down answer grows. Watch the fourth picture and its pill while that happens, and read the line underneath, which shows the sum for the strongest pixel in the frame.
Notice that the combined answer barely cares about the angle while each half of it cares enormously. That is what makes it useful. An edge detector that found vertical door frames and missed horizontal shelves would be worse than useless in a room. Combining the two directions is all it takes to fix that.
A Sobel edge detector is run over a photograph of a plain white wall in even light, and then over a photograph of a black cat on a white sofa. What comes out?
An outline, not a shape. Every pixel in the middle of the cat has neighbours just as black as it is. The answer there is zero, exactly as it is in the middle of the wall. The response appears only along the boundary. An edge detector produces an outline, not a filled object. Grouping edges into regions or objects takes more work, and Steps 7 and 9 show two ways to do it.
Step 7

Cut a grey picture into black and white at one level

At some point a machine has to stop describing and start deciding. Is this pixel part of the thing or part of the background. The cheapest possible decision is to pick a level and compare. Anything at or above the level becomes white. Everything else becomes black. Try being the level yourself first: drag it up and down in the lab and watch what the decision does to the picture.

Lab 13 · Choosing the level, including badly
Try this firstDrag the level to 0 and then to 255, and read the count of white pixels at each end. One end gives all 256, the other gives none. Then find the whole band of levels in between that give exactly the 44 the disc really contains.
Notice that both failures are silent. At level 20 the machine reports a large white shape and is completely wrong about what it is. At level 240 it reports that there is nothing there. Neither answer comes with a warning, because a cut at a level has no way of knowing what a sensible answer would look like.

That cut has a name. Comparing every pixel against one level is a threshold, and the result, a picture with only two values in it, is called a binary picture. It throws away nearly everything. A pixel that was 129 and a pixel that was 255 come out identical. A pixel that was 127 goes the other way, despite being almost the same as the 129. In exchange you get something you can count, join up and measure, which grey pixels do not let you do. Steps 9 through 11 all need a binary picture to work on.

Everything then hangs on the level, and the level is where this method fails. The number that separated the object from the background in one photograph is not a fact about the object. It is a fact about the light on the day that photograph was taken.

How do you choose the level without guessing?

The simplest honest rule is to read it off the picture in front of you rather than remembering one. Take the darkest pixel and the brightest pixel, and go half way between. It costs one pass over the numbers and it moves with the light, which is exactly what a fixed level cannot do.

The method most often used in real work is called Otsu's method. It tries every possible level and keeps the one that splits the pixels into two groups that each agree with themselves most tightly. It is more work and it needs no assumptions about how bright the scene is. Both are the same idea: ask the picture, do not remember a number.

Why does a wide range of levels give exactly the same answer here?

Because this scene holds only two numbers, 70 for the background and 215 for the disc. Any level from 71 to 215 puts the same pixels on each side, so the count does not budge. A picture made of two flat values is the easiest possible case for a threshold.

A photograph is not like that. Its numbers are spread across the whole range, the object shades into shadow at one side, and there is often no level at all that separates the two cleanly. That is why real work usually blurs first, thresholds, and then throws away the shapes that are the wrong size, rather than expecting one number to do the whole job.

Lab 14 · The same level, in different light
Try this firstLeave the button on a level fixed at 128 and drag the light down to the far left. The count of found pixels drops to nothing while the disc is still plainly there. Then press a level read off the picture and drag the light across its whole range again.
Notice that nothing about the object changed between those runs. Same disc, same size, same position. The only thing that moved was how much light was falling on the scene. A rule with a number written into it fell over, and a rule that asked the picture did not. This is the shape of most real vision failures: something that worked in the lab and does not work at four in the afternoon.
A robot finds a white line on a dark floor by thresholding at 150, and it works perfectly in the workshop. At a demonstration in a sunlit hall it steers into a wall. What is the most likely explanation?
The floor came up past 150. The threshold was never measuring the line. It was measuring whether a pixel was above 150, which happened to mean line in the workshop. In sunlight it means almost everything. Reading the level off each frame would survive this. So would looking for the boundary between floor and line with an edge kernel instead. An edge is a comparison between neighbours, and it does not care how bright either of them is.
Step 8

Average before you cut, and count what survives

Real sensors produce wrong pixels. Not slightly wrong, which is the grain from Step 4, but completely wrong: a dead cell that always reads zero, a stray charge that reads full white, a bad connection. A handful of pixels in each frame hold a number with no relation to what the camera was pointing at.

A threshold has no defence against this at all, because it looks at each pixel entirely on its own. One wrong pixel of 255 in a dark background sails over the level and becomes a white pixel in the result, indistinguishable from a real one. Twenty of them become twenty little white shapes, and anything counting shapes afterwards will count twenty one objects where there is one.

The fix is to run the two operations in the other order. Average first, then cut. A single wrong pixel is one number against eight neighbours that disagree with it, so averaging drags it most of the way back before the threshold ever sees it. A real object is dozens of pixels that agree with each other, so averaging barely touches its middle.

Can I work out whether the speck will survive?

Yes, and it is one line of arithmetic. A wrong pixel of 255 sitting on a background of 70 has eight neighbours of 70. The average of those nine is 255 plus eight lots of 70, all divided by nine, which is 91. The level is 128, so 91 does not reach it and the speck never appears in the result.

The same sum tells you when it will not work. If the background were 130 rather than 70, the average would be 144, which is above 128, and the speck would survive. Averaging first is not a guarantee. It buys a specific amount of margin. You can work out exactly how much.

Is there something better than averaging for this?

Yes, and it is worth knowing by name. Instead of the average of the nine numbers, take the middle one when they are put in order. That is called a median filter. A single wrong pixel is either the largest or the smallest of the nine, so it is never the middle one. It vanishes completely rather than being watered down.

It also keeps edges sharp, because along an edge most of the nine are on one side and the middle one is on that side too. The cost is that sorting nine numbers is slower than adding them, and it is not a convolution, so it cannot be done by the same hardware. For specks exactly like these it is the right tool.

Lab 15 · The same two operations, in either order
Try this firstWith cut it straight away selected, drag the noise up to about 12 and read the pill counting separate white shapes. Then press average first, then cut without touching anything else, and read the same pill again.
Notice that nothing was added to fix this. Both runs use the same averaging window from Step 4 and the same threshold from Step 7. The only difference is which one happens first, and it decides whether the machine reports one object or a dozen. Order is part of the design, not a detail of the implementation.
Lab 16 · Both orders, at every noise level
Try this firstPress the button and watch the pairs of bars fill in. The left bar of each pair climbs steadily as the noise gets worse. The right bar stays near one almost throughout. Then compare the two biggest-shape columns in the table, which say what happened to the real disc.
Notice that averaging first is not free. The biggest shape comes out slightly larger than the true disc, because averaging spread its edge outwards and the threshold then kept some of that spread. You have traded a wrong count of objects for a small error in the size of the one that is there, which is nearly always the better trade.
A machine counts screws on a conveyor belt by thresholding and counting shapes. It has started reporting about fifteen screws when there are three. The pictures look normal to a person. What is the first thing to try?
Average first, and set a smallest size. Twelve extra objects that a person cannot see in the picture are almost certainly one or two pixels each. Both fixes work on that and neither one needs to know anything about screws. Setting a smallest size is the one to reach for when you know roughly how big the real thing is. It comes back in Step 9 as the size filter.
Step 9

Join the touching pixels, then average their positions

A binary picture is a set of white pixels, and nothing in it says which of them belong to the same object. Working that out is one rule. Two white pixels are part of the same shape if you can walk from one to the other through white pixels, moving up, down, left or right. Walk out from every white pixel until you cannot go further, give everything you reached the same number, and move on to the next one you have not visited. Each group is a blob, and giving them numbers is called labelling.

Now each blob can be measured. How many pixels it has is its area. Where it is, is the average of the across positions of all its pixels and the average of the down positions of all its pixels. That pair of averages is the centroid. It answers "where is the thing", which is the question every tracker, robot arm and autofocus system is asking.

The centroid does something quietly useful. Its inputs are whole numbers, since a pixel is either in or out, and its output is not. Average 44 whole numbers and you get an answer to two decimal places, so a camera can report a position finer than one of its own pixels.

Why up, down, left and right, but not diagonally?

It is a choice, and both versions are used. Counting only the four square neighbours is called four-connected, and counting the diagonals too is eight-connected. Four is stricter, so two blobs that touch only at a corner stay separate.

The difference matters more than it sounds. A thin diagonal line one pixel wide is a single shape under the eight-connected rule and a string of separate dots under the four-connected one. Neither is right. It is the sort of decision you make once, write down, and remember when a count comes out strange.

Is the centroid the same as the middle of the box round the shape?

No, and the difference is worth seeing. The middle of the bounding box depends only on the four extreme pixels: the leftmost, rightmost, topmost and bottommost. The centroid depends on every pixel, so it is pulled towards wherever most of the shape is.

For a symmetric blob they land in the same place. For a tadpole shape they do not: the box centre sits half way along the whole thing while the centroid sits inside the head, where the pixels are. Which one you want depends on the question. The centroid is steadier when the outline is ragged, because one stray pixel moves it hardly at all and moves the box a lot.

Lab 17 · Giving each shape a number
Try this firstPress Numbers on the right-hand picture and read the numbers inside the shapes. Every pixel of one shape carries the same number, and the background carries zero. Then drag the ignore slider up past 5 and watch the middle shape drop out of the count.
Notice that the size filter is the whole of what most real systems do about noise, after the averaging. If you know a screw is at least twenty pixels at this distance, anything under twenty is not a screw, whatever it is. That is a fact about the problem rather than about the picture, and it is the cheapest kind of knowledge to use.
Lab 18 · Where the centre lands
Try this firstStart on a round blob and drag it about, on the picture itself or with the two sliders, watching the reported centre follow it. Then press an L shape and look at where the cross goes. Read the pill that says whether the centre is on the shape at all.
Notice that the centre of the L is in the empty corner, and that this is the correct answer. The average of the pixel positions really is there. It is also a terrible place to send a robot gripper. That is why anything picking things up uses the centroid only to say roughly where the object is, and works out a grip point separately. Two lumps averaged together is the same trap, and it is why the blobs get labelled before any centre is taken.
A camera watching a doorway thresholds each frame and takes one centroid of all the white pixels, without labelling first. Two people walk in through opposite sides at the same moment. Where does it report a person?
In the gap between them. This is the two lumps case from Lab 18, and it is why labelling comes before measuring. Split the white pixels into groups first, then take one centroid per group, and you get two answers that are each about somebody. It is also a good reminder that a number can be perfectly correct and still be the answer to the wrong question.
Step 10

Subtract one frame from the next to see what moved

A video is a run of pictures, one after another, and each picture is a frame. Twenty five or thirty of them a second is normal, so very little changes between one frame and the next. That is what makes movement cheap to find.

Take two frames and subtract them, pixel by pixel, ignoring the sign of the answer. Anywhere the scene stood still, the two numbers are the same and the answer is zero. Anywhere something moved, the two disagree. One subtraction per pixel finds every moving thing in the frame without knowing anything about what any of them are.

What comes out is not the object. It is two overlapping ghosts: the place the object has left, which is now background, and the place it has arrived at, which is now object. Both of those changed. A machine using this has to remember that the region it found is bigger than the thing that caused it.

Why ignore the sign of the difference?

Because the question is whether something changed, not which way. Where a bright object moved onto dark background, the difference is a large positive number. Where it moved off, the same size of change comes out negative. Keeping the sign would report only half the movement as movement.

The sign is not useless. A system that knows the object is brighter than the background can keep only the positive differences and get just the arrival, not the departure. That halves the region and is a common trick where the assumption holds.

Why compare against the previous frame rather than an empty scene?

Comparing against a stored picture of the empty scene is the other standard method, and it is better when you can have one. It gives the object rather than two ghosts, because the background really is the background rather than the object's last position.

What makes it harder is keeping that stored picture up to date. The light changes, a chair gets moved, a shadow crawls across the floor over an afternoon. Systems that do this spend most of their effort deciding when to update the stored background and by how much. That is a much bigger problem than the subtraction itself.

Lab 19 · Two frames, and the pixels that disagree
Try this firstSet the movement slider to 0 and read the count of changed pixels. It is zero, even though the background has texture all over it. Then move it to 3 and compare the count against the pill saying how many pixels the object actually contains.
Notice that the textured background contributes nothing. It is full of different numbers and every one of them is identical in both frames, so every one of them subtracts to zero. That is the strength of the method: it does not matter how complicated the background is, only whether it moved.
Lab 20 · Four things that change a frame
Try this firstPress a cloud passes and everything dims, and read the count. Nothing in the scene moved. Then press the camera shifts one pixel and look at which pixels get reported, comparing that against the table at the bottom.
Notice that two of these four are false alarms and the method cannot tell. Subtracting frames answers exactly one question, whether these two numbers differ, and it answers it correctly every time. A camera on a pole in the wind will trigger a naive motion detector constantly. So will an outdoor scene on a partly cloudy day, and the reason is right here in the table.
A motion-triggered camera in a garden sends an alert every few minutes all afternoon, with nothing in any of the pictures. It is quiet at night. What fits best?
The light is moving, not the garden. This is Lab 20's cloud case at full scale. Every pixel changes by a similar amount, so the difference is above the level almost everywhere. There are two standard fixes. Ignore changes that affect nearly the whole frame at once, since a real intruder is a small part of the picture. Or take the average brightness off each frame before comparing them, which throws away exactly the thing a cloud changes.
Step 11

Search near where it was, until that stops working

Finding a blob in a whole frame is Step 9, and it costs a pass over every pixel. Doing that thirty times a second on a large picture is a lot of work to find something you already have a good guess about. Between one frame and the next, a thing that was here is still nearly here.

So do not search the frame. Search a small square around where the object was last time. Inside that square, do the two operations from Step 9: keep the pixels above the level, and average their positions. That answer becomes the middle of the next square. That is a complete tracker, and it is small enough to write on the back of a postcard.

It has one failure and it is built into the design. Nothing outside the square is ever looked at. If the object moves further in one frame than the square reaches, there is nothing above the level inside it, and the tracker has no idea where the object went. It also has no idea that anything is wrong. It keeps searching the same patch of empty background for ever.

Why not just widen the square until it cannot fail?

Two reasons, and the second is the one that catches people. The first is cost. Doubling the reach of the square quadruples the number of pixels in it, and the whole point was to look at fewer pixels than the full frame.

The second is that a wide square is more likely to contain something else bright. The tracker does not know what it is following. It averages the positions of whatever is above the level inside the square. A second bright object drifting into range drags the answer towards it, and can capture it completely. A narrow search is both cheaper and more selective.

What do real trackers do that this one does not?

They predict. Say the object has been moving 1.3 pixels to the right each frame. The sensible place to centre the next search is then 1.3 pixels to the right of the last answer, rather than on top of it. That single change lets a small square follow a fast object, because the square travels with it. The general version of this idea, which also keeps track of how confident it is, is the Kalman filter.

They also notice when they have failed. Suppose a tracker finds nothing, or finds a region wildly different in size from last time. It can say it has lost the object, instead of reporting a position it no longer believes. Knowing that you do not know is the difference between a demonstration and something you would put on a vehicle.

Lab 21 · Following a blob across twelve frames
Try this firstPress Play and watch the dashed square travel with the blob. Then step through with Forward one frame and compare the true centre against the estimate in the pills, and read down the out-by column in the table.
Notice how small the error is, and where the accuracy comes from. The blob is drawn on a grid of whole pixels and the estimate is right to a fraction of one. Averaging the positions of thirteen pixels gives an answer finer than the grid they sit on. This is the same trick that lets a cheap camera measure a position more precisely than its own resolution.
Lab 22 · Making it lose the blob
Try this firstDrag how far it moves each frame up one notch at a time, watching the pill that says which frame it was lost at. It stays on for a while and then fails suddenly. Then widen the search and find the setting that gets the fast case back.
Notice that losing it is not gradual. Right up to the last frame before failure the tracker is as accurate as ever, and then it is completely wrong and stays completely wrong. It does not drift off, and there is no warning in the numbers beforehand. This is why the useful thing to report alongside a position is how many pixels were found. That count is the last column of the table, and it goes to zero at the moment of failure.
A tracker following a ball loses it whenever the ball is thrown hard, but holds on perfectly when it rolls. Widening the search square fixes the throwing case and makes the tracker jump to the referee's white shirt in the rolling case. What is the better fix?
Predict, do not widen. The speed of the object is measurable from the last two answers. Adding it to the last position is a much better guess than the last position on its own. A small square in the right place beats a large square in the wrong one, and it keeps the referee out of the picture. Running the camera faster is a real answer too, and it costs money and processing that prediction does not.
Step 12

Build a pipeline of your own

Every stage in the sandbox below is an operation from an earlier step. Average the neighbours, from Step 4. Compare against a level, from Step 7. Join the touching pixels and average their positions, from Step 9. A chain of operations like that is a pipeline, and it is how nearly all classical vision is built: small, dull, well understood steps in an order somebody chose.

Nothing here is marked, and there are three settings that fight each other. More averaging removes more specks and swells the object. A higher level shrinks what is found and can lose it entirely. A larger smallest size removes specks for free but will throw away a real object that is far away and therefore small.

One suggestion, because a sandbox with no plan is only sliders. Set the noise high, then find the smallest amount of averaging that still leaves exactly one shape, and note what that did to the shape's size. Then get to the same answer using the size filter instead, with no averaging at all, and compare the two reported centres.

What is actually in front of me?

A scene, chosen with the buttons, with some of its pixels forced to black or white at random. The four pictures across the middle are the four stages in order. The picture as it arrives, the picture after the averaging passes, the picture after the cut, and last the shapes that survived the size filter. Each surviving shape carries a cross at its centre.

Every number in the table underneath was worked out from the pictures above it while you watched. The centre columns are the averages of the across and down positions of the pixels in each shape, which is the same centroid as Step 9.

What would I change to look for something else?

The order of the stages far more often than the stages themselves. To find dark objects on a bright floor, invert the comparison. To find the outline of something rather than its body, put a Sobel from Step 6 in front of the threshold. To follow it over time, hand each frame's centroid to the tracker from Step 11.

What almost never changes is the shape of the thing: soften, decide, group, measure. That spine is the same in a factory inspection system, a line-following robot and the motion detection in a doorbell camera.

How does this pipeline relate to learned vision?

Very closely. A learned system keeps the shape you just built, soften, decide, group, measure, and swaps the hand-chosen rules for rules it tuned itself against examples. Its sliding windows are the same convolution as Step 3, only with weights nobody typed in. The steps from here on build up to that, starting with a rule you can still check by hand.

The arithmetic in these twelve steps stays useful around a learned model: preparing sensor data, checking geometry, measuring speed, tracking a returned answer and enforcing a clear safety limit. The rest of the course explains the learned middle, and shows how to decide whether it has earned a place in the pipeline.

Lab 23 · Your own pipeline
Try this firstDrag the noise up to 20 and watch the shape count in the pills go into double figures. Now raise the averaging passes one at a time until the count reaches one, and note what the biggest shape's size did on the way. Then set averaging back to 0 and get to one shape using the smallest size slider instead.
Notice that two different routes to one shape give different centres. Averaging first swells the object slightly and shifts its measured centre a little. The size filter leaves the object exactly as the threshold found it and simply drops the small shapes. Neither is more correct in general, and knowing which error you have is worth more than pretending there is none.
A pipeline that finds parts on a conveyor works all week and then starts missing about a third of them. Nobody has changed the program. Which of these is the most useful first question?
Ask what changed outside the program. A threshold, a smallest size and a search reach are all numbers chosen against particular conditions, and Step 7 showed how completely a fixed level depends on the light. A lamp getting dimmer over a week is the classic version. This is why rules that measure the picture are worth their extra cost. It is also why the most useful thing a vision system can log is not its answers but the numbers it based them on.
Step 13

Find a shape by sliding a small cut-out over the picture

Edges are any change. The next question is how to find a particular thing: not any change, but this cross, this corner, this mark on a part. Here is a game that needs no new machinery. Cut the thing you want out of an old picture, nine numbers in a little square. Slide the cut-out over the new picture, stop at every spot, and ask one question. Do the numbers under it look like the numbers on it?

Asking is arithmetic. At each stop, pair up the nine numbers under the window with the nine numbers of the cut-out. Subtract each pair, ignore the sign, and add the nine answers up. If the patch under the window is exactly the cut-out, every pair matches and the total is zero. The worse the fit, the bigger the total. Call that total the disagreement, and go looking for the spot where it is smallest.

Lab 24 · Slide the cut-out until it fits
Try this firstDrag the dashed window around the picture and watch the disagreement pill. It falls as you get near the cross and lands on zero when you sit exactly on it. The working underneath shows all nine pairs of the spot you are on. Then press Jump to the best spot and see whether the machine agrees with your eye.
Notice that the bright blob scores badly even though it is the most eye-catching thing in the picture. The cut-out is not looking for brightness. It is looking for its own arrangement of nine numbers, and only the cross has that arrangement. A search that compares arrangements can tell apart two things a threshold would lump together.

A small pattern worth searching for is called a feature, and the cut-out you slide is called a template. One more word and the bridge to the rest of the course is built. Write the template's nine numbers in a row, in a fixed order, and you have a list. A list of numbers in a fixed order is called a vector. The window under the template gives another vector, and matching is comparing two vectors, number by number. Hold on to that. Every learned model in the steps ahead spends its whole life comparing vectors.

What if the thing is a bit bigger, or turned, or in different light?

Then the nine numbers under the window stop lining up with the template, and the disagreement rises even though a person would say the thing is plainly there. A template is rigid. Classical systems cope by searching again with bigger and smaller copies of the template, and sometimes rotated ones, which multiplies the work.

This rigidity is the honest limit of the method, and it is the exact itch that learned features scratch. The next step is about machines that tune their own templates until the match survives a change of size, angle and light.

Why measure disagreement instead of agreement?

Habit and hand-arithmetic. Subtract, ignore the sign, add up: every part of that is easy with a pencil, and zero meaning a perfect fit is easy to remember. You could just as well multiply each pair and add the answers up, so bigger means better. That version is exactly the multiply-and-add of convolution from Step 3, with the template as the kernel.

The two scores usually point at the same spot. Real systems use the multiply-and-add form more often, because the same hardware that does convolution then does matching for free.

Is this how a phone finds faces?

The early ones worked very close to this. A famous method from 2001 slid thousands of tiny light-and-dark templates over the picture and let each one vote. It found faces in real time on the cameras of the day, and it still ships in cheap hardware.

Modern systems learn their features instead of taking them from a designer, and they tolerate glasses, beards and bad light far better. The shape of the job has not moved: turn a patch of picture into a vector, compare it against vectors you trust, act on the best score.

Lab 25 · The disagreement map is another grid of numbers
Try this firstLook at the right-hand picture: it is the disagreement at every spot, drawn as a picture, dark where the fit is good. Press Numbers on it to see the scores themselves. Then drag the "call it found" level up from zero and watch how many spots count as a find.
Notice that you have seen this move before. Score every position, then cut the scores at a level: that is Step 7 again, run on scores instead of brightness. Vision keeps reusing its own small moves, and a low level keeps only the true cross while a generous one starts accepting places that merely resemble it.
A template of a bright cross finds its cross perfectly all morning. In the afternoon the room dims, and every pixel in the scene drops by about 60. The cross has not moved. What happens to the search?
The fit is still best at the cross, and the score is no longer near zero. Nine pairs, each about 60 apart, is a disagreement of about 540 at the true spot. This is Step 7's lesson wearing a new coat. A number written into the program was really a fact about the light. The fixes rhyme too: measure the scene and adjust, or compare in a way that ignores overall brightness, and learned features lean on both.
Step 14

Learned features: templates the training tuned

Everything so far was designed by a person. Somebody chose the blur weights, the Sobel weights, your templates. A model is a machine full of such weights where nobody chooses the numbers. They start random. Training shows the model many pictures with known answers. After each wrong guess, every weight is nudged a little in the direction that would have made the guess better. Millions of pictures later, the weights hold patterns that work, and nobody typed them in.

One family of models, the convolutional neural network, or CNN, is built from the sliding windows of Step 3, stacked in layers. The first layer's kernels end up as little templates for edges and spots. Later layers slide their windows over the answers of earlier ones. So they respond to arrangements of arrangements: a corner made of edges, a wheel made of corners. The features are learned for the task rather than named in advance.

Another family, the vision transformer, cuts the picture into square patches. Each patch becomes a vector, in the Step 13 sense, and each vector is called a token. Layers of attention then let every token compare itself with every other token, however far apart their patches sit in the picture. A convolution starts local. Attention starts everywhere at once, and pays for it, which is what the lab below counts. Many real systems mix both ideas, so CNN and transformer name families, not two sealed recipes.

What does it mean to reuse a trained model?

Pretraining fits a model once, on an enormous pile of varied pictures, at a cost only a large lab pays. The learned features, edges, textures, parts and arrangements, are useful for many jobs beyond the one they were trained on. Starting a new task from those weights instead of from random ones is called transfer learning.

It saves data and time whenever your pictures resemble the pile. It also imports the pile's blind spots and habits, silently. A model that rarely saw night-time pictures brings that gap with it into your night-time task, which is why the course ends on testing.

Why does patch size change the cost so quickly?

A 224 by 224 picture cut into 16 by 16 patches gives 14 patches across and 14 down, which is 196 tokens. Plain attention forms a score for every ordered pair of tokens. That is 196 times 196, or 38,416, pair scores in one layer, before anything else is counted. Cut the patch side to 8 and there are four times the tokens and about sixteen times the pairs.

Real models blunt this cost with windows, pooling and sparser attention. The lab counts the plain all-pairs version, as a baseline, not as a claim about every model.

Lab 26 · Counting patch tokens
Try this firstSet the image to 224 pixels and compare 16-pixel patches with 8-pixel patches. The drawing shows the patch grid and one patch's conversations with every other patch. Watch the token count, then the all-pairs count, and work out why the second grows so much faster than the first.
Notice that the two counts describe different operations, so this is not a race between them. A window reads nine neighbours per pixel. Attention scores every pair of tokens. The point of the numbers is to make the cost of "everything looks at everything" visible before hardware and clever tricks hide it.
For a fixed square image, the patch side is cut in half. What happens to the number of patch tokens and the number of plain attention pairs?
Four times the tokens, sixteen times the pairs. Two across times two down is four, and all-pairs squares whatever the token count does. This is why picture size, patch size and attention design are all part of a model's cost, and why nobody runs plain attention on every pixel.
Step 15

Match a picture to a sentence by comparing two vectors

An image-text model has two halves. One half, the image encoder, boils a whole picture down to one vector. The other half does the same to a short piece of text. Training feeds the pair machine millions of pictures with their captions. It nudges the weights so a picture's vector and its own caption's vector point in nearly the same direction, while strangers' vectors point apart. Direction is the whole trick: agreement between two vectors is measured the same way you compared template and window, only with hundreds of numbers per list instead of nine.

Once trained, hand it a new picture and several candidate sentences. Score each sentence by how closely its vector agrees with the picture's vector, and the best scorer acts as a label. Nobody fixed a list of allowed labels in advance. Ask about "a rusty bicycle" and the question is legal, whether or not the answer is any good. Labelling with no new training, just comparison, is called zero-shot.

The score needs respect. It says two vectors point in similar directions, and nothing more. It does not prove the sentence is true, or that the model noticed everything, or that it looked at the part you care about. Reword the sentence and the score moves. The lab's temperature slider stretches the shares apart or squashes them together without adding one drop of evidence.

Does "open vocabulary" mean the model knows every possible object?

No. It means the category you want can be typed in as words rather than picked from one fixed list. Whether the answer is any good still depends on what the training pairs contained. Rare objects, specialist terms, odd viewpoints and things local to one culture can all score nonsense, in fluent confidence.

So evaluate with several sensible phrasings, write down the exact wording you used, and keep a none-of-the-above escape. A model forced to pick the nearest label will pick one even when every candidate is wrong.

What about models that write whole sentences about a picture?

A generative vision-language model, or VLM, adds a writing half. A common design turns the picture's features into tokens that a language model can read, then writes its answer one token at a time. One interface can then describe a scene, answer a question about it, or read a diagram.

It can also write a fluent answer the pixels do not support, with no change of tone. For measuring, counting or any safety decision, its words need checking against a defined task. Often a plain tool, a ruler in code, does the measuring, and the model only points.

Lab 27 · Matching one image vector to text
Try this firstSwitch among the three image vectors and watch the bars. The drawing shows each vector as three bars, the agreement between each sentence and the picture, and each sentence's share of the vote. Then drag the temperature and check which bars move and which stand still.
Notice that temperature moves the shares and never the agreements. The vectors here are three numbers long so you can check every score with a pencil. Real encoders use hundreds of numbers per vector, learned from data, and the arithmetic is the same. A share of the vote is not evidence. It is a way of spreading the same evidence across the candidates you happened to offer.
An image-text model gives 74% of its vote to the sentence "a damaged bridge". What has that number established?
It is a relative score, not a fact about the bridge. The model ranked the sentences you offered, nothing more. Deciding the bridge is damaged takes a defined inspection task, suitable data and independent evidence. Treat the 74% as one measurement that means something only inside a tested procedure.
Step 16

Detection, segmentation and tracking answer different questions

Learned vision jobs come in a few shapes, and the shape decides what you can do with the answer. Classification puts one label on a picture: cat, no cat. Detection adds where, as a box around each thing it found, with a label and a score. Segmentation answers per pixel: in the thing, or not, which gives an exact outline called a mask. Tracking, which you built in Step 11, links the same thing from frame to frame. One modern system may do several of these at once, but its output shape still decides what can be measured downstream.

The request also has a shape. The part of a request you supply at run time is called a prompt. It can be words: an open-vocabulary detector takes "red-handled tool" and returns boxes whose features match the phrase. It can be spatial: a point, a box or an earlier mask, meaning this one, the thing I am touching. Words answer "which kind of thing". A point answers "which thing". The two kinds of question need different prompts, and mixing them up produces confident answers to the wrong question.

For video, a segmentation model can keep a memory of the objects you picked and carry their masks forward into later frames. That saves you clicking on every frame. It also means an error is carried forward with the same loyalty. Re-prompting, confidence checks and an honest lost-track state remain necessary, exactly as they were for the little tracker in Step 11.

Why keep boxes if masks describe the shape more precisely?

Boxes are cheaper to label, store and process, and many decisions only need a rough where. A robot may need a mask to plan its fingers around a handle, and only a box to decide which shelf the object is on. Match the precision to the decision instead of maximising it out of habit.

Promptable masks also need a rule for ambiguity. One point on a cup's handle could mean the handle, the cup, or the cup with its handle. A good system returns several candidate masks, or asks for a second point, instead of hiding the doubt behind one confident outline.

What does the score beside a detection box mean?

It is the model's own confidence that the box holds what the label says, on a scale it learned during training. It behaves like the vote shares of Step 15: useful for ranking, dangerous to read as a physical probability. A threshold on the score decides which boxes you keep, and that threshold is a dial you own, not a fact of nature.

Set it high and you miss real things. Set it low and you accept junk. The last step of the course measures exactly that trade, under the conditions where the system will actually run.

Lab 28 · A point defines the requested region
Try this firstPlace the point inside the left shape, then inside the right one, by touching the picture or with the sliders. The returned mask follows your point: same picture, different answer, because the prompt changed. Then make both shapes the same brightness, widen the prompt reach, and watch for the moment the toy rule can no longer keep them apart.
Notice that the picture alone never said which object you meant. The lab states its simple rule, keep nearby pixels of similar brightness, so it is not a demonstration of any particular model. What it demonstrates is the contract: one image can support several valid masks, and the prompt picks which one is being requested.
A promptable segmenter returns a clean mask around an unfamiliar machine part after one click. What can be concluded from that result alone?
A mask is a spatial answer, not a name. The click asked "which region", and that is the question the model answered. What the part is, what state it is in and what to do about it are separate questions. Keep recognition, geometry and safety checks as their own explicit stages rather than reading them all into one clean outline.
Step 17

Adapt the smallest part that fixes the measured problem

Every weight a model stores is called a parameter, and a useful vision model carries millions to billions of them. Suppose a pretrained model nearly works on your task, and not quite. You now own a dial that runs from touching nothing to retraining everything. Leave the model frozen and just choose better prompts. Train a small task head, a little model bolted onto the frozen one's vectors. Train an adapter: a thin packet of new parameters, like LoRA, slipped in beside the frozen ones. Or fine-tune everything, which rewrites every parameter and needs the most data, memory and care.

This is a choice about evidence, not a ladder you must climb to the top. If the frozen model's vectors already separate your cases, a small head is enough, and cheap to retrain when the world drifts. Full fine-tuning earns its keep only when a fair test shows the smaller changes falling short. The bigger the change, the more you can also break: behaviour that used to work has no loyalty to survive a retrain.

Split your data before any fitting, and split it honestly. Two frames from the same video are near twins. Let one into the training pile and the other into the test pile, and the model can score well by memory alone, which makes memorisation look like understanding. Keep each object, person, place and video sequence entirely on one side of the boundary. Include the hard negatives, and the conditions where the right answer is "I do not know".

What does a low-rank adapter actually change?

A big block of parameters in the model is a grid of numbers, wide in both directions. LoRA does not edit the grid. It writes the change as two thin strips multiplied together, one tall and narrow, one short and wide. The strip thickness is called the rank. Thin strips hold far fewer numbers than the grid they adjust, which is the entire saving.

What shrinks is the count of trainable numbers and the optimiser bookkeeping around them. The frozen model still has to run in full, and you still need honest examples of your task. Exact counts depend on which blocks get adapters, which is what the lab lets you vary.

When is the right answer to change nothing at all?

When the missing knowledge changes faster than you could retrain. A model that must know today's stock levels or this week's part numbers should look facts up at run time. That is called retrieval, and it beats baking facts into parameters that go stale. Training teaches habits well and facts badly.

And when the failure is really a data problem. A detector failing at night is not cured by rank 16 instead of rank 8. It is cured by night examples, or by admitting the system does not run at night. Measurement first, adaptation second is the honest order.

Lab 29 · Counting adapter parameters
Try this firstDouble the rank and watch both the drawing and the trainable count. The drawing shows the frozen block and the two thin strips to scale. Then double the number of adapted blocks and check the count doubles again. Compare everything against the frozen base count.
Notice how thin the strips stay even at generous ranks. The lab uses one stated formula so every number on it can be checked by hand. A real training plan gets its exact parameter and memory counts from the chosen model and framework. The shape of the argument stays the same: pay for the smallest change that measured evidence supports.
A pretrained detector fails only on one factory's unusual camera angle. Which is the sound first experiment?
Measure the boundary, then adapt. The test must stand for what the system will actually face: new sequences, that site's angle, its lighting. Only then can a small head, an adapter and a full fine-tune be compared fairly. Each larger step then has to earn its extra cost on that test, rather than on faith.
Step 18

Evaluate the vision system under the conditions where it will run

Before any score means anything, two words need pinning down, and they are worth pinning because every published result leans on them. Precision asks: of the things the system flagged, how many were real? Recall asks: of the real things that were there, how many did it flag? A smoke alarm that shrieks at toast has poor precision. One that sleeps through a fire has poor recall. Every detector trades one against the other with its score threshold, and quoting either number alone hides the trade.

One combined score can also hide a failed condition. A detector can be excellent by day, poor at night, and report a flattering average because the test set was mostly daylight. So report slices: the same measurements cut by lighting, distance, camera, weather and whatever else the operating domain cares about. Keep the number of examples beside every percentage. A recall of 90% from ten examples is a shrug, not a measurement.

Finally, test the whole path, not the model alone. Capture delay, resizing, the model's own latency, post-processing, tracking, the decision threshold, the actuator's deadline. A learned component proposes a box, a mask or a sentence. Plain code you can read should still enforce the safety limits: permissions, geometry, stopping distance, and a defined fallback for the moments when no score deserves trust. The classical tools from the first half of this course keep earning their place here, because their contract can be checked directly.

Lab 30 · One score can hide a failed slice
Try this firstLower the night true positives and raise the night misses. The bars show day, night and combined recall side by side. Watch the combined bar stay respectable while the night bar collapses. Then imagine that night is when the safety feature matters most.
Notice that the combined bar is always propped up by the better slice. Choose the slices before looking at any results, and choose them from the operating domain and the plausible ways of failing. A slicing chosen afterwards, to make the model look good, is not evaluation. It is marketing.
A practical order for a vision project
  1. Write down the required output, the speed it is needed at, the operating conditions and the safe fallback.
  2. Build a small classical or frozen-pretrained baseline, and freeze a test set.
  3. Choose a model shaped like the task: classifier, detector, segmenter, embedding model or VLM.
  4. Try prompts or a small head before adapters, and adapters before a justified full fine-tune.
  5. Evaluate by slice, read the errors one by one, measure the deployed path, and keep a way back to the previous version.

New model families keep changing which baseline is practical. They do not change the need to specify, split, measure and fail safely.

Why read the errors one by one when the metrics are already sliced?

Because a number tells you how often the system fails and never why. Twenty missed detections could be twenty different accidents. They could also be one systematic blindness wearing twenty costumes: every miss at dusk, every miss beyond ten metres, every miss of the one dark part. The pattern is visible in ten minutes of looking and invisible in the summary.

The habit also catches broken tests. A miss that turns out to be a mislabelled example is not a model failure. Finding a few of those early saves weeks of tuning against a wrong answer key.

A robot's detector reports 96% accuracy on a shuffled collection of saved frames. What is the most important missing evidence before deployment?
Evaluate the boundary the robot will face. A shuffled frame test mostly measures memory, because the twin of a test frame was probably in training. New sequences, honest slices, whole-path timing and a stated fallback are what deployment rests on, and 96% on the wrong test is not any of them.

What you can now account for

  • Pixels, clipping, convolution, filtering, gradients, thresholds, blobs and motion.
  • Templates and features, and why comparing vectors is the recurring move.
  • The difference between learned convolutional features and patch-token attention.
  • What image-text similarity scores do and do not establish.
  • The separate contracts of classification, detection, segmentation and tracking.
  • When to use a frozen model, a task head, an adapter, a full fine-tune or retrieval.
  • Leakage-safe splits, operating-condition slices, latency and safe fallback.