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

如何编程实现Allied Vision GigE相机断连重连后自动恢复图像采集?

解决方案:GigE相机断连重连后恢复Vimba采集的实现建议

核心问题分析

断连后原CameraPtr已处于无效状态,直接调用采集启停接口会因相机内部资源未清理、状态异常报错。需在回调中彻底清理旧资源,重新初始化相机并恢复采集流程。

具体实现步骤

1. 线程安全的全局状态管理

用互斥锁保护相机指针和采集状态,避免SDK回调线程与主线程并发操作冲突:

#include <mutex>
#include <memory>
#include <AVT/VmbAPI/VmbAPI.h>

std::mutex g_cameraMutex;
AVT::VmbAPI::CameraPtr g_activeCamera;
AVT::VmbAPI::FrameObserverPtr g_frameObserver; // 若使用帧观察者模式

2. 完善CameraListObserver回调逻辑

在回调中区分相机移除/添加事件,分别执行资源清理和重连初始化:

class CameraListObserver : public AVT::VmbAPI::ICameraListObserver
{
public:
    void CameraListChanged(
        AVT::VmbAPI::CameraPtr pCam,
        AVT::VmbAPI::UpdateTriggerType reason
    ) override
    {
        std::lock_guard<std::mutex> lock(g_cameraMutex);
        std::string camID;
        pCam->GetID(camID);

        if (reason == AVT::VmbAPI::TriggerTypeRemoved)
        {
            // 断连时强制清理所有资源
            if (g_activeCamera)
            {
                // 尝试停止采集(即使失败也要执行后续步骤)
                VmbErrorType err = g_activeCamera->StopContinuousImageAcquisition();
                if (err != VmbErrorSuccess)
                {
                    printf("[WARN] Stop acquisition failed on disconnect: %d\n", err);
                }
                // 关闭相机
                err = g_activeCamera->Close();
                if (err != VmbErrorSuccess)
                {
                    printf("[WARN] Close camera failed on disconnect: %d\n", err);
                }
                // 释放指针
                g_activeCamera.reset();
                g_frameObserver.reset();
            }
            printf("[INFO] Camera %s disconnected\n", camID.c_str());
        }
        else if (reason == AVT::VmbAPI::TriggerTypeAdded)
        {
            printf("[INFO] Camera %s reconnected\n", camID.c_str());
            // 重新获取有效相机实例
            AVT::VmbAPI::CameraPtr newCam;
            VmbErrorType err = AVT::VmbAPI::VimbaSystem::GetInstance()->GetCameraByID(camID.c_str(), newCam);
            if (err != VmbErrorSuccess)
            {
                printf("[ERROR] Failed to get camera by ID: %d\n", err);
                return;
            }
            // 以全权限打开相机
            err = newCam->Open(VmbAccessModeFull);
            if (err != VmbErrorSuccess)
            {
                printf("[ERROR] Failed to open camera: %d\n", err);
                return;
            }
            // 重置采集参数(断连后相机参数会恢复默认)
            err = newCam->SetFeatureValue("ExposureTime", 10000.0); // 示例:设置曝光时间
            if (err != VmbErrorSuccess)
            {
                printf("[WARN] Failed to set ExposureTime: %d\n", err);
            }
            err = newCam->SetFeatureValue("PixelFormat", VmbPixelFormatMono8); // 示例:设置像素格式
            if (err != VmbErrorSuccess)
            {
                printf("[WARN] Failed to set PixelFormat: %d\n", err);
            }
            // 重新创建帧观察者(若使用该模式)
            g_frameObserver = std::make_shared<MyFrameObserver>(newCam); // 替换为你的自定义FrameObserver
            if (!g_frameObserver)
            {
                printf("[ERROR] Failed to create FrameObserver\n");
                newCam->Close();
                return;
            }
            // 启动连续采集
            err = newCam->StartContinuousImageAcquisition(3, g_frameObserver); // 3为缓存帧数量
            if (err != VmbErrorSuccess)
            {
                printf("[ERROR] Failed to start acquisition: %d\n", err);
                newCam->Close();
                g_frameObserver.reset();
                return;
            }
            // 更新全局有效相机指针
            g_activeCamera = newCam;
            printf("[INFO] Camera %s resumed acquisition\n", camID.c_str());
        }
    }
};

3. 初始化时注册观察者

确保在Vimba系统初始化后注册相机列表观察者:

int main()
{
    VmbErrorType err = AVT::VmbAPI::VimbaSystem::GetInstance()->StartUp();
    if (err != VmbErrorSuccess)
    {
        printf("Failed to start Vimba system\n");
        return -1;
    }
    // 注册相机列表观察者
    std::shared_ptr<CameraListObserver> camObserver = std::make_shared<CameraListObserver>();
    err = AVT::VmbAPI::VimbaSystem::GetInstance()->RegisterCameraListObserver(camObserver);
    if (err != VmbErrorSuccess)
    {
        printf("Failed to register camera observer\n");
        AVT::VmbAPI::VimbaSystem::GetInstance()->ShutDown();
        return -1;
    }
    // 其他初始化逻辑...
}

关键注意事项

  • 断连后必须释放旧CameraPtr,避免无效对象占用资源
  • 重连后需完全复刻首次启动的初始化流程(打开相机、设置参数、注册观察者、启动采集)
  • 所有相机操作必须加互斥锁,防止多线程冲突
  • 可根据Vimba SDK错误码表(SDK文档内)排查具体报错原因

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:15:53