相机同步遇到的小问题

出现问题

在进行两个相机显示的时候,出现了相机显示不同步的情况,具体情况如下视频所示:

华睿/大华相机左右相机显示不同步

可以见到视频之中,右相机是比左相机更快一点的,但是有的时候就是同步的。我调用的代码是现成的,在原有的代码上进行了稍微的更改。

上面是根据现成的代码直接更改得到的,按道理而言,即便是出问题也应该是左相机显示比右相机快呀。所以决定再重新写一个显示代码。

解决思路

一.原始代码

原来的代码之中使用到了相应的SendMessage与ReceiveMessage函数,将原始的相机操作写成单独的一个.h与.cpp文件。看着代码有点儿迷糊,懒得使用这两个函数了,直接在写相应的主要的cpp函数之中进行写入。

查看技术手册,相机的操作流程为如下所示:

在进行配置好环境之后,发现设备到打开相机的操作如下代码所示:

IMV_HANDLE devHandle;unsigned int cameraIndex = 0;TCHAR errMsg[256];int ret = IMV_OK;// 发现设备 IMV_DeviceList deviceInfoList;ret = IMV_EnumDevices(&deviceInfoList, interfaceTypeAll);if (IMV_OK != ret){_stprintf_s(errMsg, _T("Enumeration devices failed! ErrorCode[%d]"), ret);throw errMsg;return FALSE;}if (deviceInfoList.nDevNum < 1){_stprintf_s(errMsg, _T("No Camera."));throw errMsg;return FALSE;}//左相机进行操作cameraIndex = 0;//假设左相机的参数为0// 创建设备句柄ret = IMV_CreateHandle(&devHandle, modeByIndex, (void*)&cameraIndex);if (IMV_OK != ret){_stprintf_s(errMsg, _T("Create devHandle failed! ErrorCode[%d]"), ret);throw errMsg;return FALSE;}// 打开相机 // Open camera ret = IMV_Open(devHandle);if (IMV_OK != ret){_stprintf_s(errMsg, _T("Open camera failed! ErrorCode[%d]"), ret);throw errMsg;return FALSE;}// 设置属性值 这个地方是需要结合后面的说明进行设定ret = IMV_SetDoubleFeatureValue(devHandle, "FrameRate", 10.00);if (exposureAuto_Left != 2){ret = IMV_SetEnumFeatureValue(devHandle, "ExposureAuto", exposureAuto_Left);ret = IMV_SetEnumFeatureValue(devHandle, "GainAuto", GainAuto_Left);ret = IMV_SetEnumFeatureValue(devHandle, "ContrastAuto", ContrastAuto_Left);ret = IMV_SetDoubleFeatureValue(devHandle, "ExposureTime", exposureTime_Left);ret = IMV_SetDoubleFeatureValue(devHandle, "Gamma", Gramma_L);if (IMV_OK != ret){printf("Set feature value failed! ErrorCode[%d]\n", ret);return ret;}}else{ret = IMV_SetEnumFeatureValue(devHandle, "GainAuto", 2);ret = IMV_SetEnumFeatureValue(devHandle, "ContrastAuto", 2);}ret = IMV_SetIntFeatureValue(devHandle, "Brightness", Brightness_L);

文档技术手册之中提到了相机参数的注册回调函数,其作用为当相机的曝光时间或增益发生变化时,应用程序可以通过注册回调函数来接收相机的通知,并相应地更新显示界面上的参数值或图像。

对比两个回调函数:

由于第二个函数是不支持多线程调用,因此选用第一个函数。

// 注册数据帧回调函数ret = IMV_AttachGrabbing(devHandle, onGetFrame, this);if (IMV_OK != ret){_stprintf_s(errMsg, _T("Attach grabbing failed! ErrorCode[%d]"), ret);throw errMsg;return FALSE;}// 开始拉流 // Start grabbing ret = IMV_StartGrabbing(devHandle);if (IMV_OK != ret){_stprintf_s(errMsg, _T("Start grabbing failed! ErrorCode[%d]"), ret);throw errMsg;return FALSE;}

一般而言,此时将显示的信息直接写到onGetFrame之中便是可以的,但是此处我是通过界面交互的方式。由于此处是将相应的采集信息通过一个线程发送出去,因此,需要将线程进行加入。

    try{LxhStartThread();}catch (TCHAR* errMsg){throw errMsg;return FALSE;}

二.问题猜想

想法一:和之前的倾角传感器的延迟解决方案一致,先启动线程再进行采集。发现并不是这里的问题。

onGetFrame函数之中将帧信息进行复制

static void onGetFrame(IMV_Frame* pFrame, void* pUser)
{if (pFrame == NULL){return;}CRGB_CameraCtrl *pThis = (CRGB_CameraCtrl2 *)pUser;// Save and call thread.FrameBuffer* pConvertFrameBuffer = new FrameBuffer(pThis->GetDevHandle(), *pFrame);memcpy_s(pThis->pRGB_bufPtr(), IMAGE_SIZE, pConvertFrameBuffer->bufPtr(), IMAGE_SIZE);//使用delete pConvertFrameBuffer;return;
}

开始写的代码是这顺序:注册回帧函数 -> 抓流 -> 启动线程。问题?是不是抓流和启动线程之间存在一定的时间延迟?

所以这里想的是在进行抓流之前便把线程启动起来,实时监控帧信息进行显示。

想法二:首先设置左右相机帧率一致,启动代码,发现仍然存在左右相机延迟的问题。

想法三:
①首先启动官方软件时,观察相机的各项指标。

可以观察到左、右相机的帧率都为10FPS,其中数据传输速率几乎一致。

左右相机同步。
②之后启动自己写的软件,观察情况。

可以观察到左右相机仍然同步。
③再次启动官方软件观察相机的各项指标。

可以发现到左相机明显出现速率变慢的情况。

④多次重复上述②③操作,发现左相机的帧率和传输速率下降的非常明显。按道理而言,在关闭自己写的软件,打开官方软件,采集速率应该是保持一致的。因此,猜想是自己写的软件并没有关闭成功。

查看后台:

果然发现软件仍然在后台进行运行。结束软件任务,重新打开官方软件,左、右相机的传输速率与帧率正常。

上述说明软件在使用过程之中,没有正常关闭软件,存在软件后台运行的问题,代码层次的原因,看一看代码方面是否存在线程未关闭的情况。

三.软件关闭

果然发现重载 主窗口类的 OnClose 函数之中缺少了一个线程的结束。完善代码,重新重复上述测试过程,不再出现掉帧的现象。

开始没往软件结束这个方向想,因为是左相机比右相机慢,想的方向直接偏到了帧率和线程方向是不是出了问题。最后,对比官方软件发现是软件关闭之后并未结束,导致左相机网口一直占用,从而左相机读出的数据比右相机慢很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/323368.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业级大数据安全架构(二)安全方案

作者&#xff1a;楼高 1 Knox访问控制 Apache Knox是一个为Apache Hadoop部署提供交互的应用网关&#xff0c;通过其REST API和用户友好的UI&#xff0c;为所有与Hadoop集群的REST和HTTP交互提供了统一的访问点。Knox不仅仅是一个访问网关&#xff0c;它还具备强大的访问控制…

理解 Node.js 中的事件循环

你已经使用 Node.js 一段时间了&#xff0c;构建了一些应用程序&#xff0c;尝试了不同的模块&#xff0c;甚至对异步编程感到很舒适。但是有些事情一直在困扰着你——事件循环&#xff08;Event Loop&#xff09;。 如果你像我一样&#xff0c;花费了无数个小时阅读文档和观看…

关于一名资深Java程序员在移动端的进阶之路

今天呢&#xff0c;就借此机会&#xff0c;跟大家聊一聊我的个人职业经历吧&#xff01; 那年刚毕业 刚毕业时候&#xff0c;入职的第一家公司&#xff0c;进去后&#xff0c;说实话&#xff0c;没有太大成长吧&#xff01;基本就是让我做一些可有可无的边缘性的工作&#xff…

【CSS】浅学一下filter

目录 1、基本概念 2、用法 3、应用案例 更加智能的阴影效果&#xff1a; 元素、网页置灰 元素强调、高亮 毛玻璃效果 调整网页sepia 褐色值可以实现护眼效果 1、基本概念 CSS filter 属性将模糊或颜色偏移等图形效果&#xff08;对比度、亮度、饱和度、模糊等等&#…

新闻稿发布:媒体重要还是价格重要

在当今信息爆炸的数字时代&#xff0c;企业推广与品牌塑造不可或缺的一环就是新闻稿发布。新闻稿是一种通过媒体渠道传递企业信息、宣传品牌、事件或产品新闻的文本形式。发布新闻稿的过程旨在将企业的声音传递给更广泛的受众&#xff0c;借助媒体平台实现品牌故事的广泛传播。…

Go使用vscode开发,必备的插件及最常用快捷键和代码自动补全

一、vscode必备插件 1.Go、Code Runner 2.Markdown All in One、Markdown Preview Enhanced、Paste Image 为进行Markdown文档编写提供很多快捷键和自动补全功能&#xff0c;使vscode可以完全代替Typora。 边写边看到Markdown渲染之后的样子&#xff0c;在 Preview 界面按住鼠…

ElasticSearch 集群搭建与状态监控cerebro

单机的elasticsearch做数据存储&#xff0c;必然面临两个问题:海量数据存储问题、单点故障问题。为了解决存储能力上上限问题就可以用到集群部署。 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard)&#xff0c;存储到多个节点单点故障问题:将分片数据在不同节点备份 (r…

初学编程,到底选Java还是C++?

初学编程&#xff0c;到底选Java还是C? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#x…

stable diffusion 人物高级提示词(三)动作、表情、眼神

一、动作 中文英文站立Standing走路Walking身体前倾Leaning Forward鞠躬Bowing战斗姿势Fighting Stance单腿站立Standing on One Leg坐在椅子上Sitting on a Chair手叉腰Hand on Hip手插兜Hand in Pocket双臂交叉Crossed Arms翘二郎腿Crossed Legs跪地Kneeling双手举起来Hands…

新手可理解的PyTorch线性层解析:神经网络的构建基石

目录 torch.nn子模块Linear Layers详解 nn.Identity Identity 类描述 Identity 类的功能和作用 Identity 类的参数 形状 示例代码 nn.Linear Linear 类描述 Linear 类的功能和作用 Linear 类的参数 形状 变量 示例代码 nn.Bilinear Bilinear 类的功能和作用 B…

为什么说上了金蝶、用友系统后,下一步是部署BI?

经常有些不熟悉BI工具的用户问我&#xff1a;金蝶、用友系统和BI工具与什么区别&#xff0c;为什么说上了金蝶、用友系统后&#xff0c;下一步就是部署BI&#xff1f;这两个系统工具的功能不重叠吗&#xff1f; 首先&#xff0c;要了解金蝶、用友系统和BI工具的各自作用。 金…

使用 pg_stat_statements 优化查询

使用 pg_stat_statements 优化查询 就使用量和社区规模而言&#xff0c;PostgreSQL 是增长最快的数据库之一&#xff0c;得到许多专业开发人员的支持&#xff0c;并得到广泛的工具、连接器、库和可视化应用程序生态系统的支持。 PostgreSQL 也是可扩展的&#xff1a;使用 Postg…