With all the buzz surrounding AI recently, OpenCV has been quietly evolving, adding a range of powerful new features. The OpenCV DNN module, in particular, has matured beautifully, aging like fine wine. As of November 2025, we can see several exciting additions in the latest release. But does it still deliver the same impact as before, or has it lost its edge? Continue reading to find out.
In this blog post, we’ll cover:
- Basics of the OpenCV DNN Module
- Perform object detection with YOLOv8 Model
Table of contents
1. What Is the OpenCV DNN Module?
The OpenCV DNN (Deep Neural Network) module is a high-performance, cross-platform engine that enables you to run deep learning models directly inside OpenCV. It acts as a universal inference interface, allowing you to load and execute pre-trained models from popular frameworks like TensorFlow and PyTorch.
Unlike deep learning frameworks that focus on model training and research, OpenCV’s DNN module is designed specifically for inference. This makes it lightweight, fast, and ideal for deployment on edge devices.
What’s New in OpenCV DNN?
Right now, the DNN module has evolved into a powerful inference backend with improved hardware acceleration, support for FP16 precision, broader ONNX compatibility, and tighter integration with OpenVINO, CUDA, and ARM NN. Let’s look at new additions in the table below.
| Category | Feature/Improvement | Description & Impact |
|---|---|---|
| Model Support | Better ONNX Coverage | Broader support for modern ONNX operators and dynamic shapes, improving model import from TensorFlow and PyTorch. |
| Model Zoo Expansion | The official library of ready-to-use models is growing, giving more optimized models for detection, segmentation, and vision-language tasks. | |
| Performance & Optimization | FP16 Precision Support | Added support for 16-bit floating point (FP16) inference, improving speed and reducing memory usage on compatible hardware. |
| Hardware Acceleration | ARM NEON Optimization | Improved performance and lower latency on ARM-based boards such as Raspberry Pi 4 and NVIDIA Jetson. |
| OpenVINO Integration | Deeper integration with Intel’s OpenVINO toolkit for high-speed inference on CPUs, iGPUs, and VPUs. | |
| API & Core | Cleaner DNN API | Simplified, more consistent C++/Python API for easier model loading and backend switching. |
| New layers/cleanups | New layers (e.g., Reduce, ROIAlign, TopK), bug fixes, and codebase cleanup for maintainability |
2. Why Choose the OpenCV DNN Module?
With OpenCV’s new release in 2025, the DNN module has matured a lot. The following are a few advantages of working with DNN module.
- Super easy to set up
- Lightweight and framework-agnostic
- Optimized performance on CPUs and edge devices
- Native C++ and Python support
- Flexible Hardware and accelerator support
- Support for legacy frameworks
2.1 Lightweight and Framework-Agnostic Deployment
The DNN module is a standalone inference engine that eliminates the overhead of large deep learning frameworks:
- Zero Dependency: Installation of TensorFlow, PyTorch, or ONNX Runtime is not required to run a model.
- Universal Model Support: It loads models from virtually any framework (PyTorch, TensorFlow, Caffe) primarily through the universal ONNX format.
- Simple API: Loading and running models can be done with just a few lines of code, making deployment easy for desktop apps and quick tests.
2.2 Optimized for Edge Devices
For the growing field of edge computing, the DNN module is a perfect fit due to its efficiency on constrained hardware:
- Edge Hardware Performance: It performs exceptionally well on devices like Raspberry Pi, NVIDIA Jetson, and ARM-based devices.
- Quantization Support: It natively supports smaller, optimized models (like INT8 and FP16), which significantly boost Frames Per Second (FPS) on systems with limited power, achieving practical speeds (e.g., 10–15 FPS on a Raspberry Pi 4).
2.3 Flexible Hardware and Accelerator Support
OpenCV DNN acts as a universal deployment layer, offering extensive hardware backend support for maximum flexibility:
- Multiple Backends: It supports a wide range of hardware and acceleration libraries:
- CPU (default)
- CUDA / TensorRT (for NVIDIA GPUs)
- OpenVINO (for Intel hardware)
- CoreML (for Apple devices)
- Vulkan (cross-platform GPU API)
- ARM Compute Library
- Dynamic Switching: Developers can switch between targets with two simple function calls, making it easy to deploy the same model across diverse platforms.
2.4 Native C++ Performance Advantage
Today, when all Deep learning pipelines are using Python, OpenCV DNN is the only platform facilitating C++ development. Meaning, you can build faster pipelines where Python versions fall behind due to latency.
For the scope of this blog post, we will also share the C++ code along with downloadable code.
2.5 Native and Legacy Framework Compatibility
While ONNX is the future, the DNN module still maintains support for older and framework specific model types.
| Framework | Required Files | When to Use It | Modern Recommendation |
|---|---|---|---|
| Caffe | .caffemodel (weights) + .prototxt (architecture) | Use this for older, classic models (like AlexNet or GoogLeNet). | Use Caffe’s native format. |
| Tensorflow | .pb (frozen graph) + .pbtxt (graph definition) | Use this for legacy TensorFlow frozen graphs. | Convert to ONNX for modern TensorFlow formats (like .h5). |
| Pytorch | .t7 or .net (legacy files) | The legacy formats are still supported. | Convert to ONNX for the best performance and compatibility with all modern PyTorch models. |
| Darknet | .weights (weights) + .cfg (configuration) | Use this for older YOLO versions (like v3 and v4). | Convert to ONNX for YOLOv5 and newer versions. |
3. Object Detection using OpenCV DNN and YOLOv8
While the SSD-based object detection example demonstrated how OpenCV’s DNN module efficiently handles traditional TensorFlow models, modern computer vision applications often demand real-time performance and higher accuracy. This is where the YOLO (You Only Look Once) family of models truly shines.
Over the years, YOLO has evolved through multiple generations, developed by Ultralytics. Each version introduced improvements in model architecture, feature extraction, and detection speed. With the latest OpenCV DNN module (v4.x), we can now run YOLOv ONNX models directly without needing the Ultralytics Python package or PyTorch runtime. This means faster deployment, lightweight dependencies, and full portability across platforms.
In this demonstration, we’ll use a YOLOv8 ONNX model with OpenCV’s DNN API to perform real-time object detection on an image.
The following code loads the model, preprocesses the image using letterboxing, performs inference, and visualizes the detected objects, all using standard OpenCV functions.
3.1 Import Required Libraries
import cv2
import numpy as np
import time
import psutil
3.2 Load YOLOV8 ONNX Model
Loads the YOLOv8 model in .onnx format. You will find the model in the downloaded code folder. Alternatively, the model can be downloaded using this link. The following code snippet loads the YOLOv8 Nano model from the directory.
model_path = "yolov8n.onnx"
net = cv2.dnn.readNet(model_path)
3.3 Set Backend and Target
Here, we are configuring OpenCV’s DNN backend for computations. To use CUDA backend, the following conditions must be satisfied.
- You have an NVIDIA GPU
- OpenCV has been built from source with CUDA enabled.
Check out this article on How to install OpenCV CUDA. Otherwise, you can simply use the CPU backend without much worry. Comment out/in the following lines as required.
# Use CPU (you can switch to CUDA if available)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
#net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
3.4 Load COCO Class Labels
The following snippet reads the COCO dataset class names. Each detected object will be labeled using these names, e.g., “person”, “car”, “dog”, etc. This text file is being supplied within the code folder.
with open("coco.names", "r") as f:
class_names = [line.strip() for line in f.readlines()]
3.5 Image Preprocessing with Letterboxing
- YOLOv8 requires inputs to be square (e.g., 640×640) while keeping the original aspect ratio.
- letterbox() resizes the image and adds padding to fill any remaining space.
- Returns the resized image, scaling ratio, and padding offsets (dw, dh) needed to map detections back to the original image.
def letterbox(img, new_shape=(640, 640), color=(114, 114, 114)):
shape = img.shape[:2]
ratio = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
new_unpad = (int(shape[1] * ratio), int(shape[0] * ratio))
dw = new_shape[1] - new_unpad[0]
dh = new_shape[0] - new_unpad[1]
dw /= 2
dh /= 2
img_resized = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
top, bottom = int(round(dh)), int(round(dh))
left, right = int(round(dw)), int(round(dw))
img_padded = cv2.copyMakeBorder(
img_resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color
)
return img_padded, ratio, left, top
3.6 Running Detection with OpenCV DNN
- Memory and time measurement: Tracks resource usage for analysis.
- Preprocessing: Applies letterbox resizing and creates a blob using cv2.dnn.blobFromImage().
- Normalizes pixels to [0,1] with 1/255.0.
- Swaps R and B channels (swapRB=True) because OpenCV uses BGR format by default.
- Inference: net.forward() runs the YOLOv8 model on the preprocessed image.
- YOLOv8 outputs a large tensor containing bounding box predictions, confidence scores, and class probabilities.
def detect_objects(frame, display_width=800):
input_size = 640
# Measure start memory & time
process = psutil.Process()
mem_before = process.memory_info().rss / (1024 ** 2)
start_time = time.time()
# Preprocess
img_letterboxed, ratio, dw, dh = letterbox(frame, new_shape=(input_size, input_size))
blob = cv2.dnn.blobFromImage(
img_letterboxed, 1/255.0, (input_size, input_size), swapRB=True, crop=False
)
net.setInput(blob)
# Inference
outputs = net.forward()
# Measure end time & memory
end_time = time.time()
mem_after = process.memory_info().rss / (1024 ** 2)
inference_time = end_time - start_time
mem_used = mem_after - mem_before
# Post-processing
H, W, _ = frame.shape
boxes, confidences, class_ids = [], [], []
# Handle output shape variations
if len(outputs.shape) == 3 and outputs.shape[1] == 25200 and outputs.shape[2] == 85:
output = outputs[0]
elif len(outputs.shape) == 3 and outputs.shape[1] == 84 and outputs.shape[2] == 8400:
output = outputs[0].T
elif len(outputs.shape) == 3 and outputs.shape[1] == 8400 and outputs.shape[2] == 85:
output = outputs[0]
else:
raise ValueError(f"Unexpected output shape: {outputs.shape}")
for detection in output:
if output.shape[1] == 85:
scores = detection[5:]
objectness = detection[4]
class_id = np.argmax(scores)
confidence = objectness * scores[class_id]
elif output.shape[1] == 84:
scores = detection[4:]
class_id = np.argmax(scores)
confidence = scores[class_id]
else:
continue
if confidence > 0.3:
cx, cy, w, h = detection[0:4]
cx *= input_size
cy *= input_size
w *= input_size
h *= input_size
x = int((cx - w / 2 - dw) / ratio)
y = int((cy - h / 2 - dh) / ratio)
w = int(w / ratio)
h = int(h / ratio)
x = max(0, x)
y = max(0, y)
w = min(W - x, w)
h = min(H - y, h)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
# Apply Non-Maximum Suppression (NMS)
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.3, 0.4)
if len(indices) > 0:
# Draw Boxes and Labels with white background + larger text
for i in indices.flatten():
x, y, w, h = boxes[i]
label = class_names[class_ids[i]]
confidence = confidences[i]
color = (0, 255, 0)
# Text setup
label_text = f"{label} {confidence:.2f}"
font_scale = 2.0
font_thickness = 3
# Get text size
(text_width, text_height), baseline = cv2.getTextSize(
label_text, cv2.FONT_HERSHEY_SIMPLEX, font_scale, font_thickness
)
# Position text above box
text_x = x
text_y = y - 10
if text_y < text_height:
text_y = y + h + text_height + 10 # move below if near top
# Draw white background rectangle
cv2.rectangle(
frame,
(text_x, text_y - text_height - baseline),
(text_x + text_width, text_y + baseline),
(255, 255, 255),
cv2.FILLED
)
# Draw black text on white background
cv2.putText(
frame, label_text, (text_x, text_y),
cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 0), font_thickness
)
# Draw bounding box
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 4)
# Print performance stats
print(f" Inference Time: {inference_time:.3f} seconds")
print(f" Memory Used: {mem_used:.3f} MB")
# Resize for display (maintain aspect ratio)
h, w = frame.shape[:2]
scale = display_width / w
display_height = int(h * scale)
resized_frame = cv2.resize(frame, (display_width, display_height))
return resized_frame
3.7. Run Detection Using OpenCV DNN: Example 1
image_path = "image1.jpg"
image = cv2.imread(image_path)
if image is None:
print(" Error: Image not found or unable to read.")
else:
print(f" Processing: {image_path}")
result = detect_objects(image)
print(f" Displaying result for {image_path}")
# Display image in Jupyter Notebook
result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10, 8))
plt.imshow(result_rgb)
plt.axis('off')
plt.show()
# CPU Inference Result
Processing: image1.jpg
Inference Time: 0.363 seconds
Memory Used: 4.711 MB
Displaying result for image1.jpg
# GPU Inference Results
Processing: image1.jpg
Inference Time: 0.010 seconds
Memory Used: 4.570 MB
Displaying result for image1.jpg
3.8 Run Detection Using OpenCV DNN: Example 2
# CPU Inference Results
Processing: image2.jpg
Inference Time: 0.045 seconds
Memory Used: 4.711 MB
Displaying result for image2.jpg
# GPU Inference Results
Processing: image2.jpg
Inference Time: 0.008 seconds
Memory Used: 2.340 MB
Displaying result for image2.jpg
OpenCV DNN Summary
With this, we wrap up the blog post on OpenCV DNN module in 2025. In the article, we explored how the OpenCV DNN module enables efficient deep learning inference across multiple frameworks. We walked through an example showing object detection using the YOLOv8 nano model. OpenCV DNN’s cross-platform support, hardware acceleration, and lightweight design make it an excellent choice for deploying computer vision models on both powerful machines and edge devices, providing developers a simple yet powerful way to bring AI to real-world applications.
REFERENCES
Deep Learning with OpenCV DNN Module
The post OpenCV DNN : Bridging Classic Vision and Modern Deep Learning appeared first on OpenCV.