OpenCV 使用方式与典型场景:Python 与 C++ 两个可运行示例
使用方式与典型场景:Python 与 C++ 两个可运行示例
Python 适合做原型验证与算法调试,改一行就能重跑,是确定参数的最快路径。下面这段完成「读图 → 灰度 → 高斯滤波 → Canny 边缘 → 落盘」的经典链路:
import cv2
import numpy as np
img = cv2.imread("input.jpg", cv2.IMREAD_COLOR) # 注意:默认是 BGR
if img is None:
raise SystemExit("imread failed, check path and codec support")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
edges = cv2.Canny(blur, 50, 150)
cv2.imwrite("edges.png", edges)
print("shape:", img.shape, "dtype:", img.dtype)
Python 版本同样能跑 dnn,用于验证模型输入输出形状、确定阈值,这一步做完再迁到 C++:
import cv2
import numpy as np
net = cv2.dnn.readNetFromONNX("model.onnx")
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
img = cv2.imread("input.jpg")
blob = cv2.dnn.blobFromImage(img, 1 / 255.0, (640, 640),
swapRB=True, crop=False)
net.setInput(blob)
outs = net.forward()
print("output shape:", outs.shape)
C++ 是端侧落地的形式,逻辑与 Python 一致,差别主要在类型显式化与内存管理:
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/dnn.hpp>
#include <iostream>
int main()
{
cv::Mat img = cv::imread("input.jpg", cv::IMREAD_COLOR);
if (img.empty()) {
std::cerr << "imread failed" << std::endl;
return -1;
}
// 预处理:转 RGB,再交给 blobFromImage 做缩放与归一化
cv::Mat rgb;
cv::cvtColor(img, rgb, cv::COLOR_BGR2RGB);
cv::dnn::Net net = cv::dnn::readNetFromONNX("model.onnx");
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
cv::Mat blob = cv::dnn::blobFromImage(rgb, 1.0 / 255.0,
cv::Size(640, 640),
cv::Scalar(), false, false);
net.setInput(blob);
cv::Mat out = net.forward();
std::cout << "output dims: " << out.dims << std::endl;
return 0;
}
编译时按安装前缀指定头文件与库路径,静态链接时把依赖一起带上。具体链接哪些第三方库与编译选项有关,遇到未定义符号时按报错逐个补:
g++ -O2 detect.cpp -o detect \
-I./install-arm64/include/opencv4 \
-L./install-arm64/lib \
-lopencv_core -lopencv_imgproc -lopencv_imgcodecs -lopencv_dnn
适合用 OpenCV 的场景:需要在端侧完成确定性图像处理与轻量推理、需要一套代码同时覆盖原型与产品、需要相机标定与几何测量这类成熟算法、以及团队要在 Python 与 C++ 之间来回切换。它在这类场景里的优势是接口稳定、文档与社区足够厚。
不适合的场景:需要训练模型(该用训练框架)、需要极致的推理吞吐与算子覆盖(该评估专用推理引擎)、需要在没有操作系统的 MCU 上跑(完整 OpenCV 不面向裸机,需要用它的裁剪版或选择更轻的库)、以及只需要极少量图像操作却引入了完整依赖链的场景——为一个 resize 背上一整套库并不划算。

