You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Teledyne Dalsa线扫相机高行频下Harvesters(GenICam)触发异常

Teledyne Dalsa线扫相机高行率下Arduino触发图像捕获不稳定问题

我使用Teledyne Dalsa线扫描相机,当行率提升至13000或更高时,通过Arduino以3V3电平触发,无法像行率10000及以下那样每次触发都稳定从缓冲区捕获图像。但在Sapera软件中,高行率下触发功能运行正常,即使照搬Sapera的所有参数配置,仍有部分触发无法返回图像。

附上当前使用的代码:

import platform
import os
import sys
import time
from harvesters.core import Harvester
import cv2
import numpy as np

h = Harvester()

gentl_file = r"C:\Program Files\MATRIX VISION\mvIMPACT Acquire\bin\x64\mvGenTLProducer.cti"

h.add_file(gentl_file)
h.update()

ia = h.create(0)
ia.remote_device.node_map.Width.value = 2048
ia.remote_device.node_map.Height.value = 2000
ia.remote_device.node_map.PixelFormat.value = 'RGB8'
ia.remote_device.node_map.AcquisitionLineRate.set_value(15000)
ia.remote_device.node_map.ExposureTime.set_value(47)
ia.remote_device.node_map.Gain.set_value(6)
ia.remote_device.node_map.TriggerSelector.value = "FrameBurstStart"
ia.remote_device.node_map.TriggerMode.value = "On"
ia.remote_device.node_map.triggerFrameCount.set_value(1) # new
ia.remote_device.node_map.TriggerSource.value = "Line2"
ia.remote_device.node_map.TriggerActivation.value = "RisingEdge"
ia.remote_device.node_map.TriggerDelay.set_value(0.0) # new
ia.remote_device.node_map.triggerDelaySource.value = "lineTriggerSignal" # new

ia.remote_device.node_map.LineSelector.value = "Line2"
ia.remote_device.node_map.LineFormat.value = "SingleEnded"

ia.remote_device.node_map.lineDetectionLevel.value = "Threshold_for_3V3"
ia.remote_device.node_map.LineInverter.value = False 
ia.remote_device.node_map.lineDebouncingPeriod.value = 0
ia.remote_device.node_map.lineElectricalTermination.value = "Disabled"

ia.start()

start = time.time()

ia.start()

def image_capture():
    global ia
    print('Image capture started')
    lst_app = []
    with ia.fetch() as buffer:
        component = buffer.payload.components[0]
        _2d_new = component.data.reshape(component.height,component.width,int(component.num_components_per_pixel))
        _2d_new = cv2.cvtColor(_2d_new , cv2.COLOR_RGB2BGR)
        lst_app.append(_2d_new)

    if len(lst_app) == 1:
        print('Buffer is full')
        arr = np.vstack(lst_app)
        lst_app = []

        return np.array(arr)

count = 0
while True:
    image = image_capture()
    print('captured', count)
    count += 1

可能的原因及解决方案

1. 修复重复启动相机的错误

代码中连续调用了两次ia.start(),会导致相机内部状态异常,直接删除第二次调用即可。

2. 增加缓冲区数量适配高行率

高行率下单帧数据量达~12MB(2048×2000×3字节),默认缓冲区数量可能不足以应对连续触发,导致丢帧:

# 在第一次ia.start()前添加缓冲区配置
ia.remote_device.node_map.BufferCount.value = 8  # 可根据实际情况调整为8-16个

3. 优化触发信号稳定性

Arduino的3V3触发信号可能存在抖动或脉冲宽度不足,高行率下相机对时序精度要求更高:

  • 在Arduino端增加触发脉冲宽度(至少10µs):
    digitalWrite(triggerPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(triggerPin, LOW);
    
  • 调整相机防抖参数,过滤信号噪声:
    ia.remote_device.node_map.lineDebouncingPeriod.value = 2  # 设置为2µs
    

4. 分离捕获与处理逻辑避免阻塞

当前代码中图像捕获和格式转换在同一线程执行,高行率下处理耗时会错过触发信号,改用多线程分离:

import threading
from queue import Queue

image_queue = Queue(maxsize=4)

def capture_worker():
    while True:
        with ia.fetch() as buffer:
            component = buffer.payload.components[0]
            raw_data = component.data.reshape(
                component.height, 
                component.width, 
                int(component.num_components_per_pixel)
            )
            image_queue.put(raw_data)

# 启动后台捕获线程
threading.Thread(target=capture_worker, daemon=True).start()

# 主线程单独处理图像格式转换
count = 0
while True:
    if not image_queue.empty():
        raw_img = image_queue.get()
        bgr_img = cv2.cvtColor(raw_img, cv2.COLOR_RGB2BGR)
        print('captured', count)
        count += 1

5. 确认触发模式参数匹配Sapera

检查相机采集模式是否与Sapera一致,部分场景下FrameBurstStart触发需配合多帧模式:

ia.remote_device.node_map.AcquisitionMode.value = "MultiFrame"

内容的提问来源于stack exchange,提问作者John son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:46:14