目录

  • 前言
  • 正文
    • 编程环境
    • 获取相机的一些基本信息
    • 主动抓图
    • 触发抓图
    • 参数的获取
  • 参考

前言

由于工作的需要,又完成了一款相机的SDK的调用。通过这一款相机的调用,还是学习到了很多调用一款相机的SDK在细节上的一些东西。本篇文章基本只会讲关于调用过程中的一些重难点。其他,通过SDK的Demo就基本能够完成。但整体的流程,我还是会按照我标题写的那样逐步写下来的。希望能帮你少走一些弯路。

正文

编程环境

我的工作环境是:Win10+Qt5.15+MSVC VS2019
大华的SDK使用的是:Ver2.3.1。基本上大华的SDK就都在这里面了。注意,我使用的这款SDK是没有C++的接口的,只有C#和C。并且还有一个很多的缺陷,这个版本没有一个可以获取所有参数的统一的接口。据说Vver2.2.5这款是有C++的接口的。我也没详细去看,仅供参考,有需要还是要自己下载下来,看一下对应版本的SDK的区别。再决定开发的版本。

获取相机的一些基本信息

一开始,我们要先获取一下该相机的基本信息,这基本是所有操作SDK最开始的操作:
我选取核心的这个函数展示一下:

bool MDeviceDahuaG3UCInfo::SearchDeviceInfos(QStringList &lInfo)
{int ret = IMV_OK;
#ifdef WIN_DAHUA_G3UIMV_DeviceInfo* pDevInfo = NULL;// 发现设备// discover cameraIMV_DeviceList deviceInfoList;ret = IMV_EnumDevices(&deviceInfoList, interfaceTypeAll);if (IMV_OK != ret){qDebug()<<"Enum Device fail"<<ret;return false;}if (deviceInfoList.nDevNum < 1){qDebug()<<"--> no camera";return false;}for (uint32_t i = 0; i < deviceInfoList.nDevNum; i++){pDevInfo = &deviceInfoList.pDevInfo[i];QString ModelName = pDevInfo->modelName;QString CameraVendor = pDevInfo->vendorName;QString DeviceVersion = pDevInfo->deviceVersion;QString manufacetureInfo = pDevInfo->manufactureInfo;QString DeviceSN = pDevInfo->serialNumber;QString DeviceKey = pDevInfo->cameraKey;QString DeviceUserID = pDevInfo->cameraName;bool bUsed = isDeviceOpen(DeviceKey);QString devInfo;devInfo += QString("%1:%2;").arg(XML_TLAYER_TYPE)      //传输协议.arg(XML_TLAYER_GEV);devInfo += QString("%1:%2;").arg(XML_DRIVER_TYPE)      //驱动类型.arg(m_cCameraType);devInfo += QString("%1:%2;").arg(XML_DEVICE_MODEL_NAME)//设备型号.arg(ModelName);devInfo += QString("%1:%2;").arg(XML_DEVICE_USER_DEFINE)//自定义名称.arg(DeviceUserID);devInfo += QString("%1:%2;").arg(XML_DEVICE_ID)         //序列号.arg(DeviceSN);devInfo += QString("%1:%2;").arg(XML_DEVICE_ID)         //序列号.arg(DeviceSN);devInfo += QString("%1:%2;").arg(XML_DEVICE_VENDOR)     //生产厂家.arg(CameraVendor);devInfo += QString("%1:%2;").arg(XML_DEVICE_VERSION)    //设备版本.arg(DeviceVersion);devInfo += QString("%1:%2;").arg(XML_DEVICE_STATUS)     //设备状态.arg(bUsed);qDebug()<<"=>GetDeviceDaHuaG3U:"<<devInfo;lInfo << devInfo;ret = true;}
#endifreturn ret;
}

里面大部分内容应该都是很简单的。里面有一个isDeviceOpen这个函数可以暂时先不用管它,等后面,我会重点讲一下这部分的内容。
这里基本上就是发现设备,调用第几个设备的接口。从而获取对应设备的信息。

主动抓图

主动抓图的话,也是比较简单地,核心就是弄个线程不断的调用下面这个函数就可以了。你们可以做个参考,如果语言是Qt的。关于这部分还是建议去看大华SDK本身的demo.qt的写的也不错。

qint32 MDeviceDahuaG3UC::CaptureImageEx(QImage *img, MFrameInfo *info)
{qint32 ret = RETURN_FAIL;try {if(m_bLoaded&&m_cTriggerMode=="Off"){IMV_Frame frame;unsigned char* pRGBbuffer = NULL;ret = IMV_GetFrame(m_devHandle, &frame, 1000);if (IMV_OK != ret){return ret;}m_iHeight = (qint32)frame.frameInfo.height;m_iWidth = (qint32)frame.frameInfo.width;QImage::Format format = QImage::Format_Indexed8;if(m_cPixelFormat.compare("Mono8")!=0)format = QImage::Format_RGB888;if((img->width() !=m_iWidth) ||(img->height() !=m_iHeight) ||(img->format() !=format) ){qDebug()<<"--> DahuaG3V:CaptureImageEx reset image memory! ";*img = QImage(m_iWidth,m_iHeight,format);if(format == QImage::Format_Indexed8)img->setColorTable(m_vColorTabel);}if(m_cPixelFormat.compare("Mono8")!=0)//注意点1{int nRgbBufferSize = 0;nRgbBufferSize = frame.frameInfo.width *frame.frameInfo.height*3;pRGBbuffer = (unsigned char*)malloc(nRgbBufferSize);if (pRGBbuffer == NULL){// 释放内存// release memoryfree(frame.pData);printf("RGBbuffer malloc failed.\n");}IMV_PixelConvertParam stPixelConvertParam;stPixelConvertParam.nWidth = frame.frameInfo.width;stPixelConvertParam.nHeight = frame.frameInfo.height;stPixelConvertParam.ePixelFormat = frame.frameInfo.pixelFormat;stPixelConvertParam.pSrcData = frame.pData;stPixelConvertParam.nSrcDataLen = frame.frameInfo.size;stPixelConvertParam.nPaddingX = frame.frameInfo.paddingX;stPixelConvertParam.nPaddingY = frame.frameInfo.paddingY;stPixelConvertParam.eBayerDemosaic = demosaicNearestNeighbor;stPixelConvertParam.eDstPixelFormat = gvspPixelRGB8;stPixelConvertParam.pDstBuf = pRGBbuffer;stPixelConvertParam.nDstBufSize = nRgbBufferSize;int ret = IMV_PixelConvert(m_devHandle, &stPixelConvertParam);if (IMV_OK != ret){// 释放内存// release memoryqDebug()<<"image convert to RGB failed! ErrorCode"<<ret;if(pRGBbuffer&&frame.pData)//注意点2{free(frame.pData);free(pRGBbuffer);}return false;}}void *pbit = nullptr;int size =0;if(m_cPixelFormat.compare("Mono8")!=0){pbit = pRGBbuffer;size = qMin((int)frame.frameInfo.size*3,img->byteCount());//注意点3}else{pbit = frame.pData;size = qMin((int)frame.frameInfo.size,img->byteCount());//这个操作是为了防止复制操作会导致数据溢出}if(size)memcpy(img->bits(),pbit,size);info->nWidth  = (qint32)frame.frameInfo.width;info->nHeight = (qint32)frame.frameInfo.height;info->nFramerLen = (qint32)frame.frameInfo.size;quint64 nformat = (qint32)frame.frameInfo.pixelFormat;//info->cFormat = nformat;info->cFormat = "RGB888";info->fFrameRate = m_fFrameRate;if(m_cPixelFormat.compare("Mono8")!=0&&pRGBbuffer!=nullptr)//注意点4{free(pRGBbuffer);}ret = IMV_ReleaseFrame(m_devHandle, &frame);//注意点5if (IMV_OK != ret){printf("Release frame failed! ErrorCode[%d]\n", ret);}ret = RETURN_OK;}} catch (...) {qDebug()<<"MDeviceDahuaG3UC::CaptureImageEx has some nullPtr";return false;}return ret;
}

有几个需要注意的点,我这里提一下,对应的注意点在程序中都已经标出,可以对应着过去那边看一看:
注意点1:首先,我在这个程序里面,不管当前相机采集出的格式是什么(除了Mon8),我都会调用它的转换函数,转换成RGB888.这也是其demo提供出的方法。
注意点2:这里最好做一个判断,再去释放,万一分配不成功,你还强行去释放,程序容易崩溃。
注意点3:拷贝数据的时候,注意,这里要拷贝3倍的mono8格式数据的大小。
注意点4:转换完后,要及时把申请的内存给释放了。不然,你程序很快就会变缓慢,然后卡顿崩溃。因为内存都会分配完了。
注意点5:注意,结束的时候,要调用IMV_ReleaseFrame的这个帧。

触发抓图

关于这部分,还是建议去看其SDK的demo,因为我这边会写的比较割裂,也就是步骤都是比较分开的,不太适宜观看,但为了文章结构的完整性,还是贴上来,进行讲解。
1、首先,要先注册一下回调函数,这是触发前的准备工作:
code

qint32  MDeviceDahuaG3UC::GrabThreadStart()
{qint32 ret = RETURN_FAIL;if(m_bLoaded){try {IMV_ClearFrameBuffer(m_devHandle);//注意点1ret = IMV_AttachGrabbing(m_devHandle, (IMV_FrameCallBack)onGetFrame, this);//注意点2if (IMV_OK != ret){printf("Attach grabbing failed! ErrorCode[%d]\n", ret);}else{ret = RETURN_OK;}}catch (...) {qDebug()<<"MDeviceDahuaG3UC::GrabThreadStart has nullptr";}}return ret;
}

注意点

  1. 注意点1:注意,最好在开始注册之前,清空一下相机的帧缓存,不然,有可能会出现开始注册的时候,由于相机有图片,自动调用了注册函数了。
  2. 注意点2:ret = IMV_AttachGrabbing(m_devHandle, (IMV_FrameCallBack)onGetFrame, this);//注意点2
    这个就是注册函数了,注意,中间的回调函数要进行强制类型转换。

2、这个函数就是回调函数,首先,这个函数要是静态函数,将,传入的对象进行强制类型转换。
code

static void onGetFrame(IMV_Frame* pFrame, const void* pUser)
{const MDeviceDahuaG3UC* pDev=static_cast<const MDeviceDahuaG3UC*>(pUser);if(pDev){pDev->triggerEvent(pFrame);}}

3、 接下来是调用的传帧的函数
code

void   MDeviceDahuaG3UC::triggerEvent(IMV_Frame* pFrame)const
{#ifdef WIN_DAHUA_G3Uint ret = IMV_OK;if(m_bStopWork){qDebug()<<"triggerEvent m_bStopWork is true";return;}if(m_fGrabCallbackEx){MFrameInfo info;unsigned char* pRGBbuffer = NULL;if(m_cPixelFormat.compare("Mono8")!=0)//注意点1{int nRgbBufferSize = 0;nRgbBufferSize = pFrame->frameInfo.width *pFrame->frameInfo.height * 3;//注意点2pRGBbuffer = (unsigned char*)malloc(nRgbBufferSize);if (pRGBbuffer == NULL){// 释放内存// release memoryfree(pFrame->pData);printf("RGBbuffer malloc failed.\n");}IMV_PixelConvertParam stPixelConvertParam;stPixelConvertParam.nWidth = pFrame->frameInfo.width;stPixelConvertParam.nHeight = pFrame->frameInfo.height;stPixelConvertParam.ePixelFormat = pFrame->frameInfo.pixelFormat;stPixelConvertParam.pSrcData = pFrame->pData;stPixelConvertParam.nSrcDataLen = pFrame->frameInfo.size;stPixelConvertParam.nPaddingX = pFrame->frameInfo.paddingX;stPixelConvertParam.nPaddingY = pFrame->frameInfo.paddingY;stPixelConvertParam.eBayerDemosaic = demosaicNearestNeighbor;stPixelConvertParam.eDstPixelFormat = gvspPixelRGB8;stPixelConvertParam.pDstBuf = pRGBbuffer;stPixelConvertParam.nDstBufSize = nRgbBufferSize;ret = IMV_PixelConvert(m_devHandle, &stPixelConvertParam);if (IMV_OK != ret){// 释放内存// release memoryqDebug()<<"image convert to RGB failed! ErrorCode\n";free(pFrame->pData);free(pRGBbuffer);return ;}}uchar *pbit = nullptr;if(m_cPixelFormat.compare("Mono8")!=0){pbit = pRGBbuffer;info.nFramerLen = pFrame->frameInfo.size*3;//注意点3info.cFormat = "RGB888";}else{pbit = pFrame->pData;info.nFramerLen = pFrame->frameInfo.size;info.cFormat = "Mono8";}info.nWidth  = pFrame->frameInfo.width;info.nHeight = pFrame->frameInfo.height;m_fGrabCallbackEx(m_pCallUser,pbit,&info);if(m_cPixelFormat.compare("Mono8")!=0&&pRGBbuffer!=NULL)//注意点4{free(pRGBbuffer);}ret = IMV_ReleaseFrame(m_devHandle, pFrame);//注意点5if (IMV_OK != ret){qDebug()<<"Release frame failed!";}}
#endif
}

注意点
注意点1:注意,非Mono8格式的帧要进行格式转换。
注意点2:开辟的内存空间,要是宽高的三倍。
注意点3:往上传递的帧信息的大小也要是宽
高的3倍。
注意点4:如果是非Mono8的格式的要对申请的缓存进行释放
注意点5:要释放帧。

参数的获取

关于这个SDK的缺点就在于这了,没有一个接口可以获取所有的参数名称,让我能够进行统一获取,然后,批量化显示,所以,我这里只能使用xml文件进行固定的一些参数进行显示。
我这里就直接举例几个获取与设置参数的函数。
曝光的获取:

double MDeviceDahuaG3UC::GetExposureTime()
{double ExposureTime = 0;int ret = IMV_OK;
#ifdef WIN_DAHUA_G3Uif(m_devHandle){ret = IMV_GetDoubleFeatureValue(m_devHandle,"ExposureTime",&ExposureTime);if (IMV_OK != ret){qDebug()<<"--> GetExposureTime fail"<<ExposureTime;}else{m_fExposureTime = ExposureTime/1000;}}
#endifreturn m_fExposureTime;
}

曝光的设置

void MDeviceDahuaG3UC::SetExposureTime(double time)
{int ret = IMV_OK;
#ifdef WIN_DAHUA_G3Uif(m_devHandle){ret = IMV_SetDoubleFeatureValue(m_devHandle,"ExposureTime",time*1000);if (IMV_OK != ret){qDebug()<<"--> SetExposureTime fail"<<time;}else{m_fExposureTime = time;}}
#endif
}

参考

大华相机SDK调用——主动采图、外触发、参数相关推荐

  1. C#调用大华相机SDK获取图片,转换成VisionPro的Icogimage格式

    文章讲的是C#调用大华相机SDK,通过回调事件获取图片并转换成visionpro的Icogimage格式,文章底部会分享例程.在调用SDK之前,需要先安装大华的相机软件到C盘,不安装到C盘会显示依赖项 ...

  2. Unity调用大华相机SDK采集图像及基本功能设定

    unity平台对视频播放不是很友好,而大华的SDK只有c#版本的并没有专门为unity做出来SDK,最开始尝试过使用SDK里面的方式获取YUV格式的视频流,再讲YUV格式的视频流转换为unity可以播 ...

  3. 1.8安装大华相机SDK及测试

    不同工业相机的sdk不同,可以到相应的官网下载,我使用的是大华相机 下载SDK: 官方下载地址:http://download.huaraytech.com/pub/sdk/ 我使用的是2.2.5的L ...

  4. 大华相机接入web页面实现人脸识别

    先看下效果,中间主视频流就是大华相机(视频编码H.264),海康相机(视屏编码H.265) 前端接入视屏流代码 <!--视频流--><div id="col2"& ...

  5. 使用大华NetSDK对接大华相机

    使用大华NetSDK对接相机 一. 下载大华NetSDK support 根据自己的需要下载对应版本的sdk.这边我们就以Win32版本作为开发使用. 下载的文件解压后,内部文件如下图所示: 开发使用 ...

  6. 【Delphi】从大华科技SDK的C头文件转换来的DHNetSDK.pas和DHConfigSDK.pas

    大华科技的SDK不支持Delphi,如果想用Delphi调用大华科技SDK里面的接口,需要先把其中C头文件转换成Delphi的pas文件.文件压缩包里面的两个文件(DHNetSDK.pas和DHCon ...

  7. 基于大恒相机SDK,二次开发

    基于大恒相机SDK,二次开发(C#) 界面如下 有曝光.增益两个参数可以调整(平台是X64) 有问题可以问 看到就回答 using System; using System.Collections.G ...

  8. 2019.11.12-最新大华摄像机SDK开发,预览实时视频并指定码流格式保存到文件中(可观看)

    大华摄像机SDK开发,预览实时视频并指定码流格式保存到文件中 由于本人最近在开发大华摄像机,特此分享一些经验给到各位开发朋友,本次实例是关于大华摄像机的实时预览视频码流保存到文件中的Demo,本人还开 ...

  9. 相机PHP,C/C++、C#、PHP相机开发实例 大恒相机SDK

    [实例简介]C/C .C#.PHP相机开发实例 大恒相机SDK [实例截图] [核心代码] public  class GxBitmap { IGXDevice      m_objIGXDevice ...

  10. 大华相机IP网段更新配置

    大华相机在出厂后一般都会对应一个IP,如192.169.1.XX.实际项目中,为了将相机放到与wifi相同的频段,一般需要更改相机的IP和网关,使之与wifi处于相同频段,那么就可以在wifi覆盖的所 ...

最新文章

  1. 【Away3D代码解读】(四):主要模块简介
  2. optee内存管理和页表建立
  3. 在浏览器中分析AV1码流
  4. c#10:string内插处理
  5. python操作mysql时mysqldb和pymysql的安装和使用
  6. 终于实现了 SpringBoot+WebSocket实时监控异常....
  7. 云-PC-matlab-物联网及其它
  8. Chrome安装程序遇到错误 0xe0000008解决办法
  9. 快看你的达标没!充电宝新国标只有这20家合格
  10. Python 数据处理与分析(六) 设计一个高回报的投资组合(投资回报和风险分析)任务 5:使用Python实现均值-方差组合模型
  11. #7 实现指定函数printSize
  12. 如何使用射手影音寻找字幕
  13. 再探 set/map
  14. 【已解决】探究CUDA out of memory背后原因,如何释放GPU显存?
  15. [英语]凡是倒装都有表“强调“之意
  16. 全球量产汽车流行色彩报告:亚洲偏爱白色,欧洲喜好灰色
  17. Pr——2020版本对导入视频如何编辑的操作
  18. 64位多核 MIPS 异常和中断内核代码分析
  19. excel修改柱状图系列1名称
  20. linux 喇叭 耳机 切换,解决linux耳机和喇叭同时发音的问题

热门文章

  1. 学做‘视频剪辑’攻略
  2. 【STP】生成树协议及STP 802.1D (上)
  3. 局域网计算机如何传输文件,强烈推荐电脑同一个局域网传输文件的图文教程
  4. python加法运算符可以用来连接字符串并生成新字符串_中国大学MOOCPython语言入门网课答案...
  5. UE4官网关于GamePlay框架的介绍
  6. 苹果4s怎么越狱_越狱软件续签教程
  7. Git64位windows版Git-2.10.1-64-bit.exe
  8. 写一个用矩形法求定积分的通用函数,分别求sinx,cosx,expx从0到1的定积分(指针方法处理)——C语言
  9. IDEA初始jsp模板和修改jsp模板
  10. 企业如何利用OA系统轻松管理员工请休假