使用Ninja配置Msvc编译

This commit is contained in:
qupengwei
2026-01-06 10:21:22 +08:00
parent 9b2a6bf423
commit 158beaabeb
3 changed files with 338 additions and 127 deletions

View File

@@ -2,43 +2,70 @@
## 1. 系统概述 ## 1. 系统概述
本系统是一个基于立体视觉的仓库巡检图像采集与处理系统。它集成了图漾(Percipio)工业相机SDK和海康(MVS)相机SDK进行多相机图像采集使用OpenCV进行图像处理Qt6作为用户界面框架并通过Redis与外部系统如机器人控制系统进行通信和任务调度。 本系统是一个基于立体视觉的仓库巡检图像采集与处理系统。它集成了图漾(Percipio)工业深度相机SDK和海康(MVS)工业2D相机SDK进行多相机图像采集使用OpenCV进行图像处理Qt6作为用户界面框架并通过Redis与外部系统WMS仓库管理系统、机器人控制系统)进行通信和任务调度。
系统主要功能包括: 系统主要功能包括:
- 多相机同步采集(深度图与彩色图) - **多相机统一管理**同时支持深度相机Percipio和2D相机MVS的数据采集
- 实时图像预览与状态监控 - **实时图像预览与状态监控**GUI界面实时显示相机图像支持深度图伪彩色显示
- 基于Redis的任务触发与结果上报 - **基于Redis的任务触发与结果上报**:支持跨数据库的任务监听和结果写入
- 多种检测算法(货位占用、横梁/立柱变形、托盘偏差等) - **多种检测算法**
- 系统配置管理与日志记录 - 货位占用检测Flag 1基于2D图像的目标检测
- 托盘位置偏移检测Flag 2基于深度数据的3D位置计算
- 横梁/立柱变形检测Flag 3基于深度数据的结构变形测量
- 视觉盘点检测Flag 4基于Halcon的QR码识别支持连续扫描和去重
- 盘点停止信号Flag 5停止Flag 4的连续扫描循环
- **智能相机分配**:根据任务类型自动选择合适的相机设备
- **系统配置管理与日志记录**:支持参数持久化、实时日志显示和错误处理
## 2. 目录结构说明 ## 2. 目录结构说明
```text ```text
scripts/ # 批处理脚本 (数据库配置、模拟任务等) scripts/ # 批处理脚本 (Redis数据库配置、模拟WMS任务等)
docs/ # 项目文档
├── project_architecture.md # 项目架构文档 (本文档)
├── project_class_interaction.md # 类交互关系文档
└── cmake_configuration_summary.md # CMake构建配置文档
image_capture/ image_capture/
├── CMakeLists.txt # 主构建配置文件
├── cmake/ # CMake模块配置
│ ├── CompilerOptions.cmake # 编译器选项配置
│ ├── Dependencies.cmake # 依赖项管理 (Qt6, OpenCV, Open3D)
│ └── PercipioSDK.cmake # Percipio相机SDK配置
├── config.json # 系统配置文件 (相机参数、算法阈值、Redis配置等)
└── src/ └── src/
├── algorithm/ # 核心算法库 ├── algorithm/ # 核心算法库
│ ├── core/ # 算法基类与结果定义 (DetectionBase, DetectionResult) │ ├── core/ # 算法基类与结果定义
│ ├── detections/ # 具体检测算法实现 (SlotOccupancy, BeamRackDeflection等) ├── detection_base.h/cpp # 检测算法基类
└── utils/ # 图像处理工具 (ImageProcessor) │ └── detection_result.h/cpp # 检测结果数据结构
│ ├── detections/ # 具体检测算法实现
│ │ ├── slot_occupancy/ # 货位占用检测
│ │ ├── pallet_offset/ # 托盘偏移检测
│ │ ├── beam_rack_deflection/ # 横梁立柱变形检测
│ │ └── visual_inventory/ # 视觉盘点检测
│ └── utils/ # 图像处理工具
├── camera/ # 相机驱动层 ├── camera/ # 相机驱动层
│ ├── ty_multi_camera_capture.cpp/h # 图漾(Percipio) 3D相机封装 │ ├── ty_multi_camera_capture.h/cpp # 图漾(Percipio)深度相机封装
│ └── mvs_multi_camera_capture.cpp/h # 海康(MVS) 2D相机封装 │ └── mvs_multi_camera_capture.h/cpp # 海康(MVS)2D相机封装
├── common/ # 通用设施 ├── common/ # 通用设施
│ ├── config_manager.cpp/h # 配置管理单例 │ ├── config_manager.h/cpp # 配置管理单例 (JSON配置加载/保存)
│ ├── log_manager.cpp/h # 日志管理 │ ├── log_manager.h/cpp # 日志管理 (spdlog封装)
│ └── log_streambuf.h # std::cout重定向到GUI │ └── log_streambuf.h # std::cout重定向到GUI
├── device/ # 硬件设备管理 ├── device/ # 硬件设备管理
│ └── device_manager.cpp/h # 相机设备单例管理 │ └── device_manager.h/cpp # 相机设备单例管理 (统一设备接口)
├── gui/ # 用户界面 ├── gui/ # 用户界面 (Qt6)
│ └── mainwindow.cpp/h/ui # 主窗口实现 (集成Settings Tab) │ └── mainwindow.h/cpp/ui # 主窗口实现 (实时预览+设置界面)
├── redis/ # 通信模块 ├── redis/ # 通信模块
│ └── redis_communicator.cpp/h # Redis客户端封装 │ └── redis_communicator.h/cpp # Redis客户端封装 (跨数据库支持)
├── task/ # 任务调度 ├── task/ # 任务调度
│ └── task_manager.cpp/h # 任务分发与执行逻辑 │ └── task_manager.h/cpp # 任务管理器 (队列+线程+算法调度)
├── vision/ # 系统控制 ├── vision/ # 系统控制
│ └── vision_controller.cpp/h # 顶层控制器,协调RedisTask │ └── vision_controller.h/cpp # 顶层控制器 (Redis+Task协调)
├── common_types.h # 通用数据类型 (Point3D, CameraIntrinsics) ├── common_types.h # 通用数据类型 (Point3D, CameraIntrinsics)
├── tools/ # 工具程序目录
│ ├── calibration_tool/ # 相机标定工具
│ ├── slot_algo_tuner/ # 货位算法调参工具
│ └── intrinsic_dumper/ # 相机内参导出工具
└── main.cpp # 程序入口 └── main.cpp # 程序入口
``` ```
@@ -46,11 +73,11 @@ image_capture/
系统采用分层架构设计,各模块职责明确: 系统采用分层架构设计,各模块职责明确:
- **展示层 (GUI)**: `MainWindow` 负责界面显示、手动控制、参数配置及日志展示。 - **展示层 (Presentation)**: `MainWindow` 负责Qt6界面显示、实时相机预览、手动控制、参数配置及日志展示。
- **控制层 (Controller)**: `VisionController` 作为系统级控制器,负责服务的启动/停止,协调 `RedisCommunicator``TaskManager` - **控制层 (Control)**: `VisionController` 作为系统级控制器,负责服务的启动/停止协调Redis通信和任务管理,使用回调机制解耦模块间依赖
- **业务逻辑层 (Task/Manager)**: `TaskManager` 解析任务指令,`DeviceManager` 管理硬件资源。 - **业务逻辑层 (Business Logic)**: `TaskManager` 负责任务队列管理、算法调度和结果处理;`DeviceManager` 作为硬件资源的统一访问点(单例模式)
- **算法层 (Algorithm)**: 提供具体的视觉检测功能,继承自 `DetectionBase` - **算法层 (Algorithm)**: 提供具体的视觉检测功能,所有算法继承自 `DetectionBase`,支持统一的 `execute()` 接口
- **驱动层 (Driver)**: `CameraCapture` 封装底层SDK调用。 - **基础设施层 (Infrastructure)**: `CameraCapture` 封装底层相机SDK调用`RedisCommunicator` 处理跨数据库通信,`ConfigManager` 管理系统配置
### 系统分层架构图 ### 系统分层架构图
@@ -112,101 +139,187 @@ graph TB
classDiagram classDiagram
class MainWindow { class MainWindow {
+VisionController visionController_ +VisionController visionController_
+QTimer imageTimer_
+updateImage() +updateImage()
+onSaveSettings() +onSaveSettings()
+showLogMessage()
} }
class VisionController { class VisionController {
+RedisCommunicator redis_comm_ +shared_ptr<RedisCommunicator> redis_comm_
+TaskManager task_manager_ +shared_ptr<RedisCommunicator> redis_result_comm_
+shared_ptr<TaskManager> task_manager_
+initialize()
+start() +start()
+stop() +stop()
-onTaskReceived()
} }
class DeviceManager { class DeviceManager {
<<Singleton>> <<Singleton>>
+CameraCapture camera_capture_ +shared_ptr<CameraCapture> capture_
+unique_ptr<MvsMultiCameraCapture> mvs_cameras_
+initialize() +initialize()
+startAll()
+getLatestImages()
+computePointCloud() +computePointCloud()
+get2DCameraImage()
} }
class TaskManager { class TaskManager {
+executeTask() +queue<RedisTaskData> task_queue_
-algorithms_ map +map<int, DetectionBase*> detectors_
+thread execution_thread_
+handleTask()
+executeDetectionTask()
-executeVisualInventoryLoop()
-processResult()
-addWarningAlarmSignals()
} }
class CameraCapture { class CameraCapture {
+vector<CameraInfo> cameras_
+getLatestImages() +getLatestImages()
+computePointCloud() +computePointCloud()
+start() +start()
-captureThreadFunc() -captureThreadFunc()
} }
class MvsMultiCameraCapture {
+vector<CameraInfo> cameras_
+getLatestImage()
+start()
}
class RedisCommunicator { class RedisCommunicator {
+connect() +connect()
+listenForTasks() +startListening()
+publishResult() +writeString()
+setTaskCallback()
} }
class ConfigManager { class ConfigManager {
<<Singleton>> <<Singleton>>
+json config_data_
+loadConfig() +loadConfig()
+saveConfig() +saveConfig()
+getValue()
} }
MainWindow --> VisionController : 只有与管理 class DetectionBase {
VisionController --> RedisCommunicator : 使用 <<Abstract>>
VisionController --> TaskManager : 使用 +execute(depth, color, side, result, point_cloud, beam_length)
}
VisionController ..> DeviceManager : 依赖(全局)
TaskManager ..> DeviceManager : 获取图像/点云 class SlotOccupancyDetection {
DeviceManager --> CameraCapture : 拥有 +execute()
}
MainWindow ..> ConfigManager : 读写配置
TaskManager ..> ConfigManager : 读取参数 class PalletOffsetDetection {
+execute()
}
class BeamRackDeflectionDetection {
+execute()
}
class VisualInventoryDetection {
+execute()
}
MainWindow --> VisionController : 拥有并管理
VisionController --> RedisCommunicator : 管理 (任务监听)
VisionController --> TaskManager : 分发任务
RedisCommunicator --> VisionController : 回调通知 (onTaskReceived)
VisionController ..> DeviceManager : 依赖(全局单例)
TaskManager ..> DeviceManager : 获取图像数据 (Dependency)
DeviceManager --> CameraCapture : 拥有 (深度相机)
DeviceManager --> MvsMultiCameraCapture : 拥有 (2D相机)
TaskManager --> DetectionBase : 调用算法
DetectionBase <|-- SlotOccupancyDetection : 继承
DetectionBase <|-- PalletOffsetDetection : 继承
DetectionBase <|-- BeamRackDeflectionDetection : 继承
DetectionBase <|-- VisualInventoryDetection : 继承
MainWindow ..> ConfigManager : 读写配置 (Dependency)
TaskManager ..> ConfigManager : 读取参数 (Dependency)
MainWindow ..> DeviceManager : 图像显示 (Dependency)
``` ```
## 4. 关键模块详解 ## 4. 关键模块详解
### 4.1 GUI与主入口 (MainWindow) ### 4.1 GUI与主入口 (MainWindow)
- **职责**: 程序的主要入负责UI渲染、用户交互、参数配置及系统状态反馈 - **职责**: Qt6应用程序主窗负责UI渲染、用户交互、参数配置、实时预览及日志展示
- **调用关系**: - **调用关系**:
- 初始化时创建 `VisionController` - 程序启动时创建 `VisionController` 并初始化系统
- 通过 `QTimer` 定期从 `DeviceManager` 获取图像更新界面。 - 通过 `QTimer` (30FPS) 定期从 `DeviceManager` 获取最新图像更新界面显示
- **Settings Tab**: 直接在 `MainWindow` 中实现,提供 "Beam/Rack Deflection", "Pallet Offset" 等算法参数配置界面 - **实时预览**: 支持深度图伪彩色显示和彩色图显示,带自适应缩放
- 通过 `ConfigManager` 加载和保存配置,包括ROI点坐标和各类阈值。 - **设置界面**: Settings Tab提供完整的算法参数配置,包括
- Beam/Rack Deflection: 横梁/立柱变形检测阈值和ROI配置
- Pallet Offset: 托盘位置偏移检测参数
- 系统配置: Redis连接参数、相机设置等
- **日志显示**: 通过 `LogStreamBuf``std::cout/cerr` 重定向到GUI日志窗口。
- 通过 `ConfigManager` 加载和保存 `config.json` 配置,支持热重载。
### 4.2 视觉控制器 (VisionController) ### 4.2 视觉控制器 (VisionController)
- **职责**: 系统的"大脑"不依赖于GUI运行设计上支持无头模式 - **职责**: 系统的核心控制器协调Redis通信和任务管理支持无头模式运行
- **流程**: - **架构特点**:
1. `initialize()`: 连接Redis - 使用智能指针管理 `RedisCommunicator``TaskManager` 生命周期
2. `start()`: 启动Redis监听线程 - 支持跨数据库Redis操作任务监听DB(输入)和结果写入DB(输出)
3. `onTaskReceived()`: 当Redis收到任务时转发给 `TaskManager` - 通过回调机制实现模块解耦,避免循环依赖
- **工作流程**:
1. `initialize()`: 创建并初始化两个Redis连接器任务DB和结果DB
2. 初始化 `TaskManager`传入Redis连接器用于结果写入和任务状态清空。
3. `start()`: 启动Redis任务监听线程设置任务接收回调。
4. `onTaskReceived()`: 收到Redis任务时通过回调转发给 `TaskManager::handleTask()`
### 4.3 任务管理 (TaskManager) ### 4.3 任务管理 (TaskManager)
- **职责**: 解析Redis下发的JSON指令选择合适的算法执行 - **职责**: 任务队列管理、算法调度、结果处理和跨线程执行的核心业务逻辑处理器
- **架构特点**:
- **异步处理**: 使用任务队列 + 独立执行线程避免阻塞Redis监听和GUI。
- **相机智能分配**: 根据任务Flag自动选择合适的相机设备和数据类型。
- **去重机制**: Flag 4视觉盘点支持连续扫描和QR码去重。
- **状态管理**: 提供任务执行状态查询接口,支持外部监控。
- **工作流**: - **工作流**:
1. 接收任务ID和参数 1. `handleTask()`: 接收Redis任务加入线程安全的任务队列
2. `DeviceManager` 获取当前最新的一帧图像(深度+彩色) 2. `taskExecutionThreadFunc()`: 后台线程持续处理队列任务
3. **点云生成**: 对于需要3D数据的任务Flag 2/3调用 `DeviceManager::computePointCloud()` 生成点云。 3. **相机选择**: 根据Flag选择相机
4. 根据任务类型实例化或调用相应的 `DetectionBase` 子类。 - Flag 1: MVS 2D相机 (SN: DA8743029左/DA8742900右)
5. 执行 `detect()`,传入图像和点云数据。 - Flag 2/3: Percipio深度相机 (SN: 207000146458左/207000146703右)
6. 将结果打包为JSON通过回调或直接通过 `RedisCommunicator` 返回。 - Flag 4: MVS 2D相机 (SN: DA8789631) + 连续扫描循环
4. **数据获取**: 调用 `DeviceManager` 获取图像Flag 2/3时生成点云。
5. **算法执行**: 调用对应的 `DetectionBase::execute()` 方法。
6. **结果处理**: `processResult()` 格式化JSON、计算警告/报警、写入Redis结果DB。
### 4.4 设备管理 (DeviceManager) ### 4.4 设备管理 (DeviceManager)
- **职责**: 硬件资源的全局访问点(单例模式) - **职责**: 多类型相机的统一管理接口,全系统硬件资源的单例访问点。
- **封装**: 内部持有 `CameraCapture` 实例,确保相机资源全生命周期只被初始化一次。 - **架构特点**:
- **功能**: - **双SDK支持**: 同时管理Percipio深度相机和MVS 2D相机。
- 提供线程安全的图像获取接口 `getLatestImages()` - **统一接口**: 提供一致的设备枚举、启动/停止和数据获取接口
- 提供点云计算接口 `computePointCloud()`利用SDK内部参数生成高精度点云 - **线程安全**: 所有接口都是线程安全的,支持并发访问
- **资源管理**: 使用智能指针和RAII确保相机资源正确释放。
- **功能**:
- `initialize()`: 扫描并初始化所有类型的相机设备。
- `getLatestImages()`: 统一的图像获取接口,支持深度图+彩色图。
- `get2DCameraImage()`: 专门的2D相机图像获取接口。
- `computePointCloud()`: 基于深度图和相机内参计算3D点云。
- **相机索引映射**: 内部管理深度相机和2D相机的索引映射。
### 4.5 相机驱动 (CameraCapture) ### 4.5 相机驱动
- **实现**: `ty_multi_camera_capture.cpp` - **Percipio深度相机** (`ty_multi_camera_capture.cpp`):
- **机制**: - 基于图漾工业相机SDK支持TY系列深度相机。
- 为每个相机开启独立采集线程。 - 为每个相机维护独立采集线程和帧缓冲区
- 维护内部帧缓冲区 - 支持深度图和彩色图同步采集,内部处理时间戳对齐
- 将SDK的 `TYImage` 转换为 OpenCV `cv::Mat` - **点云计算**: 集成 `TYMapDepthImageToPoint3d`利用相机标定参数生成精确3D点云
- **点云优化**: 内部集成 `TYMapDepthImageToPoint3d`利用相机标定参数直接计算3D点云消除畸变 - 自动畸变校正和深度数据滤波
- **MVS 2D相机** (`mvs_multi_camera_capture.cpp`):
- 基于海康工业相机SDK支持MV系列2D相机。
- 支持连续采集模式,内部缓冲区管理。
- 提供高帧率彩色图像采集,适用于快速检测场景。
- 支持相机序列号匹配,便于多相机场景下的设备识别。
### 4.6 配置管理 (ConfigManager) ### 4.6 配置管理 (ConfigManager)
- **职责**: 管理 `config.json` 文件,集中管理系统配置。 - **职责**: 管理 `config.json` 文件,集中管理系统配置。
@@ -220,87 +333,181 @@ classDiagram
## 5. 系统执行与数据流 ## 5. 系统执行与数据流
### 5.1 初始化流程 ### 5.1 初始化流程
1. `main()` 启动 `QApplication` 1. **程序启动**: `main.cpp` 创建Qt6应用程序设置Fusion样式
2. `MainWindow` 构造: 2. **MainWindow构造**:
- 初始化UI - 初始化Qt6 UI界面主窗口 + Settings选项卡
- **调用 `ConfigManager::getInstance().loadConfig()` 加载本地配置。** - **配置加载**: 调用 `ConfigManager::loadConfig()` `config.json` 加载系统配置。
- 调用 `DeviceManager::getInstance().initialize()` 初始化相机。 - **设备初始化**: 调用 `DeviceManager::initialize()` 扫描Percipio和MVS相机。
- 创建并初始`VisionController`(连接 Redis,但暂不启动监听) - **控制器创建**: 实例`VisionController`,传入Redis配置参数
- 启动定时器调用 `updateImage()` 刷新界面显示 - **Redis初始化**: `VisionController::initialize()` 创建任务监听和结果写入的Redis连接器
3. 启动设备采集:调用 `DeviceManager::startAll()` - **定时器启动**: 启动30FPS的 `QTimer` 用于实时图像预览
4. 设备启动成功后再调用 `VisionController::start()` 开启 Redis 监听,确保任务到来时设备已就绪 3. **设备启动**: 调用 `DeviceManager::startAll()` 启动所有相机采集线程
4. **服务启动**: 调用 `VisionController::start()` 开启Redis监听确保设备就绪后再接收任务。
### 5.2 自动任务执行流 (Redis触发) ### 5.2 自动任务执行流 (Redis触发)
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant Redis participant WMS as WMS/外部系统
participant RC as RedisCommunicator participant Redis_Task as Redis_Task_DB
participant RC_Task as RedisCommunicator_Task
participant VC as VisionController participant VC as VisionController
participant TM as TaskManager participant TM as TaskManager
participant DM as DeviceManager participant DM as DeviceManager
participant Algo as DetectionAlgorithm participant Algo as DetectionAlgorithm
participant RC_Result as RedisCommunicator_Result
participant Redis_Result as Redis_Result_DB
WMS->>Redis_Task: SET vision_task_flag=1,side=left,time=xxx
Redis_Task->>RC_Task: Key change notification
RC_Task->>VC: onTaskReceived(task_data)
VC->>TM: handleTask(task_data)
Redis->>RC: Publish Task (JSON)
RC->>VC: onTaskReceived(data)
VC->>TM: executeTask(data)
activate TM activate TM
TM->>DM: getLatestImages() TM->>TM: Queue task (async)
DM-->>TM: depth_img, color_img TM->>DM: getLatestImages() or get2DCameraImage()
DM-->>TM: images (depth+color or 2D only)
TM->>DM: computePointCloud(depth)
DM-->>TM: point_cloud (vector<Point3D>)
TM->>Algo: execute(images, point_cloud) alt Flag 2/3 (需要点云)
TM->>DM: computePointCloud(depth)
DM-->>TM: point_cloud (vector<Point3D>)
end
TM->>Algo: execute(images, point_cloud, ...)
activate Algo activate Algo
Algo-->>TM: DetectionResult Algo-->>TM: DetectionResult
deactivate Algo deactivate Algo
TM->>TM: processResult() TM->>TM: processResult() + addWarningAlarmSignals()
TM->>RC: writeString(key, value) TM->>RC_Result: writeDetectionResult(json_map)
RC->>Redis: Set Key-Value RC_Result->>Redis_Result: MSET key1=value1 key2=value2 ...
TM->>RC_Task: writeString(vision_task_flag, "0")
TM->>RC_Task: writeString(vision_task_side, "")
TM->>RC_Task: writeString(vision_task_time, "")
RC_Task->>Redis_Task: Clear task flags
deactivate TM deactivate TM
``` ```
1. **外部触发**: Redis 发布任务消息 1. **外部触发**: WMS系统通过Redis Task DB发布任务设置 `vision_task_flag``side``time`
2. **接收**: `RedisCommunicator` 监听到消息,触发回调 2. **异步接收**: `RedisCommunicator_Task` 监听Task DB触发回调给 `VisionController`
3. **调度**: `VisionController` 调用 `TaskManager::executeTask()` 3. **任务队列**: `VisionController` 将任务加入 `TaskManager` 的线程安全队列
4. **获取数据**: `TaskManager` `DeviceManager` 获取最新帧。 4. **后台执行**: `TaskManager` 执行线程处理任务根据Flag选择相机和算法
5. **算法处理**: 调用相应算法(如 `SlotOccupancyDetection::detect`)。 - **Flag 1**: MVS 2D相机 → `SlotOccupancyDetection`
6. **结果反馈**: 结果封装成JSON通过 `RedisCommunicator` 写入Redis结果队列。 - **Flag 2**: Percipio深度相机 → `PalletOffsetDetection` (带点云)
7. **任务复位**: 结果写入完成后,将 `vision_task_flag``0``vision_task_side`/`vision_task_time` 置空,避免程序重启后被旧任务自动触发。 - **Flag 3**: Percipio深度相机 → `BeamRackDeflectionDetection` (带点云)
- **Flag 4**: MVS 2D相机 → `VisualInventoryDetection` (连续循环+QR识别)
5. **智能数据获取**: 根据任务类型调用相应的 `DeviceManager` 接口。
6. **结果处理**: 计算警告/报警信号格式化JSON结果。
7. **跨DB写入**: 结果写入Redis Result DB任务状态清理写入Task DB。
### 5.3 实时监控执行流 (GUI) ### 5.3 实时监控执行流 (GUI)
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant Timer as QTimer participant Timer as QTimer (30FPS)
participant MainWin as MainWindow participant MainWin as MainWindow
participant DM as DeviceManager participant DM as DeviceManager
Timer->>MainWin: timeout() loop 每33ms
activate MainWin Timer->>MainWin: timeout()
MainWin->>DM: getLatestImages() activate MainWin
DM-->>MainWin: depth_img, color_img MainWin->>DM: getLatestImages(0) + get2DCameraImage(0)
DM-->>MainWin: depth_img, color_img, mvs_img
MainWin->>MainWin: Convert to QImage
MainWin->>MainWin: update QLabel alt 深度相机活跃
deactivate MainWin MainWin->>MainWin: applyColorMap(depth_img) → 伪彩色显示
else 2D相机活跃
MainWin->>MainWin: 显示彩色图像
end
MainWin->>MainWin: MatToQImage() + scaleToFit()
MainWin->>MainWin: update QLabel displays
deactivate MainWin
end
``` ```
1. **定时刷新**: `MainWindow``QTimer` 触发 `updateImage()` 1. **高频刷新**: `QTimer` 以30FPS触发 `updateImage()`,确保流畅的实时预览
2. **数据拉取**: 调用 `DeviceManager::getInstance().getLatestImages()` 2. **多相机预览**: 同时获取深度相机和2D相机的最新图像支持混合显示
3. **渲染**: 将OpenCV Mat 转换为 QImage 并显示在 `QLabel` 3. **图像处理**: 深度图应用伪彩色映射,便于观察深度信息;彩色图直接显示
- 深度图进行伪彩色处理以便观察 4. **自适应渲染**: OpenCV Mat转换为QImage支持窗口大小自适应缩放
- 自适应窗口大小缩放 5. **状态同步**: 图像显示与任务执行异步进行,不影响检测性能
## 6. 异常处理与日志 ## 6. 异常处理与日志
- **日志**: 使用 `LogManager``spdlog` (如果集成) 或标准输出。 - **日志**: 使用 `LogManager``spdlog` (如果集成) 或标准输出。
- **重定向**: `LogStreamBuf``std::cout/cerr` 重定向到GUI的日志窗口方便现场调试。 - **重定向**: `LogStreamBuf``std::cout/cerr` 重定向到GUI的日志窗口方便现场调试。
- **错误恢复**: 相机掉线重连机制(在驱动层实现或计划中)。 - **错误恢复**: 相机掉线重连机制(在驱动层实现或计划中)。
## 6. 检测算法详解
### 6.1 算法框架 (DetectionBase)
所有检测算法继承自 `DetectionBase` 抽象基类,提供统一的接口:
```cpp
virtual bool execute(const cv::Mat& depth_img,
const cv::Mat& color_img,
const std::string& side,
DetectionResult& result,
const std::vector<Point3D>* point_cloud = nullptr,
double beam_length = 0.0) = 0;
```
### 6.2 具体算法实现
#### Flag 1: 货位占用检测 (SlotOccupancyDetection)
- **输入**: 2D彩色图像 (MVS相机)
- **算法**: 基于图像处理的目标检测和位置判断
- **输出**: 货位占用状态 (occupied/free)
- **相机**: DA8743029 (左侧), DA8742900 (右侧)
#### Flag 2: 托盘位置偏移检测 (PalletOffsetDetection)
- **输入**: 深度图 + 彩色图 + 3D点云
- **算法**: 基于点云的3D位置计算检测托盘相对于基准位置的偏移
- **输出**: 左右偏移(mm)、前后偏移(mm)、插孔变形(mm)、旋转角度(°)
- **相机**: 207000146458 (左侧), 207000146703 (右侧)
- **警告/报警**: 基于阈值的四级判断 (正常/警告/报警)
#### Flag 3: 横梁/立柱变形检测 (BeamRackDeflectionDetection)
- **输入**: 深度图 + 彩色图 + 3D点云
- **算法**: 基于点云的结构变形测量
- **输出**: 横梁弯曲量(mm)、立柱弯曲量(mm)
- **相机**: 207000146458 (左侧), 207000146703 (右侧)
- **警告/报警**: 基于阈值的四级判断
#### Flag 4: 视觉盘点检测 (VisualInventoryDetection)
- **输入**: 2D彩色图像 (MVS相机)
- **算法**: 基于Halcon的QR码识别支持连续扫描和去重
- **特殊机制**: 循环执行直到收到Flag 5停止信号支持实时去重
- **输出**: JSON格式的条码列表 `{"side": ["BOX001", "BOX002", ...]}`
- **相机**: DA8789631 (专用盘点相机)
#### Flag 5: 盘点停止信号
- **功能**: 停止Flag 4的连续扫描循环
- **无算法执行**: 仅作为控制信号
### 6.3 相机分配策略
系统根据任务Flag智能选择相机
| Flag | 相机类型 | 序列号 | 位置 | 数据类型 |
|------|---------|--------|------|----------|
| 1 | MVS 2D | DA8743029 / DA8742900 | 左/右 | 彩色图 |
| 2 | Percipio深度 | 207000146458 / 207000146703 | 左/右 | 深度+彩色+点云 |
| 3 | Percipio深度 | 207000146458 / 207000146703 | 左/右 | 深度+彩色+点云 |
| 4 | MVS 2D | DA8789631 | 盘点专用 | 彩色图 |
## 7. 编译与构建 ## 7. 编译与构建
- **工具**: CMake - **构建系统**: CMake 3.10+
- **依赖**: Qt6, OpenCV 4.x, Percipio SDK, (Redis库通常被封装或作为源码包含) - **编程语言**: C++17
- **平台**: Windows (MSVC/MinGW) - **目标平台**: Windows 10/11 (MSVC 2022 v143)
- **主要依赖**:
- **Qt6**: Widgets组件 (GUI框架)
- **OpenCV 4.x**: 图像处理和计算机视觉
- **Open3D 0.17+**: 3D点云处理
- **Percipio SDK**: 图漾工业相机驱动
- **MVS SDK**: 海康工业相机驱动
- **Redis C++ Client**: hiredis + redis-plus-plus (Redis通信)
- **可选依赖**: Halcon (用于QR码识别在Flag 4中使用)
- **构建流程**: 标准CMake流程支持Release/Debug配置
---
*文档更新时间: 2025-01-06*

View File

@@ -1,12 +1,13 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
# 支持 MSVC # 支持 MSVC
# 注意:配置 CMake 时请选择合适的生成器(例如 "Visual Studio 17 2022" # 注意:配置 CMake 时请选择合适的生成器(例如 "Visual Studio 17 2022" 或 "Ninja"
project(image_capture LANGUAGES CXX) project(image_capture LANGUAGES CXX)
if(NOT MSVC) # 检查是否使用 MSVC 风格的编译器
message(FATAL_ERROR "This project requires MSVC (Visual Studio) compiler. Please use a Visual Studio generator (e.g., -G \"Visual Studio 17 2022\").") if(NOT (MSVC OR CMAKE_CXX_COMPILER_ID STREQUAL "MSVC"))
message(FATAL_ERROR "This project requires MSVC (Visual Studio) compiler. Please use Ninja with MSVC or Visual Studio generator.")
endif() endif()
# ============================================================================ # ============================================================================
@@ -106,7 +107,10 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/third_party/mvs/Libraries/win64/MvCameraControl.lib ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mvs/Libraries/win64/MvCameraControl.lib
) )
target_link_directories(${PROJECT_NAME} PRIVATE ${OpenCV_LIB_DIRS}) target_link_directories(${PROJECT_NAME} PRIVATE
${OpenCV_LIB_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/third_party/percipio/lib/win/x64
)
if(Open3D_RUNTIME_DLLS) if(Open3D_RUNTIME_DLLS)
foreach(DLL_FILE ${Open3D_RUNTIME_DLLS}) foreach(DLL_FILE ${Open3D_RUNTIME_DLLS})

View File

@@ -2,7 +2,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <opencv2/core.hpp> #include <opencv2/opencv.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
#include "../../../common_types.h" #include "../../../common_types.h"