C++ 项目约定:目录结构、依赖管理、构建与 Git

所谓「约定」= 一套项目结构规范 + 依赖管理规范:以后不管做什么项目,都按这个套路来,不用每次重新想。 适用背景:Windows(VS2022)只做 Boost + OpenCV,不做 Qt;Qt 开发放在 Linux(Ubuntu 虚拟机/服务器)。 文中 <OpenCV安装目录>、<Boost根目录>、<项目根目录> 为占位符,替换成本机实际目录即可。 一、总体原则 三句话: CMake 是唯一的构建系统,不碰 qmake、不碰手动 .vcxproj。 依赖一律走环境变量 + find_package,不在 CMakeLists.txt 里硬编码路径。 Windows 端 IDE 是 VS2022 + CMake 项目模式;Linux 端用 Qt Creator 或 VS Code。 二、目录结构约定(Windows 端) 每个项目固定长这样: <项目根目录>\<项目名>\ ├── CMakeLists.txt ├── CMakePresets.json ├── CMakeUserPresets.json # 本地预设(不提交 Git) ├── .gitignore ├── README.md ├── src\ # 源码 │ ├── main.cpp │ ├── core\ # Boost 业务逻辑 │ │ ├── Service.h │ │ └── Service.cpp │ └── vision\ # OpenCV 图像处理 │ ├── ImageProcessor.h │ └── ImageProcessor.cpp ├── include\ # 对外头文件(可选) ├── resources\ # 静态资源、图片(可选) ├── tests\ # 测试代码(可选) ├── third_party\ # 第三方源码(可选,一般不用) └── out\ # 构建输出(不提交 Git) └── build\ ├── debug\ └── release\ 关键点: ...

2026 年 10 月 13 日

CMake 工程模板:VS2022 + OpenCV 4.10

这是一个可直接复制的 OpenCV 工程模板(VS2022 + CMake + Ninja)。模板的作用:新建 OpenCV 项目时不用每次手动加 include/lib 路径——复制模板、改项目名、加源文件即可。整套约定是:CMake 为唯一构建系统、依赖走环境变量 + find_package、构建输出在 out/build/、不写死路径。 前置环境变量: OpenCV_DIR = <OpenCV安装目录>\build\x64\vc16\lib PATH 追加:<OpenCV安装目录>\build\x64\vc16\bin 一、目录结构 <项目根目录>\OpenCVTemplate\ ├── CMakeLists.txt ├── CMakePresets.json ├── .gitignore ├── src\ │ └── main.cpp └── out\ └── build\ 二、CMakeLists.txt(复制到项目根目录) cmake_minimum_required(VERSION 3.20) project(OpenCVTemplate LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # ---------- OpenCV ---------- # OpenCV_DIR 由 CMakePresets.json 从环境变量注入,这里不写路径 find_package(OpenCV REQUIRED) # ---------- 源文件 ---------- set(SOURCES src/main.cpp ) add_executable(${PROJECT_NAME} ${SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${OpenCV_INCLUDE_DIRS} ) target_link_libraries(${PROJECT_NAME} PRIVATE ${OpenCV_LIBS} ) 三、CMakePresets.json(复制到项目根目录) { "version": 3, "configurePresets": [ { "name": "debug", "generator": "Ninja", "binaryDir": "${sourceDir}/out/build/${presetName}", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "OpenCV_DIR": "$env{OpenCV_DIR}" } }, { "name": "release", "inherits": "debug", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } } ], "buildPresets": [ { "name": "debug", "configurePreset": "debug" }, { "name": "release", "configurePreset": "release" } ] } 版本待核实:预设文件 "version": 3 与 CMakeLists.txt 里 cmake_minimum_required(VERSION 3.20) 的版本要求是否匹配(version 3 预设需较新的 CMake),首次配置前请确认本机 / VS2022 自带 CMake 的实际版本。 ...

2026 年 10 月 13 日

OpenCV 4.10 + Visual Studio 环境配置:属性页手动配法

在 Visual Studio 项目里用属性页手动配置 OpenCV 4.10 的完整步骤:包含目录、库目录、链接器输入、环境变量,四步配好后用一段自检代码验证。(如果用 CMake 工程,则改为环境变量 + find_package 的方案,不用逐项目配属性页。) 一、配置步骤 1. 包含目录 项目属性 → VC++ 目录 → 包含目录,添加: <OpenCV安装目录>\build\include 2. 库目录 项目属性 → VC++ 目录 → 库目录,添加: <OpenCV安装目录>\build\x64\vc16\lib vc16 对应 Visual Studio 2019/2022 3. 链接器输入 项目属性 → 链接器 → 输入 → 附加依赖项,添加: opencv_world4100.lib 4. 环境变量 系统环境变量 Path 中添加: <OpenCV安装目录>\build\x64\vc16\bin 二、验证 #include <opencv2/opencv.hpp> #include <iostream> int main() { std::cout << "OpenCV Version: " << CV_VERSION << std::endl; return 0; } 三、常见问题 运行时弹出找不到 dll → 检查环境变量是否配置正确 链接错误 → 检查库目录和附加依赖项 Release / Debug 库混用 → Debug 构建须链接带 d 后缀的 opencv_world4100d.lib,Release 用 opencv_world4100.lib

2026 年 10 月 13 日

OpenCV 常用 API:图像读写、显示与颜色空间转换

OpenCV 入门最常用的几组 API:图像读取、显示、颜色空间转换、保存、获取图像信息。 一、图像读取与显示 #include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取图像 Mat img = imread("test.jpg"); // 显示图像 imshow("窗口名", img); // 等待按键 waitKey(0); return 0; } 二、灰度图转换 Mat gray; cvtColor(img, gray, COLOR_BGR2GRAY); imshow("灰度图", gray); 三、HSV 图像转换 Mat hsv; cvtColor(img, hsv, COLOR_BGR2HSV); imshow("HSV", hsv); 四、常用颜色空间 转换 常量 BGR → 灰度 COLOR_BGR2GRAY BGR → HSV COLOR_BGR2HSV BGR → RGB COLOR_BGR2RGB 灰度 → BGR COLOR_GRAY2BGR 五、图像保存 imwrite("output.jpg", gray); 六、获取图像信息 int width = img.cols; // 宽度 int height = img.rows; // 高度 int channels = img.channels(); // 通道数

2026 年 10 月 13 日

OpenCV 像素遍历:at<> 与 ptr<> 两种方式对比

OpenCV 访问像素的两种方式:at<> 直接访问和 ptr<> 指针访问。 一、方式一:at<> 直接访问 通过行列索引直接访问像素,代码简洁但每次访问都有边界检查开销。 // 单通道(灰度图) uchar pixel = image.at<uchar>(i, j); image.at<uchar>(i, j) = 255 - pixel; // 三通道(彩色图) Vec3b pixel = image.at<Vec3b>(i, j); pixel[0] = 255 - pixel[0]; // B pixel[1] = 255 - pixel[1]; // G pixel[2] = 255 - pixel[2]; // R image.at<Vec3b>(i, j) = pixel; 二、方式二:ptr<> 指针访问 获取行首指针后直接偏移,性能更优(无边界检查)。 // 单通道 uchar* rowPtr = image.ptr<uchar>(i); rowPtr[j] = 255 - rowPtr[j]; // 三通道 Vec3b* rowPtr = image.ptr<Vec3b>(i); Vec3b pixel = rowPtr[j]; pixel[0] = 255 - pixel[0]; pixel[1] = 255 - pixel[1]; pixel[2] = 255 - pixel[2]; rowPtr[j] = pixel; 三、对比 特性 at<> ptr<> 语法 简洁直观 需理解指针 性能 每次边界检查,较慢 无边界检查,较快 适用 小批量访问、调试 大图遍历、性能敏感 四、反转图像示例(完整) void invertImage(Mat& image) { int w = image.cols; int h = image.rows; int channels = image.channels(); for (int i = 0; i < h; i++) { uchar* rowPtr = image.ptr<uchar>(i); for (int j = 0; j < w * channels; j++) { rowPtr[j] = 255 - rowPtr[j]; } } imshow("Inverted", image); } 可用 rowPtr[j] = 255 - rowPtr[j] 一次处理所有通道,无需区分通道数。

2026 年 10 月 13 日

Windows 上 Boost + OpenCV + CMake 的环境配置方案:只配两件事

从零配置的一套通用方案:环境变量 + CMakePresets.json。一次配好,所有项目通用。Windows 端只配 Boost + OpenCV,不配 Qt(Qt 开发放在 Linux 端)。 文中 <OpenCV安装目录>、<Boost根目录>、<项目根目录> 为占位符,替换成本机实际目录即可。 一、环境变量(系统变量) 在 Windows「系统属性 → 环境变量」里,系统变量新建: 变量名 值 作用 OpenCV_DIR <OpenCV安装目录>\build\x64\vc16\lib OpenCV 的 Config.cmake 所在目录 BOOST_ROOT <Boost根目录> Boost 根目录 PATH 追加(运行时找 dll): <OpenCV安装目录>\build\x64\vc16\bin Boost 不用加 PATH,静态库,运行时不需要 dll。 二、每个库的配置细节 OpenCV 关键文件(示例路径): <OpenCV安装目录>\build\x64\vc16\lib\OpenCVConfig.cmake <OpenCV安装目录>\build\x64\vc16\lib\opencv_world4100.lib <OpenCV安装目录>\build\x64\vc16\lib\opencv_world4100d.lib 变量: OpenCV_DIR = <OpenCV安装目录>\build\x64\vc16\lib CMake 里: find_package(OpenCV REQUIRED) target_include_directories(main PRIVATE ${OpenCV_INCLUDE_DIRS}) target_link_libraries(main PRIVATE ${OpenCV_LIBS}) Boost 关键文件(示例路径): <Boost根目录>\stage\lib\cmake\Boost-1.81.0\BoostConfig.cmake <Boost根目录>\stage\lib\libboost_filesystem-vc143-mt-x64-1_81.lib <Boost根目录>\stage\lib\libboost_filesystem-vc143-mt-gd-x64-1_81.lib 变量: BOOST_ROOT = <Boost根目录> CMake 里: set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) find_package(Boost 1.81 REQUIRED COMPONENTS filesystem system thread) target_link_libraries(main PRIVATE Boost::filesystem Boost::system Boost::thread) 注意:Boost 大部分是 header-only,find_package 只对需要编译的库(filesystem、system、thread 等)起作用。header-only 的库直接 #include 就行,CMake 里不用 find_package。 ...

2026 年 10 月 13 日