Dalsa 相机拍摄图像丢帧(模糊)解决办法

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:24   1860   0

Dalsa相机图像丢帧可能存在的原因

1、硬件原因

(1)硬件主要涉及网线和网卡的选择,Dalsa相机最好选择千兆网线千兆网卡。若一台PC需要连接多个相机,最好添加对应个数的网卡;

(2)网卡配置:对应网卡需要进行配置,配置方法如下所示:

①打开“网络连接”,选择对应网卡,右键选择“属性”;

②选择“配置”

③选择“高级”,配置“巨帧数据包”,选择最大(9014字节);“速度和双工”,选择最大(1.0 Gbps全双工)。

至此,和硬件相关的配置已经结束,如果能解决图像丢帧的问题,即可忽略第二步。若还没有解决,可能还与软件(代码)有关,代码主要在于抓图方式和取图方式。

2、软件原因

本人使用的是官方MFC-SDK,需要实现的功能为:当收到触发信号时,获取相机当前帧图像,并对该图像进行图像处理操作。最开始使用的方法为,开启软件后,持续获取流数据,即调用Grab()函数开始抓图,当收到触发信号时,直接从缓冲区(m_Buffers)中取数据转换为Mat图像,然后进行后续处理,结果发现,此方法会存在丢帧的情况。

后通过查看相机文档及相关资料得知,当相机得到一帧完整数据时,会自动调用回调函数(XferCallback),回调函数结束时,说明获取了一张完整的图像,故选用单张抓图Snap()+回调函数内获取图像的方式,最终解决了图像丢帧的问题。

主要代码部分展示:

头文件主要变量及函数定义:

CImageExWnd m_ImageWnd;
SapAcqDevice *m_AcqDevice;
SapBuffer  *m_Buffers;
SapTransfer  *m_Xfer;
SapView        *m_View;
static void XferCallback(SapXferCallbackInfo *pInfo);

初始化OnInitDialog()函数部分代码:

 //OnInitDialog()函数中
        //Select acquisition server from dialog
 //Only the servers that support "AcqDevice" resource are listed
 CAcqConfigDlg dlg(this, CAcqConfigDlg::ServerAcqDevice);
 if (dlg.DoModal() != IDOK)
 {
  MessageBox(_T("未发现或选中相机"), _T("错误"), MB_ICONHAND);
  EndDialog(TRUE);
  return FALSE;
 }

 // Define objects(important!)
 m_AcqDevice = new SapAcqDevice(dlg.GetLocation(), dlg.GetConfigFile());
 m_Buffers = new SapBufferWithTrash(1, m_AcqDevice); //1个垃圾缓冲区,如果获取多帧图像,为防止丢帧最好设置至少2个以上的缓冲区,因为此处使用单张抓图,所以1个缓冲区即可。
 m_Xfer = new SapAcqDeviceToBuf(m_AcqDevice, m_Buffers, XferCallback, this);
 m_View = new SapView(m_Buffers);

  Attach sapview to image viewer
 m_ImageWnd.AttachSapView(m_View);

 // Create all objects
 if (!CreateObjects()) { EndDialog(TRUE); return FALSE; }

 m_ImageWnd.AttachEventHandler(this);
 m_ImageWnd.CenterImage();
 m_ImageWnd.Reset();

回调XferCallback()函数:

void CGigeCameraDemoDlg::XferCallback(SapXferCallbackInfo *pInfo)
{
 CGigeCameraDemoDlg *pDlg = (CGigeCameraDemoDlg *)pInfo->GetContext();

 int staticCount = 0;
 BYTE pData;
 void* pDataAddr = &pData;
 pDlg->m_Buffers->GetAddress(staticCount, &pDataAddr);
 int width = pDlg->m_Buffers->GetWidth();
 int height = pDlg->m_Buffers->GetHeight();
 Mat img = Mat::zeros(cv::Size(width, height), CV_8U);
 memcpy(img.data, pDataAddr, width*height);
 img.copyTo(global_source_image);  //global_source_image为全局Mat

 callback_flag = true;  //自定义全局变量
}

某函数中抓取图像:

//m_Xfer->Snap()即为单张抓图,此处选用单张抓图
//m_Xfer->Grab()即为获取视频流,持续抓图
if (m_Xfer->Snap())
{
    UpdateMenu(); //更新按钮状态
}

//当callback_flag为true时,可以使用图像
while(callback_flag == true)
{
    //使用global_source_image进行一系列图像操作
    //操作结束退出循环,并将callback_flag置为false.
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP