Start with your phone
You pick up your phone and look at it. Most of the time it unlocks. But two annoying things can happen.
Sometimes it is really you, and the phone still says no. You look again, maybe wipe the camera, and try a second time. Mildly irritating.
The other case is scarier. Imagine the phone unlocked for someone who is not you - say a sibling who looks a little like you. That should never happen, but no system is perfect, so once in a very long while it could.
That is the whole story of this post. Every system that checks "is this the right person?" can make exactly those two mistakes: it can wrongly say no to the real person, or wrongly say yes to the wrong person. Detection Error Tradeoff (DET) analysis is just a neat way to look at those two mistakes and decide how to balance them.
We will go slowly, one small idea at a time, with a picture for each. By the end, words like FAR, FRR and EER will feel obvious, and you will see how the exact same idea shows up in computer vision as precision and recall.
The machine behind the scenes
Before the mistakes, let's see what the machine actually does. It is simpler than you think.
It takes two things and compares them: the face (or fingerprint, or voice) in front of it right now, and the one it has saved for you. Out of that comparison it produces one number, a score. Think of the score as "how alike are these two, from 0 to 1?" A score near 1 means "these look like the same person". A score near 0 means "these look like different people".
Then it needs a rule to turn that score into a yes or no. That rule is a single cut-off number called the threshold. If the score is at or above the threshold, it says yes, accept. If it is below, it says no, reject. That is the entire machine.
Two faces go in, a "how alike" score comes out, and one cut-off line (the threshold) turns that score into yes or no. Everything in this post is about where you put that line.
Here is the catch that makes all of this interesting: the score is never perfect. On a bad day (dim light, a new haircut, a tired face) the real you might score a little low. And two different people who happen to look alike might score a little high. So there is no cut-off line that is right every single time. Wherever you draw it, a few mistakes sneak through. And there are only two kinds.
Two ways to get it wrong
Let's name the two mistakes. Keep the phone in mind.
- Letting the wrong person in. The machine said "yes" when it should have said "no". A stranger got unlocked. We call how often this happens the False Acceptance Rate, or FAR. This is the safety mistake. A high FAR means the system is too easy to fool.
- Turning the right person away. The machine said "no" when it should have said "yes". The real owner got blocked. We call how often this happens the False Rejection Rate, or FRR. This is the annoyance mistake. A high FRR means the system keeps rejecting people who should get in.
That is it. FAR = wrong person gets in. FRR = right person gets blocked. Two mistakes, and every identity system lives somewhere between them.
Now a picture that makes the rest of the post click. Suppose we test the machine thousands of times. Some tests are real matches (you vs your own saved face). Some are fake matches (a stranger vs your saved face). We write down the score each time and stack them up.
The fakes mostly get low scores. The real matches mostly get high scores. So we get two hills. The problem: the hills overlap in the middle. That overlap is exactly where mistakes are born.
The red hill is strangers, the green hill is the real you. The dashed line is your cut-off. See the little bit of red poking past the line on the right? Those are strangers who scored high enough to get in - that is your FAR. See the green spilling left of the line? That is the real you, scoring too low and getting blocked - that is your FRR.
If you like plain numbers, FAR and FRR are just simple fractions:
strangers who still got in
FAR = ----------------------------
all the strangers
real users who got blocked
FRR = ----------------------------
all the real users
For example, a phone might have a FAR of 1 in 50,000 (a stranger gets in that rarely) and an FRR of 2 in 100 (about twice in a hundred tries, you have to look again). Two small numbers, and together they describe the phone far better than a single word like "accuracy" ever could.
The see-saw: you can't win both
Here is the part that trips everyone up, so go slow.
You might think: "just move the cut-off line until both mistakes disappear." You cannot. The two mistakes are on a see-saw. Push one down and the other pops up.
Picture a door guard checking IDs. If the guard is strict (only waves you through when the photo is a dead-on match), almost no stranger gets in - great, FAR goes down. But now the guard also stops the real employee who got a haircut - FRR goes up. If the guard is relaxed (waves through anything close enough), real people breeze in - FRR goes down - but a few lookalike strangers slip past too - FAR goes up.
Moving the cut-off line is exactly turning that "strictness" knob. Let's sweep the knob from relaxed to strict and watch both mistakes at once.
Turn the knob toward strict (move right) and the red line (FAR, strangers let in) drops, while the green line (FRR, real people blocked) climbs. They go opposite ways. Somewhere in the middle, the two lines cross. Remember that crossing point - it is the star of the next section.
EER: one score to rate them all
Look again at where the two lines cross in that last picture. At that one knob setting, the two mistakes happen equally often. FAR and FRR are tied. That tie has a name: the Equal Error Rate, or EER.
Why do people love the EER so much? Because it squeezes the whole balancing act into one single number you can compare at a glance. Think of it like a report card grade for the system.
Say you are choosing between two face-unlock systems. System A has an EER of 2%. System B has an EER of 6%. Lower is better, so System A wins - at its balanced setting it makes fewer mistakes of both kinds. You did not need to stare at two whole graphs; one number told you which is sharper-eyed.
Two things worth knowing so you use it correctly:
- The EER is a report card, not usually the real setting. A bank does not run at the balance point. It cares far more about keeping strangers out than about the odd extra retry, so it deliberately turns the knob stricter than the EER. The EER is there to compare systems, not to tell you where to run one.
- A lower EER means the two hills overlap less. Go back to the two-hills picture. If the stranger hill and the real-you hill barely touch, the crossing point sits very low, so the EER is tiny. A big EER is a warning that the hills smear into each other and the system often cannot tell real from fake.
The DET curve: the whole story in one picture
So far we have two mistakes (FAR and FRR) and one summary grade (EER). The last tool ties them together. Instead of drawing FAR and FRR against the knob, we plot them against each other: FAR along the bottom, FRR up the side. Every dot on the line is one knob setting. Slide the knob and you draw the whole line. That line is the DET curve.
The whole tradeoff as one line. The nearer the line hugs the bottom-left corner (few strangers let in and few real people blocked), the better the system. The dashed diagonal is where the two mistakes are equal, so the EER is just the spot where the curve touches that diagonal.
Here is why this one picture is so handy: to compare two systems, you draw both curves on the same axes. The one whose line sits closer to that bottom-left corner is better, at every setting of the knob, not just at one. So you are not arguing about a single threshold - you can see the whole story and pick the better system outright. (You may also hear of the ROC curve; it is the same idea shown a slightly different way. The DET version is popular because it puts the two "mistakes" on the axes directly, and lower-left simply means better.)
The same idea in computer vision
Now the fun part, and the reason this idea travels so far. Swap "is this the right person?" for "did the model find the object?" and the whole story repeats, just with different names.
Imagine a model that looks at a photo of a tree and tries to circle every apple. For each guess it draws a box and gives a confidence (again, a number from 0 to 1, "how sure am I this is an apple?"). And just like before, it can make two mistakes:
- It circles a leaf it mistook for an apple. That is a false alarm (a false positive). It is the cousin of letting a stranger in.
- It misses a real apple entirely. That is a miss (a false negative). It is the cousin of blocking the real user.
Computer vision usually measures these with two friendly words:
- Precision answers: of everything the model circled, how much was actually an apple? High precision = few false alarms.
- Recall answers: of all the real apples on the tree, how many did the model catch? High recall = few misses.
Think of a fishing net. A big loose net (keep even unsure guesses) scoops up every fish - great recall - but also drags in boots and seaweed, so precision drops. A small tight net (keep only very confident guesses) holds only real fish - great precision - but slips past the ones near the edges, so recall drops. Same see-saw as FAR and FRR, exact same feeling.
And there is the same knob: the confidence threshold. Keep only guesses above a high confidence and you rarely cry wolf (high precision) but you miss the faint apples (low recall). Drop the confidence bar low and you catch every apple (high recall) but circle a lot of leaves too (low precision). Sweep that knob and, just like the DET curve, you can draw the whole tradeoff as one line - here it is called a precision-recall curve.
Sweep the confidence knob and the model walks along this line. Top-left is the tight net (very picky, catches few). Bottom-right is the loose net (catches everything, lots of junk). The dream is the top-right corner: catch every apple and never circle a leaf. Real models never quite reach it, so you pick the spot that fits your job.
This is how you compare and separate two detection models. Draw both precision-recall curves (or both DET curves) on the same axes and look at which line sits in the better corner. A model whose curve stays higher and to the right is catching more real objects without drowning in false alarms - so it wins, and it wins across the whole range of knob settings, not just one lucky threshold. When people want a single number for a leaderboard, they measure the area under that curve (often called average precision, and mAP when averaged over many object types). It is the exact same spirit as the EER: boil the whole tradeoff down to one score so two models can be ranked side by side.
Here is the little dictionary between the two worlds. It is the same two mistakes the whole way down:
| Face-unlock world | Object-detection world | Plain meaning | |---|---|---| | Stranger let in (false accept) | False alarm (false positive) | flagged something that was not there | | Real user blocked (false reject) | Miss (false negative) | missed something that was there | | Lower FAR | Higher precision | fewer false alarms | | Lower FRR | Higher recall | fewer misses | | The cut-off line (threshold) | The confidence threshold | the strictness knob | | DET curve | Precision-recall curve | the whole tradeoff as one line | | EER (balance point) | balanced score / area under the curve | one number to rank models |
Try it yourself in Python
You do not need a heavy library for any of this. If you have a pile of scores for real matches and a pile for fakes, every number above is a couple of lines.
import numpy as np
# Pretend data: real matches score high, fakes score low, but they overlap.
rng = np.random.default_rng(0)
real = rng.normal(0.68, 0.11, 5000) # the real person, tested many times
fake = rng.normal(0.32, 0.11, 5000) # strangers, tested many times
# Try every possible cut-off line from 0 to 1.
lines = np.linspace(0, 1, 1000)
# FAR = fakes that still scored above the line (strangers let in).
far = np.array([np.mean(fake >= t) for t in lines])
# FRR = real matches that fell below the line (real users blocked).
frr = np.array([np.mean(real < t) for t in lines])
# EER = the line where the two mistakes are closest to equal.
i = np.argmin(np.abs(far - frr))
print(f"Balanced cut-off : {lines[i]:.2f}")
print(f"EER (its grade) : {(far[i] + frr[i]) / 2 * 100:.1f}%")
Reading it in plain words:
realandfakeare the two hills from the first picture - one pile of scores for the real person, one for strangers.np.mean(fake >= t)is just "what fraction of strangers scored above this line?" - that is the FAR, the red area poking past the line.np.mean(real < t)is "what fraction of real users fell below the line?" - that is the FRR, the green spilling to the left.- Trying every
tinlinesis sweeping the strictness knob - it draws both crossing lines. np.argmin(np.abs(far - frr))finds where the two mistakes are closest to equal. That is the crossing point, the EER.
The computer-vision version is the same shape: swap "fakes" and "real matches" for "false alarms" and "real objects", and swap FAR/FRR for precision and recall.
The one thing to remember
If you forget everything else, keep this: no setting makes both mistakes go away. You only get to choose where to stand on the see-saw.
- FAR and FRR are the two mistakes: a stranger let in, or the real person blocked. They always move in opposite directions as you turn the knob.
- EER is the tie point where the two mistakes are equal - one tidy grade for comparing whole systems, even though you rarely run at that exact setting.
- The DET curve shows every knob setting at once. Where you choose to stand depends on what you fear more: letting the wrong person in, or annoying the right one.
- And it is not just faces. In computer vision the very same see-saw becomes precision vs recall, drawn as a precision-recall curve, and it is how we decide which detection model is actually better.
Once these click, a sentence like "this model has a lower EER" or "this detector has higher precision at the same recall" stops sounding like jargon. It is just a precise way of saying: here is how well it tells real from fake, and here is where we chose to stand.
For a hands-on companion that actually produces the kind of detections these scores grade, see my Computer Vision with OpenCV and YOLOv8 project.
Tech stack
- Python with NumPy - the knob sweep and every rate is a one-line array operation
- Matplotlib (optional) - to redraw the two hills, the crossing lines, and the curves from your own data
- scikit-learn -
roc_curveandprecision_recall_curvegive you these sweeps for free if you would rather not hand-roll them - Simple bell-curve math was used to draw the honest, smooth shapes on this page
Reference
- DET curves (original paper) - Martin et al., NIST
- NIST FRVT - Face Recognition Vendor Test, FAR/FRR benchmarks
- Precision and recall - scikit-learn precision_recall_curve
- scikit-learn ROC - roc_curve documentation