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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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响应的错误信息