前言
这里也对这个插件进行一些记录,对于这个插件,我只完成了实时采图与回调采图(触发采图),因为这个相机的SDK并没有给我们留接口获取可以获取配置相机参数的接口。所以,我这里基本也可以给个结论给那些想要找这样一个接口的人,可以放弃这样的一个想法了。除非他们对他们的SDK进行更新,不然,应该是没有的。这个与这篇博客大恒相机采图功能的QT实现插件还是有较大相似的地方的,都可以进行参考。注意,如果程序出现没有办法加载这个插件的话,要检查一下这个相机的SDK下的dll文件有没有放在程序的运行路径之下,这个很重要,有可能会导致你的插件无法加载。
主动采图
首先给出完整的函数:
qint32 MDeviceDahuaG3UC::AcquisitionStart()
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHUA_G3U
if(m_bLoaded)
{
if(m_bStopWork)
{
CSystem &systemObj = CSystem::getInstance();
if (NULL == streamPtr.get())//streamPtr的初始化在 DeviceLoading
{
printf("create stream obj fail.\n");
return false;
}
if(!isTrigger)
{
bool isStartGrabbingSuccess = streamPtr->startGrabbing();// 开始拉流
if (!isStartGrabbingSuccess)
{
printf("StartGrabbing fail2.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
}
// if(m_pConfigureObj->UpdateConfigureFromDevice())
// {
// m_pConfigureObj->SlotConfigChanged();
// }
// if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())
// {
// m_pConfigureObj->SlotSimplyConfigChanged();
// }
ret = RETURN_OK;
m_bStopWork =false;
}
}
#endif
return ret;
}
qint32 MDeviceDahuaG3UC::AcquisitionStop()
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHUA_G3U
if(m_bLoaded)
{
if(!m_bStopWork)
{
CSystem &systemObj = CSystem::getInstance();
if (NULL == streamPtr.get())//streamPtr的初始化在 DeviceLoading
{
printf("create stream obj fail.\n");
return false;
}
bool isStopGrabbingSuccess = streamPtr->stopGrabbing();
if (!isStopGrabbingSuccess)
{
printf("StopGrabbing fail.\n");
return false;
}
m_bStopWork =true;
}
}
#endif
return ret;
}
下面开始进行解析
- 首先,获取系统实例,注意,这里是一个单例,所以,不管你获取多少次,它都是还是那个
systemObj
CSystem &systemObj = CSystem::getInstance();
- 开始采图
bool isStartGrabbingSuccess = streamPtr->startGrabbing();// 开始拉流
if (!isStartGrabbingSuccess)
{
printf("StartGrabbing fail2.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
被动抓图
所谓被动抓图,即为软触发抓图,也可以称为回调抓图。通过按钮进行软触发,控制相机的抓图。
首先,先给出整个完整的函数,大概瞄一眼
qint32 MDeviceDahuaG3UC::GrabThreadStart()
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHUA_G3U
if(m_bLoaded)
{
try {
bool bRet = false;
if (NULL == sptrAcquisitionControl.get())
{
printf("create AcquisitionControl object fail.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
if (NULL == streamPtr.get())// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
{
printf("create stream obj fail.\r\n");
return false;
}
if(sptrAcquisitionControl!=NULL)
{
bool bRet2 = setSoftTriggerConf(sptrAcquisitionControl);
if (!bRet2)
{
printf("set soft trigger config fail.\n");
// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
}
bRet = streamPtr->attachGrabbingEx(onGetFrame,(void*)this);// 注册回调函数
if(!bRet)
{
printf("attach Grabbing fail.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
bool isStartGrabbingSuccess = streamPtr->startGrabbing();// 开始拉流
if (!isStartGrabbingSuccess)
{
printf("StartGrabbing fail2.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
isTrigger = true;
ret = RETURN_OK;
}
catch (...) {
qDebug()<<"MDeviceDahuaG3UC::GrabThreadStart has nullptr";
}
}
#endif
return ret;
}
void MDeviceDahuaG3UC::triggerEvent(const CFrame &pFrameInfo)const
{
#ifdef WIN32_DAHUA_G3U
if(m_bStopWork)
{
qDebug()<<"triggerEvent m_bStopWork is true";
return;
}
if(m_fGrabCallbackEx)
{
MFrameInfo info;
info.nWidth = pFrameInfo.getImageWidth();
info.nHeight = pFrameInfo.getImageHeight();
info.nFramerLen = pFrameInfo.getImageSize();
info.cFormat = pFrameInfo.getImagePixelFormat();
uchar *pbit = (uchar*)pFrameInfo.getImage();//得到指向Buffer的地址
m_fGrabCallbackEx(m_pCallUser,pbit,&info);
//qDebug()<<"MDeviceHikG3UC::triggerEvent"<<pFrameInfo->nFrameNum<<m_cPixelFormat;
}
#endif
}
- 首先,先判断后面要进行抓图的一些指针是否为空,为空,就不能进行抓图了。
if (NULL == sptrAcquisitionControl.get())
{
printf("create AcquisitionControl object fail.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
if (NULL == streamPtr.get())// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
{
printf("create stream obj fail.\r\n");
return false;
}
- 设置触发源,触发器,触发模式
bool MDeviceDahuaG3UC::setSoftTriggerConf(IAcquisitionControlPtr sptrAcquisitionCtl)
{
// 设置触发源为软触发
CEnumNode enumNode = sptrAcquisitionCtl->triggerSource();
bool bRet = enumNode.setValueBySymbol("Software");
if (bRet != true)
{
printf("set trigger source fail.\n");
return false;
}
// 设置触发器
enumNode = sptrAcquisitionCtl->triggerSelector();
bRet = enumNode.setValueBySymbol("FrameStart");
if (bRet != true)
{
printf("set trigger selector fail.\n");
return false;
}
// 设置触发模式
enumNode = sptrAcquisitionCtl->triggerMode();
bRet = enumNode.setValueBySymbol("On");
if (bRet != true)
{
printf("set trigger mode fail.\n");
return false;
}
return true;
}
- 注册回调函数
bRet = streamPtr->attachGrabbingEx(onGetFrame,(void*)this);// 注册回调函数
void onGetFrame(const CFrame &pFrame, const void* pUser)
{
const MDeviceDahuaG3UC* pDev=static_cast<const MDeviceDahuaG3UC*>(pUser);
if(pDev)
{
pDev->triggerEvent(pFrame);
}
}
- 开始抓图
bool isStartGrabbingSuccess = streamPtr->startGrabbing();// 开始拉流
if (!isStartGrabbingSuccess)
{
printf("StartGrabbing fail2.\n");// 实际应用中应及时释放相关资源,如diconnect相机等,不宜直接return
return false;
}
- 注意
triggerEvent
的这个函数,这个函数会把获得的buffer和一些信息传递给这个回调函数m_fGrabCallbackEx
让其把信息传到最上层,从而显示图片。
总结
我前面也说过了,这个上面的代码只能起到一些你写插件的一些参考而已,你只能去汲取你所需要的那部分东西而已,千万别想着照搬,因为有太多东西是没有贴出来的。首先,相信自己,可以写出来,其次多参考它给的demo和开发文档。我这里也把我用到的大华相机的SDK给贴出来,地址如下:
大华相机参考SDK开发材料
因为这个积分可能不受控制的涨的很快,所以,如果有有需要,但是没积分的,可以私信我!