目录
- 前言
- 正文
- 准备工作
- 设备的初始化
- 设备信息的获取
- 主动采图
- 相机参数配置
- 创建doc树
- 获取doc树下的每一个元素并将其信息写入xml文件中
- 被动采图
- 总结
前言
本篇博客稍微记录一下我所写的插件。具体内容是有关于大恒相机的,关于这个相机,相信搜索到这个博客的应该都有所了解了,关于这个插件,我所完成的功能是:利用该相机提供的SDK完成主动采图,回调采图,以及显示出该相机的参数列表这三个主要的功能。下面就是正文,我只会贴属于这个插件的代码,其他部分就不贴出来了。所以,应该只能给你编写的代码一些启示,但就目前这些代码,却没办法运行起来这个代码的,你应该根据软件的功能去继承一些虚函数,就可以完成这个插件啦,这个博客只是节省你看SDK文档的时间,挺多东西,你应该可以从这上面得到。注意,如果程序出现没有办法加载这个插件的话,要检查一下这个相机的SDK下的dll文件有没有放在程序的运行路径之下,这个很重要,有可能会导致你的插件无法加载。
我这篇文章是三个功能的集合,如果想要看比较详细的,可以移步到另外三篇文章,这里给出地址:
大恒相机开发实践(1)——实时采图
大恒相机开发实践(2)——触发采图
大恒相机开发实践(3)——参数设置
正文
准备工作
首先,开始写这个插件肯定是从下载这个相机的SDK开始的,下面就给出下载链接。
大恒相机SDK,我们需要从这个软件的安装目录中拿出我们所需要的东西,需要的东西我也打包成一个链接:
大恒相机必备材料。 如果没积分的话,私信或评论噢。
设备的初始化
MDeviceDahengG3UC.cpp
下面这个函数的主要功能就是完成设备的初始化工作,下面这个函数没有什么跟那个SDK挂上钩的地方,接下去的这个函数比较重要。
bool MDeviceDahengG3UC::InitDevice(QString index,QString identifier)
{
m_cCameraID = index;
m_cIdentifier = identifier;
bool ret = false;
#ifdef WIN32_DAHENG_GEV
if(DeviceLoading(m_cIdentifier))
{
m_pConfigureObj = new MConfigureDahengG3UC();
m_pConfigureObj->InitConfigure(m_cCameraID,this);
m_pConfigureObj->RegisterConfigureCallback(m_fXmlChange,m_pCallUser);
QVariant wVal;
QVariant hVal;
QVariant pixelForamt;
QVariant frameRate;
this->GetParameter("Width",wVal);
this->GetParameter("Height",hVal);
this->GetParameter("PixelFormat",pixelForamt);
if(IsExistParameter("ResultingFrameRate"))
{
qDebug()<<"resultingFrameRate";
this->GetParameter("ResultingFrameRate",frameRate);
}
else if(IsExistParameter("ResultingFrameRateAbs"))
{
this->GetParameter("ResultingFrameRateAbs",frameRate);
}
m_iWidth = wVal.toInt();
m_iHeight = hVal.toInt();
m_cPixelFormat = pixelForamt.toString();
m_fFrameRate = frameRate.toFloat();
ret = true;
}
#endif
return ret;
}
下面这个函数就有比较多值得学习的地方,以下讲的地方都是从SDK中得出的。
- 首先,是相机设备的初始化
IGXFactory::GetInstance().Init();
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
- 接下来,就是获得当前设备的所有信息,这里就列举一些信息的获得就好了。这里可以稍微注意一下,强制类型转换在这里的应用。
GxIAPICPP::gxstring SerialNumber;
QString SerialNumber2;
GX_DEVICE_CLASS_LIST gClass2 = vectorDeviceInfo[n].GetDeviceClass();
SerialNumber = vectorDeviceInfo[n].GetSN();
SerialNumber2 = static_cast<QString>(SerialNumber);
- 接下来,根据设备序列号打开设备并获得实例
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(strSN,GX_ACCESS_EXCLUSIVE);
- 打开流对象
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
- 下面这个就是比较完整的函数了。
bool MDeviceDahengG3UC::DeviceLoading(QString identifier)
{
m_bLoaded = false;
bool bIsDeviceOpen = false;
bool bIsStreamOpen = false;
#ifdef WIN32_DAHENG_GEV
int nRet = -1;
IGXFactory::GetInstance().Init();
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
if (vectorDeviceInfo.size() <= 0)
{
qDebug()<<"No Device!";
return m_bLoaded;
}
else
{
for (uint n = 0; n < vectorDeviceInfo.size(); n++)
{
bool accessStatus = vectorDeviceInfo[n].GetAccessStatus();
if(accessStatus)
{
GxIAPICPP::gxstring SerialNumber;
QString SerialNumber2;
GX_DEVICE_CLASS_LIST gClass2 = vectorDeviceInfo[n].GetDeviceClass();
SerialNumber = vectorDeviceInfo[n].GetSN();
SerialNumber2 = static_cast<QString>(SerialNumber);
if(SerialNumber2.length()>=16)
SerialNumber2 = SerialNumber2.left(16);
if(identifier.contains(SerialNumber2))
{
m_cSerialNumber = SerialNumber2;
m_cModelName = static_cast<QString>(vectorDeviceInfo[n].GetModelName());
m_cCameraVendor = vectorDeviceInfo[n].GetVendorName();
m_cUserDefine = vectorDeviceInfo[n].GetUserID();
m_cDeviceVersion = vectorDeviceInfo[n].GetDisplayName();
GxIAPICPP::gxstring strSN = vectorDeviceInfo[n].GetSN();
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(strSN,GX_ACCESS_EXCLUSIVE);
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
m_pCaptureEventHandler = new CSampleCaptureEventHandler();
m_bLoaded = true;
bIsDeviceOpen = true;
break;
}
}
}
}
return m_bLoaded;
#endif
}
设备信息的获取
MDeviceDahengG3UCInfo.cpp
下面这个函数主要是获取根据SDK获取对象的相机信息,并且是相对上面那个函数会较全。
- 首先也是要进行初始化,并获得设备信息对象。
IGXFactory::GetInstance().Init();
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
- 然后就是获取设备信息的那部分了。注意一些强制类型转换。
- 下面这个就是比较完整的函数了。
bool MDeviceDahengG3UCInfo::SearchDeviceInfos(QStringList &lInfo)
{
bool ret = false;
#ifdef WIN32_DAHENG_GEV
int nRet = -1;
IGXFactory::GetInstance().Init();
GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
if(vectorDeviceInfo.size()>0)
{
for (uint32_t i = 0; i < vectorDeviceInfo.size(); i++)
{
if(vectorDeviceInfo[i].GetDeviceClass() == GX_DEVICE_CLASS_GEV||vectorDeviceInfo[i].GetDeviceClass()==GX_DEVICE_CLASS_U3V)
{
GxIAPICPP::gxstring ModelName = vectorDeviceInfo[i].GetModelName();
QString ModelName2 = static_cast<QString>(ModelName);
GxIAPICPP::gxstring CameraVendor = vectorDeviceInfo[i].GetVendorName();
QString CameraVendor2 = static_cast<QString>(CameraVendor);
GxIAPICPP::gxstring UserID = vectorDeviceInfo[i].GetUserID();
QString UserID2 = static_cast<QString>(UserID);
GxIAPICPP::gxstring DeviceID = vectorDeviceInfo[i].GetDeviceID();
QString DeviceID2 = static_cast<QString>(DeviceID);
GxIAPICPP::gxstring DeviceIP = vectorDeviceInfo[i].GetIP();
QString DeviceIP2 = static_cast<QString>(DeviceIP);
GxIAPICPP::gxstring DeviceSN = vectorDeviceInfo[i].GetSN();
QString DeviceSN2 = static_cast<QString>(DeviceSN);
GxIAPICPP::gxstring DeviceDisplayName = vectorDeviceInfo[i].GetDisplayName();
QString DeviceDisplayName2 = static_cast<QString>(DeviceDisplayName);
bool DeviceStatus = vectorDeviceInfo[i].GetAccessStatus();
QString devInfo;
devInfo += QString("%1:%2;").arg(XML_TLAYER_TYPE)
.arg(XML_TLAYER_U3V);
devInfo += QString("%1:%2;").arg(XML_DRIVER_TYPE)
.arg(m_cCameraType);
devInfo += QString("%1:%2;").arg(XML_DEVICE_MODEL_NAME)
.arg(ModelName2);
devInfo += QString("%1:%2;").arg(XML_DEVICE_USER_DEFINE)
.arg(UserID2);
devInfo += QString("%1:%2;").arg(XML_DEVICE_ID)
.arg(DeviceSN2);
devInfo += QString("%1:%2;").arg(XML_DEVICE_VENDOR)
.arg(CameraVendor2);
devInfo += QString("%1:%2;").arg(XML_DEVICE_VERSION)
.arg(DeviceDisplayName2);
devInfo += QString("%1:%2;").arg(XML_DEVICE_STATUS)
.arg(DeviceStatus);
qDebug()<<"=>GetDeviceDaHengU3V:"<<devInfo;
lInfo << devInfo;
}
}
}
#endif
return ret;
}
主动采图
下面这个函数是主动采图的两个函数,所谓主动采图,就是通过按钮,用户主动去控制采图的过程,控制定时器定时器的开关,从而得到在一定的时间内可以连续采图,最终得到较好的连续的图像。
- 首先,开启流通道采集
if(!m_objStreamPtr.IsNull())
{
qDebug()<<"MDeviceDahengG3UC::AcquisitionStart m_objStreamPtr";
m_objStreamPtr->StartGrab();
}
- 给设备发送开始开采命令
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
if(!m_objFeatureControlPtr.IsNull())
{
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
ret = RETURN_OK;
}
- 在这里调用相机参数配置的函数
if(m_pConfigureObj->UpdateConfigureFromDevice())
m_pConfigureObj->SlotConfigChanged();
if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())
m_pConfigureObj->SlotSimplyConfigChanged();
- 给设备发送关闭开采的命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
m_objStreamPtr->Close();
下面这个是比较打开采图的函数,关闭采图的函数
qint32 MDeviceDahengG3UC::AcquisitionStart()
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEV
if(m_bLoaded)
{
if(m_bStopWork)
{
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
m_objImageProcessPtr = m_objDevicePtr->CreateImageProcessConfig();
bool m_bIsColorFilter = m_objFeatureControlPtr->IsImplemented("PixelColorFilter");
if(!m_objStreamPtr.IsNull())
{
qDebug()<<"MDeviceDahengG3UC::AcquisitionStart m_objStreamPtr";
m_objStreamPtr->StartGrab();
}
if(!m_objFeatureControlPtr.IsNull())
{
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
ret = RETURN_OK;
}
if(m_pConfigureObj->UpdateConfigureFromDevice())
m_pConfigureObj->SlotConfigChanged();
if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())
m_pConfigureObj->SlotSimplyConfigChanged();
m_bStopWork =false;
}
}
#endif
return ret;
}
qint32 MDeviceDahengG3UC::AcquisitionStop()
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEV
if(m_bLoaded)
{
if(!m_bStopWork)
{
if((!m_objFeatureControlPtr.IsNull())&&(!m_objStreamPtr.IsNull()))
{
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
m_objStreamPtr->StopGrab();
m_objStreamPtr->Close();
}
if(m_pConfigureObj->UpdateConfigureFromDevice())
m_pConfigureObj->SlotConfigChanged();
if(m_pConfigureObj->UpdateSimplyConfigureFromDevice())
m_pConfigureObj->SlotSimplyConfigChanged();
ret = RETURN_OK;
m_bStopWork = true;
}
}
#endif
return ret;
}
这两个函数一旦实现,基本就完成主动采图的功能了,接下来就是相机参数的配置。
相机参数配置
ConfigureDahengG3UC.cpp
首先,这里给出的只是很小的一部分代码,只是插件中的一部分,至于节点成树的那部分就没有贴出来了。
创建doc树
- 首先判断好一些比较重要的指针传进来别是零了,所以,这里就要完成好检测的那个功能。
if((Q_NULLPTR == m_pNodeMap))
if(m_pDevice->m_objDevicePtr.IsNull())
- 通过相机的SDK得到相对应的参数集合featureNameList,featureRemoteNameList,它总共有两个参数集合。
GxIAPICPP::gxstring_vector featureNameList;
GxIAPICPP::gxstring_vector featureRemoteNameList;
CGXFeatureControlPointer featureControl = m_pDevice->m_objDevicePtr->GetFeatureControl();
if(!featureControl.IsNull())
featureControl->GetFeatureNameList(featureNameList);
GXFeatureControlPointer featureControl2 = m_pDevice->m_objDevicePtr->GetRemoteFeatureControl();
if(!featureControl2.IsNull())
featureControl2->GetFeatureNameList(featureRemoteNameList);
- 创建xml文件中的头部的一些信息还有创建根节点
QDomDocument *m_doc = new QDomDocument();
QDomProcessingInstruction instruction;
instruction = m_doc->createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
m_doc->appendChild(instruction);
QDomElement root = m_doc->createElement(XML_TAG_CONFIGUR);
m_doc->appendChild(root);
- 接下来就是拿出一个一个的参数出来弄成节点,然后往下传
for(size_t i=0;i<featureNameList.size();i++)
{
GxIAPICPP::gxstring name = featureNameList.at(i);
QDomElement param = m_doc->createElement(XML_TAG_PARAMETER);
if(CreateElement(name,m_pNodeMap,param,featureControl))
{
root.appendChild(param);
}
}
- 下面这个函数是比较完整的函数
bool MConfigureDahengG3UC::CreateDocXml()
{
bool ret = false;
#ifdef WIN32_DAHENG_GEV
if((Q_NULLPTR == m_pNodeMap))
{
qDebug()<<"MConfigureDahengG3UC::CreateDocXml m_pNodeMap is null";
return ret;
}
if(m_pDevice->m_objDevicePtr.IsNull())
{
qDebug()<<"MConfigureDahengG3UC::CreateDocXml m_pDevice->m_objDevicePtr.IsNull";
return ret ;
}
GxIAPICPP::gxstring_vector featureNameList;
GxIAPICPP::gxstring_vector featureRemoteNameList;
CGXFeatureControlPointer featureControl = m_pDevice->m_objDevicePtr->GetFeatureControl();
if(!featureControl.IsNull())
featureControl->GetFeatureNameList(featureNameList);
CGXFeatureControlPointer featureControl2 = m_pDevice->m_objDevicePtr->GetRemoteFeatureControl();
if(!featureControl2.IsNull())
featureControl2->GetFeatureNameList(featureRemoteNameList);
QDomDocument *m_doc = new QDomDocument();
QDomProcessingInstruction instruction;
instruction = m_doc->createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
m_doc->appendChild(instruction);
QDomElement root = m_doc->createElement(XML_TAG_CONFIGUR);
m_doc->appendChild(root);
for(size_t i=0;i<featureNameList.size();i++)
{
GxIAPICPP::gxstring name = featureNameList.at(i);
QDomElement param = m_doc->createElement(XML_TAG_PARAMETER);
if(CreateElement(name,m_pNodeMap,param,featureControl))
{
root.appendChild(param);
}
}
for(size_t i=0;i<featureRemoteNameList.size();i++)
{
GxIAPICPP::gxstring name = featureRemoteNameList.at(i);
QDomElement param = m_doc->createElement(XML_TAG_PARAMETER);
if(CreateElement(name,m_pNodeMap,param,featureControl2))
{
root.appendChild(param);
}
}
ret = m_pNodeMap->SetDocument(m_doc);
#endif
return ret;
}
获取doc树下的每一个元素并将其信息写入xml文件中
ConfigureDahengG3UC.cpp
这个函数,主要是接受该节点的属性,然后根据这个节点的类型创建不同类型连接在父节点的后面,并将其信息写入xml文件中
- 首先,对传进来的数据类型进行类型转换,这个转换还是蛮难的,至少我是花了挺多的时间研究这个东西。接下来就是获得节点的类型。
GxIAPICPP::gxstring gxName;
QString name = QString::fromStdString(gxName.c_str());
GX_FEATURE_TYPE gxType = featureControl->GetFeatureType(gxName);
接下来,就可以开始判断该数据的数据类型是什么,然后根据这个类型,调用对应的取信息的函数,就可以获取到一些比较必要的信息,将其写入xml文件之中。下面,列举两个:
if(gxType==GX_FEATURE_INT)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CIntFeaturePointer objIntPtr = featureControl->GetIntFeature(gxName);
int64_t valueInt;
int64_t valueMinInt;
int64_t valueMaxInt;
if(bIsReadable)
{
valueInt = objIntPtr->GetValue();
valueMinInt = objIntPtr->GetMin();
valueMaxInt = objIntPtr->GetMax();
element.setAttribute(XML_KEY_MIN,QString::number(valueMinInt,10));
element.setAttribute(XML_KEY_MAX,QString::number(valueMaxInt,10));
element.setAttribute(XML_KEY_VALUE,QString::number(valueInt,10));
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_NUMBER);
element.setAttribute(XML_KEY_DECIMALS,0);
element.setAttribute(XML_KEY_UNIT,"");
eType = IFT_IInteger;
ret = true;
}
else if(gxType == GX_FEATURE_FLOAT)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CFloatFeaturePointer objFloatPtr = featureControl->GetFloatFeature(gxName);
double valueFloat;
double valueMinFloat;
double valueMaxFloat;
if(bIsReadable)
{
valueFloat = objFloatPtr->GetValue();
valueMinFloat = objFloatPtr->GetMin();
valueMaxFloat = objFloatPtr->GetMax();
element.setAttribute(XML_KEY_MIN,valueMinFloat);
element.setAttribute(XML_KEY_MAX,valueMaxFloat);
element.setAttribute(XML_KEY_VALUE,valueFloat);
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_NUMBER);
element.setAttribute(XML_KEY_DECIMALS,3);
element.setAttribute(XML_KEY_UNIT,"");
eType = IFT_IFloat;
ret = true;
}
下面是较为完整的函数,
bool MConfigureDahengG3UC::CreateElement(GxIAPICPP::gxstring gxName,MNodeMap *nodeMap,QDomElement &element,CGXFeatureControlPointer featureControl)
{
bool ret = false;
#ifdef WIN32_DAHENG_GEV
qint32 iVisibility = 0;
QString name = QString::fromStdString(gxName.c_str());
QString displayName= name;
bool enable = false;
bool hide = false;
GX_XML_InterfaceType eType;
GX_FEATURE_TYPE gxType = featureControl->GetFeatureType(gxName);
Mc::VisibilityEnums visb = (Mc::VisibilityEnums)iVisibility;
QString visbStr = MEnumToString<Mc::VisibilityEnums>(visb);
element.setAttribute(XML_KEY_NAME,name);
element.setAttribute(XML_KEY_DISPLAYNAME,displayName);
element.setAttribute(XML_KEY_STEP,1);
element.setAttribute(XML_KEY_HIDE,hide);
element.setAttribute(XML_KEY_VISIBILITY,visbStr);
try
{
if(gxType==GX_FEATURE_INT)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CIntFeaturePointer objIntPtr = featureControl->GetIntFeature(gxName);
int64_t valueInt;
int64_t valueMinInt;
int64_t valueMaxInt;
if(bIsReadable)
{
valueInt = objIntPtr->GetValue();
valueMinInt = objIntPtr->GetMin();
valueMaxInt = objIntPtr->GetMax();
element.setAttribute(XML_KEY_MIN,QString::number(valueMinInt,10));
element.setAttribute(XML_KEY_MAX,QString::number(valueMaxInt,10));
element.setAttribute(XML_KEY_VALUE,QString::number(valueInt,10));
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_NUMBER);
element.setAttribute(XML_KEY_DECIMALS,0);
element.setAttribute(XML_KEY_UNIT,"");
eType = IFT_IInteger;
ret = true;
}
else if(gxType == GX_FEATURE_FLOAT)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CFloatFeaturePointer objFloatPtr = featureControl->GetFloatFeature(gxName);
double valueFloat;
double valueMinFloat;
double valueMaxFloat;
if(bIsReadable)
{
valueFloat = objFloatPtr->GetValue();
valueMinFloat = objFloatPtr->GetMin();
valueMaxFloat = objFloatPtr->GetMax();
element.setAttribute(XML_KEY_MIN,valueMinFloat);
element.setAttribute(XML_KEY_MAX,valueMaxFloat);
element.setAttribute(XML_KEY_VALUE,valueFloat);
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_NUMBER);
element.setAttribute(XML_KEY_DECIMALS,3);
element.setAttribute(XML_KEY_UNIT,"");
eType = IFT_IFloat;
ret = true;
}
else if(gxType == GX_FEATURE_ENUM)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
QString valueQEnum;
GxIAPICPP::gxstring_vector valueList;
if(bIsReadable)
{
CEnumFeaturePointer objEnumPtr = featureControl->GetEnumFeature(gxName);
valueList = objEnumPtr->GetEnumEntryList();
GxIAPICPP::gxstring valueEnum = objEnumPtr->GetValue();
valueQEnum = QString::fromStdString(valueEnum.c_str());
QStringList list;
for(size_t i=0;i<valueList.size();i++)
{
GxIAPICPP::gxstring gxValue = valueList[i];
QString gxQValue = QString::fromStdString(gxValue.c_str());
list<<gxQValue;
}
element.setAttribute(XML_KEY_ENUMENTRYS,list.join(";"));
element.setAttribute(XML_KEY_VALUE,valueQEnum);
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_COMBO);
eType = IFT_IEnumeration;
ret = true;
}
else if(gxType == GX_FEATURE_BOOL)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CBoolFeaturePointer objBoolPtr = featureControl->GetBoolFeature(gxName);
bool valueBool;
if(bIsReadable)
{
valueBool = objBoolPtr->GetValue();
element.setAttribute(XML_KEY_VALUE,QVariant(valueBool).toString());
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_BOOLEAN);
eType = IFT_IBoolean;
ret = true;
}
else if(gxType == GX_FEATURE_STRING)
{
bool gxIsWriteable = featureControl->IsWritable(gxName);
bool bIsReadable = featureControl->IsReadable(gxName);
if(gxIsWriteable)
enable = true;
CStringFeaturePointer objStringPtr = featureControl->GetStringFeature(gxName);
GxIAPICPP::gxstring valueStr;
if(bIsReadable)
{
valueStr = objStringPtr->GetValue();
element.setAttribute(XML_KEY_VALUE,QString::fromStdString(valueStr.c_str()));
}
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,XML_TYPE_STRING);
eType = IFT_IString;
ret = true;
}
else if(gxType == GX_FEATURE_COMMAND)
{
CCommandFeaturePointer objCommandPtr = featureControl->GetCommandFeature(gxName);
bool gxIsWriteable = featureControl->IsWritable(gxName);
if(gxIsWriteable)
enable = true;
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_CHECKABLE,"1");
element.setAttribute(XML_KEY_TYPE,XML_TYPE_COMMAND);
element.setAttribute(XML_KEY_VALUE,"true");
eType = IFT_ICommand;
ret = true;
}
else if(gxType == GX_FEATURE_BUFFER)
{
CRegisterFeaturePointer objRegisterPtr = featureControl->GetRegisterFeature(gxName);
bool gxIsWriteable = featureControl->IsWritable(gxName);
if(gxIsWriteable)
enable = true;
element.setAttribute(XML_KEY_ENABLE,enable);
element.setAttribute(XML_KEY_TYPE,"Register");
}
}
catch(...)
{
qDebug()<< "-->Error CreateElement: "<<name;
ret = false;
}
if(ret)
{
MNode *temp;
nodeMap->CreateNode(&temp,Mc::NodeEnums(eType));
if(temp)
{
temp->SetElement(element,false);
nodeMap->Insert(name,temp);
}
}
#endif
return ret;
}
被动采图
这里所谓的被动采图,其实就是软触发抓图,就是按下一个按钮,便执行一次抓图操作。这里就贴出一个比较重要的触发抓图函数。
- 首先,初始化一个固定的图像的大小,确保这个图像的大小与你要显示的图像的框的大小是一致的,不然,就容易出现,一个框出现三个图像的状况。不信你可以试试看。
if((img->width() !=m_iWidth) ||
(img->height() !=m_iHeight) ||
(img->format() !=format) )
{
qDebug()<<"--> HiDahengG3V:CaptureImageEx reset image memory! ";
*img = QImage(m_iWidth,m_iHeight,format);
if(format == QImage::Format_Indexed8)
img->setColorTable(m_vColorTabel);
}
- 接下来,根据相机获取单帧
CImageDataPointer objImageDataPtr;
if(!m_objStreamPtr.IsNull())
{
objImageDataPtr = m_objStreamPtr->GetImage(500);
}
- 然后对该单帧进行处理,得到一个处理好的帧,往回传,注意并把信息赋值给info。
if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)
{
void *pbit = objImageDataPtr->GetBuffer();
int size = qMin((int)objImageDataPtr->GetPayloadSize(),img->byteCount());
memcpy(img->bits(),pbit,size);
info->nWidth = (qint32)objImageDataPtr->GetWidth();
info->nHeight = (qint32)objImageDataPtr->GetHeight();
info->nFramerLen = (qint32)objImageDataPtr->GetPayloadSize();
quint64 nformat = objImageDataPtr->GetPixelFormat();
info->cFormat = GetPixelFormat(nformat);
info->fFrameRate = m_fFrameRate;
ret = RETURN_OK;
}
- 下面是比较完整的函数
qint32 MDeviceDahengG3UC::CaptureImageEx(QImage *img, MFrameInfo *info)
{
qint32 ret = RETURN_FAIL;
#ifdef WIN32_DAHENG_GEV
if(m_bLoaded)
{
QImage::Format format = QImage::Format_Indexed8;
if(m_cPixelFormat.compare("RGB888")==0)
format = QImage::Format_RGB888;
if((img->width() !=m_iWidth) ||
(img->height() !=m_iHeight) ||
(img->format() !=format) )
{
qDebug()<<"--> HiDahengG3V:CaptureImageEx reset image memory! ";
*img = QImage(m_iWidth,m_iHeight,format);
if(format == QImage::Format_Indexed8)
img->setColorTable(m_vColorTabel);
}
CImageDataPointer objImageDataPtr;
if(!m_objStreamPtr.IsNull())
{
objImageDataPtr = m_objStreamPtr->GetImage(500);
}
if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)
{
void *pbit = objImageDataPtr->GetBuffer();
int size = qMin((int)objImageDataPtr->GetPayloadSize(),img->byteCount());
memcpy(img->bits(),pbit,size);
info->nWidth = (qint32)objImageDataPtr->GetWidth();
info->nHeight = (qint32)objImageDataPtr->GetHeight();
info->nFramerLen = (qint32)objImageDataPtr->GetPayloadSize();
quint64 nformat = objImageDataPtr->GetPixelFormat();
info->cFormat = GetPixelFormat(nformat);
info->fFrameRate = m_fFrameRate;
ret = RETURN_OK;
}
}
#endif
return ret;
}
class CSampleCaptureEventHandler : public ICaptureEventHandler
{
public:
void DoOnImageCaptured(CImageDataPointer& objImageDataPointer, void* pUserParam)
{
MDeviceDahengG3UC* pDev = static_cast<MDeviceDahengG3UC*>(pUserParam);
pDev->triggerEvent(objImageDataPointer);
}
};
总结
现在完成了几个插件之后,才觉得原来这个插件是最好写的,因为这个SDK给的接口信息是最完整的,能较好的让我们利用好这些接口去做一些事情,后面遇到的相机的都让我们感觉很麻烦,如果有空,我也会做些记录,如果有错,麻烦各位在评论区指出哈!!感谢!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)