# OpenCV SSD Face Detector (UINT8) Single-shot face detection with the OpenCV SSD ResNet-10 network. The model ships in the OpenCV project as a quantized frozen TensorFlow graph (`opencv_face_detector_uint8.pb`) and is converted here to ONNX for use with OpenCV's DNN module. Only the backbone is exported — PriorBox generation, the confidence softmax, variance decode, score threshold and NMS are run in host code (see `demo.py` / `demo.cpp`). ## Model Details - **Architecture**: SSD with a ResNet-10 backbone (face detector) - **Input**: BGR image, 300×300, mean-subtracted by `[104, 177, 123]` (no scaling, no RGB swap), NHWC layout (`data:0`, shape `[1, 300, 300, 3]`) - **Output**: `mbox_loc` (`[1, 35568]`, box regressions) and `mbox_conf_flatten` (`[1, 17784]`, 2-class face/background logits); PriorBox decode + softmax + NMS are done in the demo - **Framework**: ONNX (converted from the TensorFlow frozen graph — uint8 weights with the `Dequantize` nodes folded to float `Const` — via tf2onnx, opset 18) - **Original weights**: https://github.com/opencv/opencv_3rdparty/raw/8033c2bc31b3256f0d461c919ecc01c2428ca03b/opencv_face_detector_uint8.pb The 6 SSD prior layers (min/max size, aspect ratios, step, feature-map size), the variances `[0.1, 0.1, 0.2, 0.2]`, the default confidence threshold `0.4` and the NMS IoU `0.3` are all defined in the demo scripts. ## Usage ### Python ```bash python demo.py --model opencv_face_detector_uint8_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png --conf 0.4 ``` Or import directly: ```python import cv2 net = cv2.dnn.readNet("opencv_face_detector_uint8_2026jul.onnx") # see demo.py for the full PriorBox decode + softmax + NMS pipeline ``` ### C++ The C++ demo runs inference with OpenCV's DNN module. Adjust the OpenCV paths to your setup: ```bash OCV=/path/to/opencv # OpenCV source tree OCVBUILD=/path/to/opencv/build # OpenCV build directory (generated headers + libs) g++ -std=c++17 demo.cpp -o demo \ -I$OCV/include \ -I$OCV/modules/core/include \ -I$OCV/modules/dnn/include \ -I$OCV/modules/imgproc/include \ -I$OCV/modules/imgcodecs/include \ -I$OCVBUILD \ -L$OCVBUILD/lib -Wl,-rpath,$OCVBUILD/lib -lopencv_dnn -lopencv_imgcodecs -lopencv_imgproc -lopencv_core ./demo --model opencv_face_detector_uint8_2026jul.onnx --image example_outputs/input_image.png --output example_outputs/output_image.png ``` ## Conversion The ONNX model was exported from the frozen TensorFlow graph with tf2onnx (opset 18) via [convert_to_onnx.py](./convert_to_onnx.py). The `.pb` stores its weights behind `Dequantize` nodes, so the script first folds every `Dequantize` node to a float `Const` before conversion. Inputs `data:0`, outputs `mbox_loc:0` and `mbox_conf_flatten:0`, input shape overridden to `[1, 300, 300, 3]`. Requires `tensorflow`, `tf2onnx`, and `onnx`. ```bash python convert_to_onnx.py --pb ../pb/opencv_face_detector_uint8.pb ``` ## License See [LICENSE](./LICENSE) — this is the OpenCV face detector distributed via `opencv_3rdparty` under the Apache License 2.0.