Files
chengnan/README.md
luochen570 8c9a92f2cb
Some checks failed
Build Linux Release / build-linux (push) Has been cancelled
ci: build Linux release package
2026-05-29 22:51:24 +08:00

517 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# chengnan
## 项目名称
chengnan基于 Qt 与 OpenCV 的图像显示与处理系统
## 当前实现状态
本项目已初始化为一个 Qt Widgets + OpenCV + CMake 的 C++ 图像处理应用。当前构建策略已调整为:**在 Linux 中编译,不使用 Windows 编译工具链;所有构建项目所需工具和依赖均采用项目目录内的二进制安装方式,不使用源码编译安装依赖。**
已实现功能:
- 打开图片
- 保存图片
- 另存图片
- 使用 QWidget 体系显示图像,不使用 `cv::imshow`
- 左右对比显示处理前 / 处理后图像
- 图像视图支持鼠标滚轮缩放、双击适配窗口、拖拽平移视图
- 图像处理功能:
- 放大 / 缩小
- 平移
- 指定角度旋转
- 阈值分割 + 轮廓目标提取
- 基于 HSV 均值的简单规则分类
- 使用 `QThread` + 信号槽执行 OpenCV 处理任务,避免阻塞 UI
## Linux 二进制构建原则
本项目后续构建以 Linux 环境为准,要求如下:
- 在 Linux 中编译本项目
- 不使用 Windows 编译工具链
- 不使用 `cl.exe``windeployqt.exe`、Windows `cmake.exe`、Windows `ninja.exe` 构建本项目
- 不使用当前系统上的 GCC / G++ 作为项目构建工具链
- 不全局安装 Qt、OpenCV、CMake、Ninja、Python 包等依赖
- 不污染系统 `/usr``/usr/local`、系统 Python site-packages 或全局环境变量
- 所有构建项目所需工具和依赖必须放在项目目录内
- 所有构建项目所需依赖必须优先使用官方或可信来源的二进制包
- 不使用源码编译安装 Qt / OpenCV 等依赖
- Python 使用项目目录内虚拟环境,不使用 uv 安装或管理环境
- 构建脚本只能临时设置当前进程环境变量,不能修改系统环境变量
推荐目录约定:
```text
chengnan/
├── tools/
│ ├── cmake-linux/ # Linux 版 CMake 二进制
│ ├── ninja-linux/ # Linux 版 Ninja 二进制
│ ├── compiler-linux/ # Linux 版二进制编译器工具链,如 LLVM/Clang
│ ├── python-bin/ # Python 二进制包
│ └── python-venv/ # Python 虚拟环境
├── third_party/
│ ├── qt-linux/ # Linux 版 Qt 二进制包
│ └── opencv-linux/ # Linux 版 OpenCV 二进制包
└── build-linux/ # Linux 构建输出目录
```
> 注意:如果 OpenCV 没有适配当前 Linux 发行版的官方二进制包,不应退回源码编译安装。应改为寻找可信的预编译包、容器化二进制 SDK、发行版无污染解包方案或更换依赖来源。
## 编译工具链与版本声明
本项目当前已验证的 Linux 二进制工具链如下,全部位于项目目录内的 `tools/linux-build-env/`,不依赖全局安装的 Qt / OpenCV / CMake / Ninja也不使用 Windows 编译工具链。
| 工具 / 依赖 | 当前版本 | 项目内路径 | 说明 |
| --- | --- | --- | --- |
| micromamba | 2.6.2 | `tools/micromamba/bin/micromamba` | 仅用于在项目目录内获取二进制包 |
| CMake | 4.3.3 | `tools/linux-build-env/bin/cmake` | CMake 最低要求 3.21,当前验证版本 4.3.3 |
| Ninja | 1.13.2 | `tools/linux-build-env/bin/ninja` | CMake 使用 `-G Ninja` 生成构建系统 |
| Clang / Clang++ | 22.1.6 | `tools/linux-build-env/bin/clang++` | 本项目指定使用项目内 Clang不使用系统 GCC / G++ |
| Qt | 5.15.15 | `tools/linux-build-env/``third_party/qt-linux` | 使用 Qt Widgets / Qt ConcurrentCMake 也兼容 Qt6 |
| OpenCV | 4.13.0 | `tools/linux-build-env/``third_party/opencv-linux` | 使用 `core``imgproc``imgcodecs` 组件 |
| C++ 标准 | C++17 | `CMakeLists.txt` | `CMAKE_CXX_STANDARD 17` |
> 说明:`third_party/qt-linux` 和 `third_party/opencv-linux` 是指向 `tools/linux-build-env` 的项目内软链接,方便保持 README 中的依赖目录语义;真正的二进制依赖仍统一存放在 `tools/linux-build-env/`。
## 如何构建
### 一键构建
在 Linux 中进入项目目录执行:
```bash
cd /root/chengnan
./scripts/build-linux-binary.sh
```
脚本会自动完成:
1. 检查项目内 Linux 二进制构建环境是否存在
2. 如不存在,则下载项目内 `micromamba` 二进制工具
3.`tools/linux-build-env/` 内安装 CMake、Ninja、Clang、Qt、OpenCV 等二进制依赖
4. 使用项目内 Clang / CMake / Ninja 配置并构建项目
5. 输出 Linux 可执行文件:
```text
build-linux/chengnan
```
### 生成发布包
如需生成可分发的 Linux x86_64 发布包,执行:
```bash
cd /root/chengnan
./scripts/package-linux-release.sh
```
脚本会先执行 Release 构建,再将程序、项目内 Qt/OpenCV 运行时库、Qt 插件和启动脚本打包到:
```text
dist-linux/chengnan-linux-x86_64.tar.gz
dist-linux/chengnan-linux-x86_64.tar.gz.sha256
```
解压后在有 X11 / Wayland 图形会话的 Linux 桌面环境中运行:
```bash
tar -xzf chengnan-linux-x86_64.tar.gz
./chengnan-linux-x86_64/run-chengnan.sh
```
### 分步构建
如果希望先准备依赖,再单独构建:
```bash
cd /root/chengnan
./scripts/setup-linux-binary-deps.sh
./scripts/build-linux-binary.sh
```
### 手动等价构建命令
以下命令等价于脚本中的核心构建逻辑,适合调试 CMake 参数:
```bash
cd /root/chengnan
export PATH="$PWD/tools/linux-build-env/bin:$PATH"
export CMAKE_PREFIX_PATH="$PWD/tools/linux-build-env"
export PKG_CONFIG_PATH="$PWD/tools/linux-build-env/lib/pkgconfig:$PWD/tools/linux-build-env/share/pkgconfig:${PKG_CONFIG_PATH:-}"
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:${LD_LIBRARY_PATH:-}"
export CC="$PWD/tools/linux-build-env/bin/clang"
export CXX="$PWD/tools/linux-build-env/bin/clang++"
cmake -S . -B build-linux \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX" \
-DCMAKE_INSTALL_PREFIX="$PWD/dist-linux"
cmake --build build-linux --parallel "$(nproc)"
```
### 运行程序
构建完成后运行:
```bash
cd /root/chengnan
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:${LD_LIBRARY_PATH:-}"
./build-linux/chengnan
```
如果在无桌面环境或 SSH 终端中运行Qt 图形界面可能无法显示,需要在有 X11 / Wayland 图形会话的 Linux 桌面环境中运行。
## 已清理的历史依赖
之前为了尝试构建曾产生过源码编译或非目标平台相关内容,目前已删除:
```text
third_party/opencv-src
third_party/opencv-build
third_party/opencv
third_party/qt-sdk
third_party/qt
third_party/opengl-stub
tools/uv
tools/pyenv
tools/cmake
tools/cmake.tar.gz
```
这些内容被删除的原因:
- `opencv-src` / `opencv-build` / `opencv` 属于源码编译安装路径,不符合“只使用二进制安装”的要求
- `qt-sdk` / `qt` 是 Linux 本地尝试阶段的旧 Qt 目录,需要按新的 Linux 二进制依赖规范重新放置
- `opengl-stub` 是临时构建验证用内容,不属于正式项目依赖
- `tools/uv` / `tools/pyenv` 是 uv 相关环境不符合“Python 使用虚拟环境,不使用 uv 安装”的要求
- `tools/cmake` 是旧 Linux CMake 工具目录,后续应按 `tools/cmake-linux/` 重新放置二进制工具
## 当前项目内已有的二进制依赖记录
当前目录中仍保留过 Windows 方案准备的二进制包和脚本,作为历史记录和可选参考,但**后续 Linux 构建不应使用这些 Windows 工具链**
```text
third_party/qt-windows-msvc-sdk/
third_party/qt-windows-msvc
third_party/opencv-windows-extract/
third_party/opencv-windows
third_party/qt-tools/
tools/cmake-windows/
tools/cmake-current-windows
tools/python-bin/
scripts/build-windows.ps1
scripts/setup-python-venv-windows.ps1
DEPENDENCIES.md
```
已验证这些文件曾存在:
```text
third_party/qt-windows-msvc/bin/qmake.exe
third_party/qt-windows-msvc/bin/windeployqt.exe
third_party/opencv-windows/x64/vc16/lib/OpenCVConfig.cmake
third_party/opencv-windows/x64/vc16/lib/opencv_world4100.lib
third_party/opencv-windows/x64/vc16/bin/opencv_world4100.dll
third_party/qt-tools/Tools/Ninja/ninja.exe
tools/cmake-current-windows/bin/cmake.exe
tools/python-bin/python.exe
```
这些 Windows 二进制内容不满足“在 Linux 里面编译,不使用 Windows 编译工具链”的新要求,因此 Linux 构建流程不应引用它们。
## Linux 构建目标
后续应补充或替换为 Linux 二进制依赖:
- Linux 版 CMake 二进制包
- Linux 版 Ninja 二进制包
- Linux 版二进制 C++ 编译器工具链,例如 LLVM/Clang 预编译包
- Linux 版 Qt 二进制包
- Linux 版 OpenCV 二进制包
- 项目内 Python 二进制包和虚拟环境
构建脚本建议命名为:
```text
scripts/setup-python-venv-linux.sh
scripts/build-linux-binary.sh
```
示例构建命令应类似:
```bash
./scripts/build-linux-binary.sh
```
该脚本应只使用项目内路径,例如:
```bash
export PATH="$PWD/tools/cmake-linux/bin:$PWD/tools/ninja-linux:$PWD/tools/compiler-linux/bin:$PATH"
export CMAKE_PREFIX_PATH="$PWD/third_party/qt-linux;$PWD/third_party/opencv-linux"
```
但脚本不得写入系统环境,也不得调用系统 GCC/G++ 作为项目编译器。
## 项目目标
使用 Qt 设计图形化界面,结合 OpenCV 实现图像的读取、显示、保存、基础几何处理,以及分类或目标提取功能。程序需要支持处理前后图像对比显示,并在图像处理流程中尽量使用 Qt 线程,避免阻塞界面。
## 技术要求
### 1. 开发框架
- GUI 框架Qt建议 Qt 6.x使用 Qt Widgets
- 图像处理库OpenCV
- 构建系统CMake
- 编程语言C++17 或更高版本
- 图像显示:必须使用 Qt 的 QWidget / QLabel / QGraphicsView 等控件显示图像
- 禁止使用:`cv::imshow``cv::waitKey` 等 OpenCV 窗口显示方式
### 2. 界面功能要求
界面由 Qt 设计实现,至少应包含以下基础功能:
- 打开图片
- 保存图片
- 另存图片
- 显示原始图片
- 显示处理后的图片
- 支持处理前、处理后图像的对比观看
- 显示当前操作状态或处理结果提示
建议界面布局:
- 左侧显示原始图片
- 右侧显示处理后图片
- 顶部或侧边栏放置操作按钮
- 底部状态栏显示当前文件路径、处理状态、图片尺寸等信息
### 3. 图像基础处理要求
图片处理应包含以下简单操作:
- 缩放
- 放大
- 缩小
- 按比例缩放
- 平移
- 向上、下、左、右移动图像显示区域或图像内容
- 旋转
- 顺时针旋转
- 逆时针旋转
- 指定角度旋转
可选增强功能:
- 灰度化
- 二值化
- 亮度 / 对比度调节
- 滤波 / 模糊
- 边缘检测
- 撤销 / 重做
### 4. 分类或目标提取功能要求
程序应至少实现以下两项功能之一,两者皆有最佳:
#### 方案 A图像分类
可实现简单图像分类,例如:
- 根据颜色占比进行分类
- 根据亮度、纹理、边缘数量进行规则分类
- 使用 OpenCV DNN 加载轻量模型进行分类
分类结果应显示在界面中,例如:
- 图片类型
- 置信度或规则判断依据
- 分类耗时
#### 方案 B目标提取
可实现目标提取,例如:
- 阈值分割
- 颜色区域提取
- 轮廓检测
- 边缘检测
- 前景目标提取
目标提取结果应显示在处理后图像窗口中,并可叠加以下信息:
- 目标轮廓
- 外接矩形
- 目标数量
- 面积、中心点等简单特征
建议优先实现目标提取,再扩展简单分类功能。
### 5. 显示要求
- 必须具有图像显示功能
- 必须显示处理前、处理后的图像对比
- 显示控件必须基于 QWidget 体系
- 不允许使用 OpenCV 的 `cv::imshow` 显示图片
- OpenCV 的 `cv::Mat` 与 Qt 的 `QImage` / `QPixmap` 之间应封装转换函数
### 6. 线程要求
考虑图像处理使用 Qt 线程,避免大图像处理时卡住主界面。
建议设计:
- 主线程:负责 UI 显示、按钮响应、用户交互
- 工作线程:负责 OpenCV 图像处理、分类、目标提取
- 线程通信:使用 Qt 信号与槽
- 禁止在工作线程中直接操作 QWidget 控件
建议类设计:
- `MainWindow`:主窗口,负责 UI 和用户操作
- `ImageProcessor`:图像处理逻辑类
- `ImageWorker`:运行在 QThread 中的图像处理工作对象
- `ImageConverter`:负责 `cv::Mat``QImage` 转换
### 7. 环境与依赖安装要求
所有安装的依赖不得污染本地系统环境,必须采用项目文件夹内二进制安装或指定路径解压的方式。
要求:
- 在 Linux 中编译本项目
- 不使用 Windows 编译工具链
- 不使用系统 GCC / G++ 作为项目构建工具链
- 不使用源码编译安装 Qt / OpenCV 等依赖
- 不建议直接全局安装 Qt 或 OpenCV
- 不建议污染系统 `/usr``/usr/local` 等全局路径
- 建议将依赖安装到项目目录下,例如:
- `chengnan/third_party/qt-linux/`
- `chengnan/third_party/opencv-linux/`
- `chengnan/tools/cmake-linux/`
- `chengnan/tools/ninja-linux/`
- `chengnan/tools/compiler-linux/`
- `chengnan/tools/python-venv/`
- CMake 通过 `CMAKE_PREFIX_PATH` 指向项目内依赖路径
- 构建目录使用 `chengnan/build-linux/`
- 可使用脚本统一配置环境变量,但只能影响当前进程,不修改系统环境变量
示例目录:
```text
chengnan/
├── README.md
├── CMakeLists.txt
├── .gitignore
├── app/
│ ├── include/
│ │ ├── MainWindow.h
│ │ ├── ImageView.h
│ │ ├── ImageProcessor.h
│ │ ├── ImageWorker.h
│ │ └── ImageConverter.h
│ └── src/
│ ├── main.cpp
│ ├── MainWindow.cpp
│ ├── ImageView.cpp
│ ├── ImageProcessor.cpp
│ ├── ImageWorker.cpp
│ └── ImageConverter.cpp
├── docs/
│ └── windows/ # 历史 Windows 依赖说明和脚本,仅作参考,不参与 Linux 构建
├── scripts/
│ ├── setup-linux-binary-deps.sh
│ ├── setup-python-venv-linux.sh
│ └── build-linux-binary.sh
├── tools/
│ ├── linux-build-env/ # 项目内 Linux 二进制构建环境Git 忽略
│ ├── cmake-linux -> linux-build-env
│ ├── ninja-linux -> linux-build-env
│ ├── compiler-linux -> linux-build-env
│ ├── python-bin -> linux-build-env
│ └── python-venv -> linux-build-env
├── third_party/
│ ├── qt-linux -> ../tools/linux-build-env
│ └── opencv-linux -> ../tools/linux-build-env
└── build-linux/ # Linux 构建输出目录Git 忽略
```
示例 CMake 配置方式应写入脚本中统一执行,不能依赖系统工具链:
```bash
./scripts/setup-linux-binary-deps.sh
./scripts/build-linux-binary.sh
```
脚本会在项目目录内使用 Linux 二进制包创建隔离环境,并只在当前进程内设置环境变量。核心等价配置如下:
```bash
export PATH="$PWD/tools/linux-build-env/bin:$PATH"
export CMAKE_PREFIX_PATH="$PWD/tools/linux-build-env"
export PKG_CONFIG_PATH="$PWD/tools/linux-build-env/lib/pkgconfig:$PWD/tools/linux-build-env/share/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$PWD/tools/linux-build-env/lib:$LD_LIBRARY_PATH"
export CC="$PWD/tools/linux-build-env/bin/clang"
export CXX="$PWD/tools/linux-build-env/bin/clang++"
cmake -S . -B build-linux \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_CXX_COMPILER="$CXX"
cmake --build build-linux -j$(nproc)
```
如需临时设置运行环境,建议写入脚本,不写入系统全局配置:
```bash
export PATH="$PWD/third_party/qt-linux/bin:$PWD/tools/cmake-linux/bin:$PWD/tools/ninja-linux:$PWD/tools/compiler-linux/bin:$PATH"
export LD_LIBRARY_PATH="$PWD/third_party/qt-linux/lib:$PWD/third_party/opencv-linux/lib:$LD_LIBRARY_PATH"
```
## 推荐实现步骤
1. 创建 Qt Widgets + CMake 项目结构
2. 实现主窗口和基本按钮:打开、保存、另存
3. 实现图片显示控件,完成原图和处理图对比显示
4. 封装 `cv::Mat``QImage` 的转换工具
5. 实现缩放、平移、旋转等基础处理
6. 将图像处理逻辑迁移到 `QThread` 工作线程
7. 实现目标提取功能,例如阈值分割 + 轮廓检测
8. 可选实现简单分类功能
9. 完成保存处理结果图片
10. 编写 Linux 本地二进制工具链构建脚本,确保 Qt、OpenCV、CMake、Ninja、编译器等工具均放在项目目录内
11. 测试大图处理时界面是否保持响应
12. 完善 README、运行说明和截图
## 验收标准
- 可以打开常见图片格式,例如 PNG、JPG、BMP
- 可以保存当前处理后的图片
- 可以另存为指定路径
- 可以在同一界面中对比显示处理前和处理后图像
- 支持缩放、平移、旋转操作
- 至少实现分类或目标提取功能之一
- 图像显示使用 QWidget 体系,不使用 `cv::imshow`
- 图像处理任务不会明显阻塞 UI
- 依赖安装和构建必须限制在项目目录内,不污染系统环境
- 在 Linux 中编译,不使用 Windows 编译工具链
- 所有工具和依赖使用二进制包或解压式安装,不使用源码编译安装
## 注意事项
- QWidget 只能在主线程中创建和更新
- 工作线程只处理数据,不直接改 UI
- 大图处理时应避免频繁深拷贝,可合理使用 `cv::Mat::clone()` 控制生命周期
- `QImage``cv::Mat` 共享内存时要注意对象生命周期
- 保存图片时应保存处理后的图像,而不是原图
- 若使用 OpenCV DNN 模型,模型文件应放入项目目录,例如 `models/`
- 所有脚本应避免执行破坏性系统操作