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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
A practical order for a vision project
- Write down the required output, the speed it is needed at, the operating conditions and the safe fallback.
- Build a small classical or frozen-pretrained baseline, and freeze a test set.
- Choose a model shaped like the task: classifier, detector, segmenter, embedding model or VLM.
- Try prompts or a small head before adapters, and adapters before a justified full fine-tune.
- 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.
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.