本项目使用 CMake 管理两个独立的 OpenCV 示例程序:
show:检测图像轮廓并生成彩色渐变线条艺术图。navigation:基于 A* 算法的交互式栅格路径规划演示。
两个程序均使用 C++17 和 OpenCV 4 编写。
- CMake 3.16 或更高版本
- 支持 C++17 的编译器,例如 GCC 或 Clang
- OpenCV 4 开发包
- 可显示 OpenCV HighGUI 窗口的图形环境
Ubuntu/Debian 可安装以下依赖:
sudo apt update
sudo apt install build-essential cmake libopencv-dev在项目根目录执行:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel构建完成后会生成:
build/show
build/navigation
show 会读取当前工作目录下的 jo.jpg,执行以下处理:
- 将图像转换为灰度图。
- 使用双边滤波平滑噪声,同时尽量保留边缘。
- 使用 Canny 检测边缘。
- 使用形态学闭运算连接断裂边缘。
- 查找轮廓并使用
approxPolyDP简化轮廓。 - 将轮廓映射到由红、紫、蓝等颜色组成的渐变调色板。
- 添加轻微光晕,生成柔和的彩色线条艺术图。
- 输入:
jo.jpg - 输出:
result.jpg - 预览窗口:
Color Gradient Edge ArtSmooth Edges
请从项目根目录运行,确保程序可以找到 jo.jpg:
./build/show按任意键关闭窗口。输出文件会保存为:
result.jpg
参数位于 show.cpp:
bilateralFilter(gray, filtered, 9, 45, 45);
Canny(filtered, edges, 25, 75);
approxPolyDP(contour, smooth, 0.8, true);- 增大 Canny 阈值会减少噪点,但可能漏掉弱边缘。
- 减小 Canny 阈值会增加细节,但可能产生更多碎片。
- 增大
approxPolyDP的阈值会使轮廓更简化。 - 渐变颜色可以在
colors数组和mainAlpha、halo的计算中调整。
navigation 展示一个带障碍物的栅格地图,并使用 A* 算法寻找路线。
- 起点固定为
(2, 12)。 - 初始终点为
(37, 12)。 - 鼠标左键点击任意白色格子,可以重新指定终点。
- 点击障碍物不会修改终点,并会显示提示。
- 按
Esc、Q或q退出。 - 每次选择终点后,程序都会重新计算并显示最短路线。
A* 使用以下优先级:
- 首先保证移动步数最少。
- 在步数相同的路线中,选择转弯次数最少的路线。
搜索状态由“当前位置”和“进入方向”组成:
状态 = 当前格子 + 进入该格子的方向
这样可以区分直行、转弯和反向移动。每次移动增加 1 步;转弯会增加转弯次数,但不会改变第一优先级的步数判断。启发函数使用曼哈顿距离。
- 深灰色:障碍物
- 浅蓝色:A* 搜索过的格子
- 橙色:最终路径
- 绿色:固定起点
- 红色:当前终点
./build/navigation程序启动时会先运行内置自测试,然后打开:
A* Path Planning
每次路径更新后,结果会写入:
astar_demo.png
navigation 已拆分为多个职责独立的组件:
navigation.cpp 主程序入口和窗口循环
navigation/position.hpp 网格坐标类型
navigation/grid_map.hpp
navigation/grid_map.cpp 栅格地图和演示地图
navigation/astar_planner.hpp
navigation/astar_planner.cpp A* 搜索算法
navigation/visualization.hpp
navigation/visualization.cpp 绘制、鼠标交互和 PNG 导出
navigation/self_test.hpp
navigation/self_test.cpp 路径和算法自测试
.
├── CMakeLists.txt
├── README.md
├── show.cpp
├── navigation.cpp
├── navigation/
│ ├── position.hpp
│ ├── grid_map.hpp
│ ├── grid_map.cpp
│ ├── astar_planner.hpp
│ ├── astar_planner.cpp
│ ├── visualization.hpp
│ ├── visualization.cpp
│ ├── self_test.hpp
│ └── self_test.cpp
├── jo.jpg
├── result.jpg
├── astar_demo.png
└── build/