Face detection sits at the entry gate of most computer vision pipelines. Every video call, photo gallery, and security feed depends on spotting human faces before anything else can happen. Yet the choice of model usually forces an unhappy trade-off. Heavy networks offer accuracy but demand expensive GPUs and rack-mounted cooling. Smaller models run on modest hardware yet often choke on small faces or high-resolution feeds. The YuNet model from the OpenCV Zoo breaks that pattern. I spent time benchmarking it across different scales to see whether it earns a place in real projects or merely looks good on paper.

Why YuNet Deserves a Closer Look

YuNet is not a research curiosity. It lives inside the OpenCV Zoo, a collection of pre-trained models optimized for the OpenCV DNN module. The specific variant I tested uses INT8 quantization, which means its weights and activations compress down to 8-bit integers instead of the usual 32-bit floating-point numbers. That is not a minor technical footnote. INT8 slashes memory bandwidth, reduces cache pressure, and allows modern CPUs to chew through inference without breaking a sweat. For anyone building on a laptop, an edge device, or a server without a dedicated graphics card, this efficiency is the difference between a smooth pipeline and a slideshow.

The architecture itself is lightweight by design. It skips the baggage of enormous backbones and focuses on the single task of locating faces. That discipline pays off when you need to integrate detection into a larger application where CPU and battery budget are shared with tracking, recognition, or video encoding.

The Setup

All tests ran on a Mac Studio with an Apple M4 Max chip. The model file was the YuNet INT8 quantized ONNX build from the OpenCV Zoo repository. I measured inference speed on a 1280x720 image first, then compared detection counts across four different input resolutions to understand how scale affects results.

If you want to verify these numbers on your own machine, the process is fully reproducible. Run the following commands to pull the sparse repository and execute the benchmark:

git clone --depth 1 --filter=blob:none --sparse https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .gitignore .mise/tasks Makefile mise.toml 2026/07/08/yunet-face-detection
mise -C 2026/07/08/yunet-face-detection run

The sparse checkout keeps the download small, and the mise task runner handles dependencies behind the scenes. You do not need to wrestle with Python environments or manual package installations.

Speed That Stays Consistent

On a 1280x720 image, the INT8 YuNet model averaged 9.21 milliseconds per inference. The quickest pass clocked in at 8.03 ms, while the slowest touched 10.47 ms. That is a remarkably tight band. Less than two and a half milliseconds separate the best and worst times.

In practice, this consistency matters more than bragging rights. Real-time applications do not just need low average latency; they need predictable latency. A model that sometimes takes 50 ms creates visible stutter in a webcam feed. YuNet stays flat. You can rely on it to finish a frame before the next one arrives, which makes scheduling the rest of your pipeline far simpler.

Scale Variance Reveals the Real Story

Raw speed means little if the model misses half the faces in a scene. To test this, I fed the same source imagery through YuNet at four different resolutions. The counts tell a clear story:

  • 320 x 180: 6 faces detected
  • 640 x 360: 26 faces detected
  • 1280 x 720: 38 faces detected
  • 2560 x 1440: 52 faces detected

The jump is dramatic. At 320 x 180, only the largest, closest faces register. Bump up to 640 x 360, and the count quadruples. At full 1440p, YuNet finds more than eight times as many faces as it did at the lowest resolution.

This happens because downsampling destroys detail faster than intuition suggests. A face that covers a modest patch in a 1440p frame can shrink to a smudge of five by five pixels at 360p. Once facial features collapse below the model's receptive field, they become invisible noise. Eyes merge into eyebrows. Noses disappear. YuNet has nothing to grab onto.

The practical upshot is worth remembering. If your camera captures a wide-angle view of a classroom, a conference room, or a street corner, distant faces will not appear unless you give the model enough pixels. Resolution is not just about image quality here. It is a direct lever on recall.

The Resize Strategy You Actually Need

YuNet is fast enough that you do not need to hammer your input down to 320 x 240 out of habit. On the M4 Max, even 2560 x 1440 runs without a dedicated GPU. That changes how you should architect a pipeline.

Instead of forcing every frame through a tiny fixed size, choose your input resolution based on what you are trying to find. If you only care about the person directly in front of the camera, 720p or even 640p is plenty. If you need to catalog every attendee in a large hall, feed the model a higher-resolution crop or the full native frame. Because YuNet is lightweight, you have headroom to make that choice. You are not locked into a single preset to avoid a 200 ms lag.

One caveat does remain. The model still depends on face size relative to the input tensor. There is no magic scale invariance here. Small faces stay invisible unless they occupy enough pixels. The fix is mechanical: resize your source image upward before inference when hunting for distant subjects, then map the resulting bounding boxes back to original coordinates. YuNet gives you the speed budget to afford that step.

Where This Fits in Your Stack

YuNet is not a solution for every conceivable face task. Heavy occlusion, extreme profile angles, or 3D mesh extraction are outside its scope. But for the bread-and-butter work of locating faces in photos and video streams, it occupies a sweet spot. Real-time webcam apps, automated photo culling tools, and modest embedded systems all benefit from a detector that runs fast on standard CPUs.

The INT8 ONNX format also makes deployment painless. You do not need to install PyTorch or TensorFlow on the target device. OpenCV's DNN module loads the model directly, which keeps your binary small and your dependency tree shallow.

The Bottom Line

YuNet proves that face detection does not require industrial hardware or bloated frameworks. The numbers speak plainly: under ten milliseconds for a 720p frame, and a direct, predictable boost in detection count as resolution rises. You get to choose whether you want maximum speed at moderate resolution or broader coverage at higher scale, and the model will not punish you for that choice.

If you are building anything that touches real-world imagery, run the reproduction steps above on your own hardware. Test it against your footage. Then tune your resize logic to match the faces you actually need to find. Speed is useful only when you can aim it. YuNet gives you both the velocity and the control.