news 2026/9/23 1:48:48

PaddleDetection 在 Windows 平台使用 Visual Studio 2019 编译 C++ 预测部署全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PaddleDetection 在 Windows 平台使用 Visual Studio 2019 编译 C++ 预测部署全指南
  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

本篇技术指南完整讲解如何在 Windows 平台下,使用 Visual Studio 2019 Community 对 PaddleDetection 的 C++ 端预测部署代码(deploy/cpp目录)进行 CMake 编译、链接 PaddlePaddle C++ 预测库(paddle_inference)并运行检测/关键点联合推理。读完本文,你将掌握从源码下载、预测库与 OpenCV 安装配置、VS2019 下 CMake 生成与编译、可执行文件运行到性能基准测试的完整闭环,并理解其底层调用链与源码实现原理。

一、为什么选择 Visual Studio 2019 编译 C++ 部署代码

PaddleDetection 的 C++ 端预测部署位于仓库的 deploy/cpp 目录,该目录不依赖PaddleDetection下其他任何目录,可独立编译、二次开发并集成到自有项目中。它支持跨平台(Windows / Linux / Jetson),可扩展新模型的预处理逻辑,并对图像检测的关键步骤做了性能优化,支持 YOLOv3、Faster RCNN、SSD、PP-YOLO 等多种检测模型结构。

微软从 Visual Studio 2017 开始支持直接管理 CMake 跨平台编译项目,但直到 Visual Studio 2019 才提供稳定且完整的支持。因此官方在 windows_vs2019_build.md 中明确推荐:在 Windows 上使用 CMake 管理项目编译构建时,采用Visual Studio 2019环境,本文全部命令也以 VS2019 的 Community(社区版)为例。

提示:仓库还提供了 Linux 编译部署 与 NV Jetson 编译部署 两篇指南,Windows 与 Linux 的 CMake 参数高度相似,仅有少量平台差异(见下文“平台差异”小节),本文聚焦 Windows 流程。

二、前置条件

在开始编译前,请确认系统已安装如下基本软件:

软件说明
Visual Studio 2019需要根据 Paddle 预测库所使用的 VS 版本选择,详见微软官方《Visual Studio 不同版本二进制兼容性》文档
CUDA 9.0 / CUDA 10.0仅在使用 GPU 版本的预测库时需要;cudnn 7+
TensorRT仅在使用 GPU 版本预测库且启用 TensorRT 时需要
CMake 3.0+可从 CMake 官网下载安装

TensorRT 与预测库版本对照

特别注意:Windows 下预测库需要的 TensorRT 版本有严格对应关系:

预测库版本TensorRT 版本
cuda10.1_cudnn7.6_avx_mkl_trt6TensorRT-6.0.1.5
cuda10.2_cudnn7.6_avx_mkl_trt7TensorRT-7.0.0.11
cuda11.0_cudnn8.0_avx_mkl_trt7TensorRT-7.2.1.6

版本对齐是 Windows GPU 部署最容易踩坑的地方:预测库、CUDA、cuDNN、TensorRT 四者的版本必须匹配,否则运行期会报符号缺失或引擎加载失败。

下面所有示例统一以工作目录为D:\projects演示。

三、Step1:下载代码

git clone https://github.com/PaddlePaddle/PaddleDetection.git

其中 C++ 预测代码位于PaddleDetection/deploy/cpp目录。该目录的顶层结构如下(见 deploy/cpp/README.md):

deploy/cpp ├── src │ ├── main.cc # 集成代码示例,程序入口(检测) │ ├── main_keypoint.cc # 关键点+检测联合预测的程序入口 │ ├── main_jde.cc # MOT(多目标跟踪)程序入口 │ ├── object_detector.cc # 模型加载和预测主要逻辑封装类实现 │ ├── keypoint_detector.cc# 关键点检测器封装 │ ├── preprocess_op.cc # 预处理相关主要逻辑封装实现 │ └── utils.cc ├── include │ ├── config_parser.h # 导出模型配置 yaml 文件解析 │ ├── object_detector.h # 模型加载和预测主要逻辑封装类 │ ├── preprocess_op.h # 预处理相关主要逻辑类封装 │ └── ... ├── docs │ ├── linux_build.md # Linux 编译指南 │ └── windows_vs2019_build.md # Windows VS2019 编译指南 ├── CMakeLists.txt # cmake 编译入口文件 └── cmake # 依赖的外部项目 cmake(目前仅有 yaml-cpp)

从 CMakeLists.txt 的源码可以看出,编译目标会根据功能开关选择不同的源文件集合:

  • 开启WITH_KEYPOINT:编译main_keypoint.cc+ 检测 + 关键点相关源文件;
  • 开启WITH_MOT:编译main_jde.cc+ JDE 检测器 + 跟踪(tracker/trajectory/lapjv)相关源文件;
  • 默认(两者均不开启):仅编译main.cc检测入口。

四、Step2:下载 PaddlePaddle C++ 预测库 paddle_inference

PaddlePaddle C++ 预测库针对不同的 CPU 和 CUDA 版本提供了多个预编译版本,请按实际环境从官方 C++ 预测库下载列表(Windows 一节)选择对应版本。

解压后D:\projects\paddle_inference目录包含:

paddle_inference ├── paddle # paddle 核心库和头文件 ├── third_party # 第三方依赖库和头文件 └── version.txt # 版本和编译信息

源码视角:预测库目录如何被使用

CMakeLists.txt 中,PADDLE_DIR指向的目录会被加入头文件搜索路径并链接第三方依赖库:

  • 头文件:${PADDLE_DIR}/paddle/includethird_party/install/protobuf/includeglog/includegflags/includexxhash/include,以及third_party/boostthird_party/eigen3等;
  • 库文件:third_party/install/protobuf/libglog/libgflags/libxxhash/libpaddle2onnx/libonnxruntime/lib${PADDLE_DIR}/paddle/lib/

在 Windows 分支(CMakeLists.txt)下还会额外包含${PADDLE_DIR}/paddle/fluid/inference目录,并链接${PADDLE_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}(即paddle_inference.lib)。这就是 Windows 下必须把PADDLE_LIB_NAME设置为paddle_inference的原因。

五、Step3:安装配置 OpenCV

  1. 在 OpenCV 官网下载适用于 Windows 平台的3.4.6版本;
  2. 运行下载的可执行文件,将 OpenCV 解压至指定目录,如D:\projects\opencv
  3. 配置环境变量(如果后续 CMake 使用全局绝对路径,可以不用设置环境变量):
    • 我的电脑 → 属性 → 高级系统设置 → 环境变量;
    • 在系统变量中找到Path(如没有,自行创建),双击编辑;
    • 新建,将 OpenCV 的 bin 目录填入并保存,如D:\projects\opencv\build\x64\vc14\bin

该 bin 目录下的opencv_world346.dll在运行阶段会被main.exe动态加载,若运行时报"找不到opencv_world346.dll",把该 dll 拷贝到main.exe所在目录即可(详见下文运行小节)。

六、Step4:使用 CMake 编译

1. 进入 cpp 目录

cd D:\projects\PaddleDetection\deploy\cpp

2. 使用 CMake 生成项目文件

编译参数的含义说明如下(带*表示仅在使用GPU 版本预测库时指定;其中 CUDA 库版本尽量对齐,使用 9.0、10.0 版本,不要使用 9.2、10.1 等版本的 CUDA 库):

参数名含义
*CUDA_LIBCUDA 的库路径
*CUDNN_LIBCUDNN 的库路径
OPENCV_DIROpenCV 的安装路径
PADDLE_DIRPaddle 预测库的路径
PADDLE_LIB_NAMEPaddle 预测库名称(Windows 下固定为paddle_inference

注意:

  1. 如果编译环境为 CPU,需要下载 CPU 版预测库,并把WITH_GPU的勾去掉;
  2. 如果使用的是openblas版本,请把WITH_MKL勾去掉;
  3. 如无需使用关键点模型,可以把WITH_KEYPOINT勾去掉;
  4. Windows 环境下,PADDLE_LIB_NAME需要设置为paddle_inference

执行如下命令生成项目文件:

cmake . -G "Visual Studio 16 2019" -A x64 -T host=x64 -DWITH_GPU=ON -DWITH_MKL=ON -DCMAKE_BUILD_TYPE=Release -DCUDA_LIB=path_to_cuda_lib -DCUDNN_LIB=path_to_cudnn_lib -DPADDLE_DIR=path_to_paddle_lib -DPADDLE_LIB_NAME=paddle_inference -DOPENCV_DIR=path_to_opencv -DWITH_KEYPOINT=ON

例如:

cmake . -G "Visual Studio 16 2019" -A x64 -T host=x64 -DWITH_GPU=ON -DWITH_MKL=ON -DCMAKE_BUILD_TYPE=Release -DCUDA_LIB=D:\projects\packages\cuda10_0\lib\x64 -DCUDNN_LIB=D:\projects\packages\cuda10_0\lib\x64 -DPADDLE_DIR=D:\projects\packages\paddle_inference -DPADDLE_LIB_NAME=paddle_inference -DOPENCV_DIR=D:\projects\packages\opencv3_4_6 -DWITH_KEYPOINT=ON

源码视角:编译开关与平台差异

CMakeLists.txt 顶部声明了全部可配置开关:

option(WITH_MKL "Compile demo with MKL/OpenBlas support, defaultuseMKL." ON) option(WITH_GPU "Compile demo with GPU/CPU, default use CPU." ON) option(WITH_TENSORRT "Compile demo with TensorRT." OFF) option(WITH_KEYPOINT "Whether to Compile KeyPoint detector" OFF) option(WITH_MOT "Whether to Compile MOT detector" OFF)

同时PADDLE_DIRPADDLE_LIB_NAMEOPENCV_DIRCUDA_LIBCUDNN_LIBTENSORRT_INC_DIRTENSORRT_LIB_DIR均为 CACHE 变量,可通过-D传入。如果PADDLE_DIROPENCV_DIR未设置,cmake 会直接FATAL_ERROR终止;GPU 模式下未设置CUDA_LIB同样会报错终止(CMakeLists.txt)。

平台差异还体现在:

  • 静态运行库safe_set_static_flag宏会把/MD替换为/MT(Release 下配合/bigobj /MT标志),避免运行库冲突;
  • MKL 依赖:启用WITH_MKL时 Windows 链接mklml.liblibiomp5md.lib;使用 OpenBLAS 时链接openblas.dll
  • DLL 自动拷贝:Windows 编译完成后,CMake 的POST_BUILD钩子会自动把mklml.dlllibiomp5md.dllmkldnn.dllpaddle_inference.dllonnxruntime.dllpaddle2onnx.dll等运行时依赖拷贝到可执行文件及release目录(CMakeLists.txt),保证生成物可直接运行。

3. 编译

用 Visual Studio 2019 打开cpp文件夹下的PaddleObjectDetector.sln,将编译模式设置为Release,点击生成全部生成

编译产物(可执行文件main.exe)默认输出在out\build\x64-Release目录下。

七、Step5:预测及可视化

打开cmd并切换到编译输出目录:

cd D:\projects\PaddleDetection\deploy\cpp\out\build\x64-Release

可执行文件main即为样例预测程序。其命令行参数由 gflags 定义(见 src/main.cc 与 src/main_keypoint.cc),主要的参数如下:

参数说明
--model_dir导出的检测预测模型所在路径(必填)
--model_dir_keypointOption导出的关键点预测模型所在路径
--image_file要预测的图片文件路径
--image_dir要预测的图片文件夹路径
--video_file要预测的视频文件路径
--camera_idOption用来预测的摄像头 ID,默认为 -1(表示不使用摄像头预测)
--device运行时的设备,可选择CPU/GPU/XPU,默认为CPU
--gpu_id指定进行推理的 GPU device id(默认值为 0)
--run_mode使用 GPU 时默认为 paddle,可选(paddle/trt_fp32/trt_fp16/trt_int8)
--batch_size检测模型预测时的 batch size,在指定image_dir时有效
--batch_size_keypoint关键点模型预测时的 batch size,默认为 8
--run_benchmark是否重复预测来进行 benchmark 测速
--output_dir输出图片所在的文件夹,默认为 output
--use_mkldnnCPU 预测中是否开启 MKLDNN 加速
--cpu_threads设置 cpu 线程数,默认为 1
--use_dark关键点模型输出预测是否使用 DarkPose 后处理,默认为 true

此外,源码中还有几个文档表格之外、但在进阶调优中很实用的参数:

  • --threshold:检测置信度阈值,默认 0.5;
  • --threshold_keypoint:关键点得分阈值,默认 0.5;
  • --trt_min_shape/--trt_max_shape/--trt_opt_shape:TensorRT 动态形状的最小/最大/最优输入尺寸,默认分别为 1 / 1280 / 640(对应输入[batch, 3, h, w]中的 h、w);
  • --trt_calib_mode:当模型由 TensorRT 离线量化校准产出时需置为 True;
  • --use_gpu:已废弃(Deprecated),请改用--device

注意:

  1. 优先级顺序camera_id>video_file>image_dir>image_file。该优先级在 main.cc 中体现:先判断视频/摄像头分支,再判断图片分支;同时image_dir使用 OpenCV 的cv::glob收集目录内全部图片,而单独指定image_filebatch_size必须为 1,否则程序会直接退出提示;
  2. 如果提示找不到opencv_world346.dll,把D:\projects\packages\opencv3_4_6\build\x64\vc14\bin文件夹下的opencv_world346.dll拷贝到main.exe文件夹下即可;
  3. --run_benchmark如果设置为 True,则需要安装依赖:pip install pynvml psutil GPUtil

样例一:CPU 预测单张图片

# 不使用 GPU 测试图片 D:\images\test.jpeg .\main --model_dir=D:\models\yolov3_darknet --image_file=D:\images\test.jpeg

图片文件的可视化预测结果会保存在当前目录下output.jpg文件中(实际按--output_dir指定目录输出,默认output)。

样例二:GPU 预测视频

# 使用 GPU 测试视频 D:\videos\test.mp4 .\main --model_dir=D:\models\yolov3_darknet --video_path=D:\videos\test.mp4 --device=GPU

视频文件目前支持.mp4格式的预测,可视化预测结果会保存在当前目录下output.mp4文件中。源码中通过cv::VideoCapture读取视频、cv::VideoWriter(fourcc0x00000021,即 MP4V)逐帧写入检测结果(main.cc)。

样例三:检测模型 + 关键点模型联合预测

# 使用关键点模型与检测模型联合预测,使用 GPU 预测 # 检测模型检测到的人送入关键点模型进行关键点预测 .\main --model_dir=D:\models\yolov3_darknet --model_dir_keypoint=D:\models\hrnet_w32_256x192 --image_file=D:\images\test.jpeg --device=GPU

该功能需在编译时开启WITH_KEYPOINT=ON。从 main_keypoint.cc 可以看到联合推理的完整链路:检测器先输出人体框 → 对每个class_id == 0(人)的检测框调用CropImg裁剪 → 按--batch_size_keypoint(默认 8)攒批送入关键点模型 → 关键点结果经VisualizeKptsResult绘制(关键点使用 20 色 colormap)。视频模式下还会使用PoseSmooth做关键点时序平滑,降低抖动。

源码视角:从命令行参数到推理引擎

main入口的核心逻辑(main.cc):

  1. google::ParseCommandLineFlags解析命令行;
  2. 校验--model_dir与输入源(image_file/image_dir/video_file至少一个)非空;
  3. 校验--run_mode必须是paddle/trt_fp32/trt_fp16/trt_int8之一;--device必须是CPU/GPU/XPU之一;
  4. 构造PaddleDetection::ObjectDetector,其构造函数(object_detector.h)依次完成:解析模型目录下infer_cfg.yml(读取archPreprocesslabel_listuse_dynamic_shapemin_subgraph_sizeNMSfpn_stridemask等字段,见 config_parser.h)→ 初始化预处理器 → 调用LoadModel创建paddle_infer::Predictor

模型加载时(object_detector.cc):

  • 加载model.pdmodelmodel.pdiparams(即通过 tools/export_model.py 导出的推理模型,模型目录必须包含这两个文件与infer_cfg.yml);
  • GPU 模式:EnableUseGpu(200, gpu_id)并开启 IR 优化;run_mode非 paddle 时调用EnableTensorRtEngine,并根据infer_cfg.yml中的use_dynamic_shape决定是否通过SetTRTDynamicShapeInfo设置image输入的动态形状(min/max/opt 取自--trt_min_shape等参数);
  • CPU 模式:DisableGpu,若--use_mkldnn开启则EnableMKLDNN并设置 10 个 shape 的缓存容量,线程数取--cpu_threads
  • XPU 模式:EnableXpu(10 * 1024 * 1024)
  • 最后统一DisableGlogInfo+EnableMemoryOptim(内存优化)后创建预测器。

预测时(Predict,object_detector.cc)会按 batch 依次完成:BGR→RGB 转换与预处理 → 组装imageim_shapescale_factor输入张量 → 执行predictor_->Run()→ 依据infer_cfg.ymlarch/mask字段解析输出(检测框每项 6 维[class_id, score, xmin, ymin, xmax, ymax],旋转框每项 10 维,SOLOv2 走独立后处理)→ 通过VisualizeResult绘制类别、置信度与框(掩码模型还会叠加 mask 轮廓)。

八、性能测试(Benchmark)

Benchmark 详细内容请查看仓库根目录的 deploy/BENCHMARK_INFER.md。其中针对 Windows 平台(GTX 1080Ti)给出了各模型的paddle_inferencetrt_fp32trt_fp16平均单图推理耗时(单位 ms/image,Batch Size=1,去掉前 100 轮 warmup 后测试 100 轮),可用来与本地环境对比验证部署效果。

在本地进行测速时,给main加上--run_benchmark=true即可:源码会以固定 warmup/repeats(10 次)重复预测,并在结束时通过PrintBenchmarkLog打印preproce_time / inference_time / postprocess_time三段耗时(main.cc),便于定位耗时瓶颈。注意此时需要先安装pynvml psutil GPUtil依赖。

九、常见问题与排查建议

  1. 找不到opencv_world346.dll:将 OpenCV 安装目录build\x64\vc14\bin下的 dll 拷贝到main.exe同级目录;
  2. PADDLE_LIB_NAME设置错误:Windows 下必须为paddle_inference,否则链接阶段找不到paddle_inference.lib
  3. 预测库与 TensorRT 版本不匹配:严格对照上文第三节的版本表,预测库、CUDA、cuDNN、TensorRT 必须配套;
  4. 运行时报run_mode/device不合法--run_mode只能是paddle/trt_fp32/trt_fp16/trt_int8--device只能是CPU/GPU/XPU,程序启动时会校验并打印提示;
  5. CPU 版 OpenBLAS 预测库:编译时去掉WITH_MKL勾选,CMake 会自动切换为链接 OpenBLAS 并拷贝openblas.dll
  6. 模型导出:C++ 部署使用的模型需先用 tools/export_model.py 导出,得到model.pdmodelmodel.pdiparamsinfer_cfg.yml,并将--model_dir指向该目录;导出细节可参考 deploy/EXPORT_MODEL.md。

至此,你已可以在 Windows + Visual Studio 2019 环境下完整编译并运行 PaddleDetection 的 C++ 检测/关键点推理程序,并具备结合 deploy/cpp 源码进行二次开发与性能调优的能力。

  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 1:48:34

图解原理:暴风资讯 API 升级后性能暴涨 300% 实战

图解原理:暴风资讯 API 升级后性能暴涨 300% 实战 版本升级后 API 全变了,你的服务还在跑吗? 别再硬着头皮改代码了,那是自寻死路。 今天用图解原理拆解暴风资讯新版接口的性能陷阱,让你彻底搞懂。 很多老哥反馈,自从暴风资讯换了新版 SDK,原本毫秒级的查询变成了秒级等待。…

作者头像 李华
网站建设 2026/9/23 1:48:26

小猪配齐面试避坑指南:3个核心考点保姆级教程

小猪配齐面试避坑指南:3个核心考点保姆级教程 面试被问原理答不上来,那种大脑一片空白的感觉,真的让人想找个地缝钻进去。别慌,很多资深开发在复盘时也提到,所谓的“原理”其实就那几套逻辑,关键在于你平时有没有把细节嚼碎了咽下去。今天这篇保姆级教程,就是专门针对【小猪配齐】这个高频技术场景,帮你把那些容易…

作者头像 李华
网站建设 2026/9/23 1:47:37

赚了点源码深度剖析

3个坑让你项目提速50%:新手避坑指南 面试被问原理答不上来,简历上写着“精通”,面试官一句“这个模块为什么慢”就让你卡壳。别慌,这不是你一个人的问题。我在后端摸爬滚打十年,见过太多新手在性能优化上踩坑,明明代码能跑,但一上量就崩。今天不讲虚的,直接上项目里真实发生的场景,把那些让你“赚了点”小钱却…

作者头像 李华
网站建设 2026/9/23 1:47:29

经典牛牛实战:面试必问核心逻辑全拆解

经典牛牛实战:面试必问核心逻辑全拆解 面试被问原理答不上来?别慌,很多人卡在这里。 今天拆解经典牛牛,搞定面试必问底层逻辑。 用代码还原真实场景,让你彻底吃透。 项目目标与业务场景 做棋牌类后端, 经典牛牛 是绕不开的实战题。 它不像斗地主有固定牌型,组合爆炸极难。…

作者头像 李华
网站建设 2026/9/23 1:47:16

企业宣传片策划方案避坑指南:别让环境配置坑了你

企业宣传片策划方案避坑指南:别让环境配置坑了你 做企业宣传片策划方案,最怕的不是创意不够,而是 配置环境就卡半天 。明明代码逻辑跑通了,一换台电脑、一换系统版本,直接报错,排查两小时,最后发现是依赖冲突。这种痛,老手都懂。今天这篇避坑指南,不讲虚的,直接拆解那些让你深夜抓狂的常见坑,手把手教你怎么填…

作者头像 李华
网站建设 2026/9/23 1:47:02

3个核心维度拆解suv和轿车的优缺点新手避坑指南

3个核心维度拆解suv和轿车的优缺点新手避坑指南 版本升级后 API 全变了,这不仅是代码库的噩梦,也是新手在对比车型时最容易踩的坑。很多人拿着三年前的评测数据去选车,结果发现底盘调校、辅助驾驶接口甚至座椅加热逻辑都改了,导致体验断崖式下跌。作为刚入行的工程师,我们讲究“可维护性”和“向后兼容”,选…

作者头像 李华