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

12 KiB

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
  • 类型: 文件类型(amplitudergbdepthdepthColorpointCloud
  • 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相机

# 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"

手动初始化

如果需要手动初始化:

@Autowired
private LxCameraService lxCameraService;

// 手动初始化
lxCameraService.initCameras();

基本使用

1. 拍照(默认配置)

只拍照点云数据:

@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. 拍照(自定义配置)

拍摄多种类型图片:

// 创建全类型拍照配置
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. 重连相机

boolean success = lxCameraService.reconnect("192.168.1.100");
if (success) {
    System.out.println("重连成功");
} else {
    System.out.println("重连失败");
}

4. 检查连接状态

boolean connected = lxCameraService.isConnected("192.168.1.100");
System.out.println("相机连接状态: " + (connected ? "已连接" : "未连接"));

5. 关闭相机

// 关闭指定相机
lxCameraService.closeCamera("192.168.1.100");

// 关闭所有相机
lxCameraService.closeAllCameras();

图像裁剪

基本裁剪

@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"
);

批量裁剪

// 裁剪文件夹中所有BMP图像
imageCropper.cropAllBmpImagesInFolder(
    "D:/input",
    "D:/output"
);

// 裁剪文件夹中指定格式的图像
imageCropper.cropImagesInFolder(
    "D:/input",
    "D:/output",
    "png"  // 文件扩展名
);

自定义裁剪区域

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. 拍照(默认配置)

POST /api/lxcamera/capture?cameraSn=192.168.1.100&basePath=D:/output

响应示例:

{
  "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. 拍照(自定义配置)

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
  }
}

响应示例:

{
  "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. 重连相机

POST /api/lxcamera/reconnect?cameraSn=192.168.1.100

响应示例:

{
  "success": true,
  "cameraSn": "192.168.1.100",
  "message": "重连成功"
}

4. 查询相机状态

GET /api/lxcamera/status?cameraSn=192.168.1.100

响应示例:

{
  "cameraSn": "192.168.1.100",
  "connected": true,
  "status": "已连接"
}

5. 关闭相机

POST /api/lxcamera/close?cameraSn=192.168.1.100

响应示例:

{
  "success": true,
  "cameraSn": "192.168.1.100",
  "message": "关闭成功"
}

6. 关闭所有相机

POST /api/lxcamera/closeAll

响应示例:

{
  "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 中:

Map<String, DeviceInfo> handleMap;

重试机制

  1. 连接重试默认最多3次间隔500ms
  2. 拍照重试默认最多3次间隔500ms
  3. 自动重连:拍照失败时自动尝试重连相机

性能优化建议

  1. 批量操作:一次处理多个相机时,使用并行处理
  2. 合理重试:根据网络状况调整重试次数和间隔
  3. 及时释放:使用完毕后及时关闭相机连接
  4. 异常处理:捕获并记录异常信息,便于排查问题

示例代码

完整的拍照流程

@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仍然可以继续使用

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