软件与系统集成

稳定的相机采集:缓冲区、超时与重连

采集循环看似一直在返回有效帧,却可能在重连后泄漏缓冲区,或复用旧图像。请在实际使用的 SDK 中确认缓冲区的生命周期和设备移除事件。下方附录是与厂商无关的伪代码,不是可执行的 SDK 调用,也不构成对 Deyi 能力的声明。

发送样品,申请工程评审
稳定的相机采集:缓冲区、超时与重连
工程说明用示意图,不是实物照片,也不代表已完成测试。

问题与前置条件

采集循环看似一直在返回有效帧,却可能在重连后泄漏缓冲区,或复用旧图像。请在实际使用的 SDK 中确认缓冲区的生命周期和设备移除事件。下方附录是与厂商无关的伪代码,不是可执行的 SDK 调用,也不构成对 Deyi 能力的声明。

准备测试

假设图像为 2000 × 1500 的 Mono8:每幅 3 MB,因此 8 个原始缓冲区在计入元数据和处理副本之前就占用 24 MB。固定设备标识,并在每次重连后定义新的采集代次(generation)。

设计工作线程循环之前,先阅读所选 SDK 中有关采集和生命周期的文档。弄清谁分配缓冲区、谁拥有采集结果、缓冲区何时归还给驱动,以及归还之后保留的引用是否仍然有效。确认文档中记载的设备移除通知,以及该通知在哪个线程上触发。如果 SDK 禁止在通知回调中阻塞,就把状态变更和关闭协调放到回调之外处理。设备标识应取自文档记载的稳定标识符,而不是枚举之后找到的第一台设备。把图像尺寸、像素格式、载荷大小、触发模式和传输配置记为验收通过的采集参数集。下文各个概念性操作名称,都不代表 Deyi 提供相应的 SDK 接口。

操作步骤

  1. 先配置图像尺寸和像素格式,再按 SDK 报告的载荷大小分配缓冲区。
  2. 采集时设置有限的超时时间;区分未收到触发、传输失败和设备被移除三种情况。
  3. 按文档规定的所有权规则复制或持有图像,然后再释放采集结果。
  4. 设备被移除时,停止工作线程,归还尚未归还的缓冲区,并丢弃旧代次的待处理结果。
  5. 只重连预期的那台设备,重新应用并核实配置,然后以新的代次标识符恢复运行。
VENDOR-NEUTRAL PSEUDOCODE — conceptual operations, not SDK API names
connect(expected_device_identity)
verify_configuration_and_payload()
generation = new_generation()
while connected:
    result = none
    owned_image = none
    try:
        result = acquire_with_deadline()
        if result.is_valid:
            owned_image = copy_or_retain_under_documented_rules(result)
            process(owned_image, generation)
        else:
            record_acquisition_fault(result, generation)
    finally:
        release_owned_image_if_present(owned_image)
        release_grab_result_if_present(result)
on_coordinator_receives_device_removed:
    invalidate_current_generation()
    stop_and_join_workers()
    return_all_buffers()
    discard_old_generation_results()
    reconnect_expected_device_and_verify_configuration()
    generation = new_generation()

采集时设定有限的超时时间,并在访问图像数据之前先检查采集结果。超时可能只是外部触发没有到来;传输故障或设备被移除则需要走另一条恢复路径。把每个有效帧交给处理环节之前,先将它与采集代次以及帧或事件标识关联起来。可以复制到应用自己管理的存储,也可以按 SDK 文档规定的规则保留所有权。无论哪种做法,处理过程抛出异常时和正常完成时一样,都要释放资源。为处理队列设定上限,并明确队列满了之后怎么办。内存悄悄越涨越大,不能算作有效的背压策略;拿最近一帧去充当新请求的图像,也不能替代缺失的图像。

测试记录示例

以下为示例性假设,并非 Deyi 的实测性能。请将这些数值替换为你自己经签字确认的测试记录。

测试记录示例
记录项假设值
队列容量8
未压缩图像数据量3 MB
存储容量24 MB
样本数1000

在保持已配置采集速率的同时,人为让消费端变慢。记录采集代次、帧标识符、队列深度、存活缓冲区数量和超时原因。如果图像被复制,24 MB 的计算结果不包含这些副本;如果保留的是引用,SDK 必须允许这些引用在相应的时间内保持有效。finally 块同样示范了处理过程抛出异常时的释放。重连之后,注入一个延迟到达的旧代次结果,确认它不会变成当前的检测结果。

设备被移除时,停止接收受影响代次的新任务,并先协调好工作线程的终止,再释放它们可能仍在访问的资源。按 SDK 的约定取消或完成尚未完成的操作,归还缓冲区,并丢弃未被消费的旧代次结果。重连预期的设备,并核实已验收的配置,不要想当然地认为默认值与上一次会话一致。分配新缓冲区之前,先回读载荷信息。新会话准备就绪之后,才创建新的代次。来自旧会话的迟到回调或排队中的结果,即使帧号与当前帧相似,也必须被代次检查拒绝。示例中的原始缓冲区算式只是内存消耗的一个组成部分;应把副本、队列和算法工作空间也纳入按实测得出的预算。

流程的两种视图

稳定的相机采集:缓冲区、超时与重连 — 1

所有权从采集环节转到处理环节,只有在消费端不再需要这些数据之后才归还。

  1. 采集
  2. 持有或复制
  3. 处理
  4. 释放
工程说明用示意图,不是实物照片,也不代表已完成测试。
查看原尺寸示意图

稳定的相机采集:缓冲区、超时与重连 — 2

超时、移除和有序关闭需要不同的状态转换;重连必须开启一个干净的新采集代次。

  1. 超时
  2. 移除
  3. 关闭
工程说明用示意图,不是实物照片,也不代表已完成测试。
查看原尺寸示意图

故障排查

  • 内存持续增长,说明存在未释放的采集结果,或消费端队列没有上限。
  • 图像损坏,提示缓冲区归还给驱动之后仍被使用。
  • 重连后反复出现旧图像时,需要检查队列和代次标识符,而不能只是重新打开设备。

验收与交接

运行示例中的 1000 帧试验,并加上设备移除、恢复和关闭这几种情况。确认内存有界、没有跨代次的结果,并且以明确的故障代替被复用的图像。再用慢速消费端重复一遍;原始缓冲区的算式并不是总内存预算。

测试前先设定验收限值,并保留原始证据。此处的示例并不能说明所供型号具备相应能力。

验收要把持续采集、人为中断和慢速消费端场景结合起来。对每个计划内的请求,都记录存活缓冲区、队列深度、进程内存、代次转换和终止原因。按受控流程移除并恢复设备,然后在采集尚未完成时停止应用程序。确认关闭流程能够完成,没有任何工作线程访问已释放的内存,也没有旧图像变成新的检测结果。测试处理过程中的异常,以走通 finally 路径。放行前,把最终的设备标识和配置与验收记录比对。示例中的 1000 帧运行只提供功能覆盖,不能保证长期无泄漏或长期可靠。交接材料应包含实际使用的 SDK 版本、所有权决定、队列策略、重连顺序和故障证据,其中可执行的厂商专用代码要对照其自身文档审查。

来源与技术参考资料

这些资料说明了本教程所用方法的依据与适用范围。文中的检查示例仅供参考;量产验收需要用你自己的样品取得证据。

  1. Programming with pylon CBasler核查于
  2. pylon .NET SamplesBasler核查于

工程评审

把检测问题和证据一起发过来。

请发送样品图像、当前方案,以及未通过的检查项;同时注明视野、工作距离、线速度和验收标准,便于做出切实可行的评审。

发送样品,申请工程评审
咨询

直接联系

把您的检测需求告诉工程师。

请提供样品图片、参考型号、视野、工作距离和线速度。

目标:24 小时内回复选型建议
发送样品图片