# Lx相机服务使用说明 ## 概述 本系统提供了完整的Lx相机服务管理方案,包括: - **LxCameraService**: 统一的相机操作接口 - **LxCameraServiceImpl**: 服务实现类 - **CaptureConfig**: 拍照配置类 - **CaptureResult**: 拍照结果类 - **ImageCropper**: 图像裁剪服务 ## 文件保存路径格式 所有保存的文件按照以下格式组织: ``` basePath/ ├── 20250325/ # 日期文件夹(yyyyMMdd) │ ├── amplitude/ # 强度图 │ │ ├── 192.168.1.100_amplitude_20250325_143022.png │ │ └── 192.168.1.101_amplitude_20250325_143023.png │ ├── rgb/ # RGB图 │ │ ├── 192.168.1.100_rgb_20250325_143022.png │ │ └── 192.168.1.101_rgb_20250325_143023.png │ ├── depth/ # 深度图 │ │ ├── 192.168.1.100_depth_20250325_143022.png │ │ └── 192.168.1.101_depth_20250325_143023.png │ ├── depthColor/ # 彩色深度图 │ │ ├── 192.168.1.100_depth_color_20250325_143022.png │ │ └── 192.168.1.101_depth_color_20250325_143023.png │ └── pointCloud/ # 点云 │ ├── 192.168.1.100_pointcloud_20250325_143022.pcd │ └── 192.168.1.101_pointcloud_20250325_143023.pcd ├── 20250326/ │ └── ... └── 20250327/ └── ... ``` **路径格式说明:** ``` basePath/日期/类型/SN_类型_时间戳.扩展名 ``` - **basePath**: 基础保存路径(如 `D:/output`) - **日期**: 格式为 `yyyyMMdd`(如 `20250325`) - **类型**: 文件类型(`amplitude`、`rgb`、`depth`、`depthColor`、`pointCloud`) - **SN**: 相机序列号(如 `192.168.1.100`) - **类型**: 重复文件类型(与类型文件夹一致) - **时间戳**: 格式为 `yyyyMMdd_HHmmss`(如 `20250325_143022`) - **扩展名**: 文件扩展名(`.png` 或 `.pcd`) **示例:** ``` D:/output/20250325/pointcloud/192.168.1.100_pointcloud_20250325_143022.pcd ``` 这种组织方式的优点: 1. **按日期分类**:便于按天管理和查找 2. **按类型分类**:便于按类型批量处理 3. **时间戳唯一**:确保文件名不会重复 4. **结构清晰**:一目了然 ## 初始化 ### 自动初始化 系统会在启动时自动初始化所有配置的Lx相机: ```yaml # application.yml app: lxCamera: - ip: "192.168.1.100" id: 1 savePath: "D:/output/camera1" - ip: "192.168.1.101" id: 2 savePath: "D:/output/camera2" ``` ### 手动初始化 如果需要手动初始化: ```java @Autowired private LxCameraService lxCameraService; // 手动初始化 lxCameraService.initCameras(); ``` ## 基本使用 ### 1. 拍照(默认配置) 只拍照点云数据: ```java @Autowired private LxCameraService lxCameraService; // 拍照并保存 CaptureResult result = lxCameraService.capture("192.168.1.100", "D:/output"); if (result.isSuccess()) { System.out.println("拍照成功!"); System.out.println("重试次数: " + result.getActualRetryCount()); System.out.println("文件路径: " + result.getFilePaths()); } else { System.out.println("拍照失败: " + result.getErrorDescription()); } ``` ### 2. 拍照(自定义配置) 拍摄多种类型图片: ```java // 创建全类型拍照配置 CaptureConfig config = CaptureConfig.createFullCapture(); // 或自定义配置 CaptureConfig config = CaptureConfig.createCustomConfig( true, // 强度图 true, // RGB图 true, // 深度图 true, // 彩色深度图 true // 点云 ); // 设置重试参数 config.setMaxConnectRetries(3); // 最大连接重试次数 config.setMaxCaptureRetries(3); // 最大拍照重试次数 config.setRetryInterval(500); // 重试间隔(毫秒) // 设置深度图参数 config.setMaxDepthValue(1000.0); // 最大深度值(毫米) config.setColormapType(0); // 颜色映射类型(0=JET, 1=RAINBOW, 2=HOT, 3=OCEAN, 4=PARULA) // 拍照 CaptureResult result = lxCameraService.capture("192.168.1.100", "D:/output", config); // 获取各类型图片路径 String pointCloudPath = result.getFilePath("pointCloud"); String rgbPath = result.getFilePath("rgb"); String depthPath = result.getFilePath("depth"); // ... ``` ### 3. 重连相机 ```java boolean success = lxCameraService.reconnect("192.168.1.100"); if (success) { System.out.println("重连成功"); } else { System.out.println("重连失败"); } ``` ### 4. 检查连接状态 ```java boolean connected = lxCameraService.isConnected("192.168.1.100"); System.out.println("相机连接状态: " + (connected ? "已连接" : "未连接")); ``` ### 5. 关闭相机 ```java // 关闭指定相机 lxCameraService.closeCamera("192.168.1.100"); // 关闭所有相机 lxCameraService.closeAllCameras(); ``` ## 图像裁剪 ### 基本裁剪 ```java @Autowired private ImageCropper imageCropper; // 裁剪单个BMP图像 boolean success = imageCropper.cropBmpImage( "D:/input/image.bmp", "D:/output/image_cropped.bmp" ); // 裁剪任意格式图像(使用OpenCV) boolean success = imageCropper.cropImage( "D:/input/image.png", "D:/output/image_cropped.png" ); ``` ### 批量裁剪 ```java // 裁剪文件夹中所有BMP图像 imageCropper.cropAllBmpImagesInFolder( "D:/input", "D:/output" ); // 裁剪文件夹中指定格式的图像 imageCropper.cropImagesInFolder( "D:/input", "D:/output", "png" // 文件扩展名 ); ``` ### 自定义裁剪区域 ```java import org.opencv.core.Rect; // 自定义裁剪区域 Rect cropRect = new Rect(100, 100, 800, 800); boolean success = imageCropper.cropImageWithOpenCV( "D:/input/image.jpg", "D:/output/image_cropped.jpg", cropRect ); ``` ## HTTP API接口 ### 1. 拍照(默认配置) ```http POST /api/lxcamera/capture?cameraSn=192.168.1.100&basePath=D:/output ``` **响应示例:** ```json { "success": true, "errorCode": 0, "errorMessage": null, "errorDescription": "成功", "retryCount": 1, "cameraSn": "192.168.1.100", "filePaths": { "pointCloud": "D:/output/20250325/pointCloud/192.168.1.100_pointcloud_20250325_143022.pcd" } } ``` ### 2. 拍照(自定义配置) ```http POST /api/lxcamera/capture/config Content-Type: application/json { "cameraSn": "192.168.1.100", "basePath": "D:/output", "config": { "captureAmplitude": true, "captureRgb": true, "captureDepth": true, "captureDepthColor": true, "capturePointCloud": true, "maxConnectRetries": 3, "maxCaptureRetries": 3, "retryInterval": 500, "maxDepthValue": 1000.0, "colormapType": 0 } } ``` **响应示例:** ```json { "success": true, "errorCode": 0, "errorMessage": null, "errorDescription": "成功", "retryCount": 1, "cameraSn": "192.168.1.100", "filePaths": { "amplitude": "D:/output/20250325/amplitude/192.168.1.100_amplitude_20250325_143022.png", "rgb": "D:/output/20250325/rgb/192.168.1.100_rgb_20250325_143022.png", "depth": "D:/output/20250325/depth/192.168.1.100_depth_20250325_143022.png", "depthColor": "D:/output/20250325/depthColor/192.168.1.100_depth_color_20250325_143022.png", "pointCloud": "D:/output/20250325/pointCloud/192.168.1.100_pointcloud_20250325_143022.pcd" } } ``` ### 3. 重连相机 ```http POST /api/lxcamera/reconnect?cameraSn=192.168.1.100 ``` **响应示例:** ```json { "success": true, "cameraSn": "192.168.1.100", "message": "重连成功" } ``` ### 4. 查询相机状态 ```http GET /api/lxcamera/status?cameraSn=192.168.1.100 ``` **响应示例:** ```json { "cameraSn": "192.168.1.100", "connected": true, "status": "已连接" } ``` ### 5. 关闭相机 ```http POST /api/lxcamera/close?cameraSn=192.168.1.100 ``` **响应示例:** ```json { "success": true, "cameraSn": "192.168.1.100", "message": "关闭成功" } ``` ### 6. 关闭所有相机 ```http POST /api/lxcamera/closeAll ``` **响应示例:** ```json { "success": true, "message": "所有相机已关闭" } ``` ## 错误码说明 | 错误码 | 说明 | 处理建议 | |--------|------|----------| | 0 | 成功 | 无需处理 | | -1 | 保存失败 | 检查磁盘空间和权限 | | -2 | 目录创建失败 | 检查路径和权限 | | -3 | 句柄获取失败 | 检查相机连接,尝试重连 | | -4 | 连接失败 | 检查网络和相机状态 | | -5 | 其他错误 | 查看日志详情 | ## 架构说明 ### DLL管理 系统采用"一个DLL对应一个DcLibrary"的策略: ``` libs/plc/ ├── LxCameraApi.dll # 原始DLL ├── LxCameraApi-1.dll # 相机1专用DLL ├── LxCameraApi-2.dll # 相机2专用DLL └── ... ``` 这样可以避免多个相机共享同一个DLL可能产生的冲突。 ### 设备句柄管理 每个相机有独立的设备句柄,存储在 `handleMap` 中: ```java Map handleMap; ``` ### 重试机制 1. **连接重试**:默认最多3次,间隔500ms 2. **拍照重试**:默认最多3次,间隔500ms 3. **自动重连**:拍照失败时自动尝试重连相机 ## 性能优化建议 1. **批量操作**:一次处理多个相机时,使用并行处理 2. **合理重试**:根据网络状况调整重试次数和间隔 3. **及时释放**:使用完毕后及时关闭相机连接 4. **异常处理**:捕获并记录异常信息,便于排查问题 ## 示例代码 ### 完整的拍照流程 ```java @Service public class CameraCaptureService { @Autowired private LxCameraService lxCameraService; @Autowired private ImageCropper imageCropper; public void captureAndProcess(String cameraSn, String basePath) { // 1. 检查连接 if (!lxCameraService.isConnected(cameraSn)) { log.warn("相机未连接,尝试重连"); lxCameraService.reconnect(cameraSn); } // 2. 创建拍照配置 CaptureConfig config = CaptureConfig.createFullCapture(); config.setMaxCaptureRetries(3); // 3. 拍照 CaptureResult result = lxCameraService.capture(cameraSn, basePath, config); if (result.isSuccess()) { log.info("拍照成功,共 {} 张图片", result.getFilePaths().size()); // 4. 裁剪RGB图像 String rgbPath = result.getFilePath("rgb"); if (rgbPath != null) { String croppedPath = basePath + "/cropped_" + new File(rgbPath).getName(); imageCropper.cropImage(rgbPath, croppedPath); log.info("图像裁剪完成: {}", croppedPath); } } else { log.error("拍照失败: {}", result.getErrorDescription()); } } } ``` ## 注意事项 1. **路径格式**:Windows路径使用正斜杠 `/` 或双反斜杠 `\\` 2. **权限问题**:确保程序有读写指定路径的权限 3. **相机配置**:确保每个相机的IP、ID等信息配置正确 4. **网络稳定**:相机与服务器之间的网络连接需要稳定 5. **磁盘空间**:确保有足够的磁盘空间保存图片 6. **OpenCV初始化**:确保OpenCV库已正确加载 ## 兼容性说明 本系统保留了 `LxPointCloudSaveImage` 类以保持向后兼容性,但建议使用新的 `LxCameraService` 接口。 旧的API仍然可以继续使用: ```java // 旧API(仍然支持) LxPointCloudSaveImage.saveImage("192.168.1.100", "D:/output/test.pcd"); // 新API(推荐) CaptureResult result = lxCameraService.capture("192.168.1.100", "D:/output"); ``` ## 技术支持 如有问题,请查看: 1. 日志文件:`logs/camera.log` 2. 控制台输出 3. API响应的错误信息