You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lxCameraApi/LX_CAMERA_USAGE.md

481 lines
12 KiB
Markdown

2 weeks ago
# 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<String, DeviceInfo> 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响应的错误信息