工业相机如何调整SDK枚举顺序或者打开顺序
工业相机如何调整SDK枚举顺序或者打开顺序
当使用海康工业相机SDK时,调用其枚举接口然后打开相机时,会有出现一个问题,打开顺序是固定的,如果更换相机,相机的顺序又会出现变化,总结下规律,可以发现,其顺序是根据相机出厂序列号从小到大来的;
但是,对于使用者来讲,还是会有个很尴尬的问题,多相机,在设备安装时,肯定不可能严格按照序列号大小依次安装,总会出现乱序的情况,那么怎样才能顺风顺水的打开我想要的相机呢
方法1:针对枚举出来的顺序重新排序
SDK调用的第一步,通常是枚举相机,那么枚举出来的信息,都在相机结构体
MV_CC_DEVICE_INFO_LIST
里面,我们通过去改变结构体里面的排序,自然就可以改变打开顺序
设备信息结构体
/// \~chinese 设备信息列表 \~english Device Information List
typedef struct _MV_CC_DEVICE_INFO_LIST_
{unsigned int nDeviceNum; ///< [OUT] \~chinese 在线设备数量 \~english Online Device NumberMV_CC_DEVICE_INFO* pDeviceInfo[MV_MAX_DEVICE_NUM]; ///< [OUT] \~chinese 支持最多256个设备 \~english Support up to 256 devices
}MV_CC_DEVICE_INFO_LIST;
/// \~chinese 设备信息 \~english Device info
typedef struct _MV_CC_DEVICE_INFO_
{unsigned short nMajorVer; ///< [OUT] \~chinese 主要版本 \~english Major Versionunsigned short nMinorVer; ///< [OUT] \~chinese 次要版本 \~english Minor Versionunsigned int nMacAddrHigh; ///< [OUT] \~chinese 高MAC地址 \~english High MAC Addressunsigned int nMacAddrLow; ///< [OUT] \~chinese 低MAC地址 \~english Low MAC Addressunsigned int nTLayerType; ///< [OUT] \~chinese 设备传输层协议类型 \~english Device Transport Layer Protocol Typeunsigned int nReserved[4]; ///< \~chinese 预留 \~english Reservedunion{MV_GIGE_DEVICE_INFO stGigEInfo; ///< [OUT] \~chinese GigE设备信息 \~english GigE Device InfoMV_USB3_DEVICE_INFO stUsb3VInfo; ///< [OUT] \~chinese USB设备信息 \~english USB Device InfoMV_CamL_DEV_INFO stCamLInfo; ///< [OUT] \~chinese CameraLink设备信息 \~english CameraLink Device Info// more ...}SpecialInfo;}MV_CC_DEVICE_INFO;
/// \~chinese GigE设备信息 \~english GigE device info
typedef struct _MV_GIGE_DEVICE_INFO_
{unsigned int nIpCfgOption; ///< [OUT] \~chinese IP配置选项 \~english IP Configuration Optionsunsigned int nIpCfgCurrent; ///< [OUT] \~chinese 当前IP配置 \~english IP Configuration:bit31-static bit30-dhcp bit29-llaunsigned int nCurrentIp; ///< [OUT] \~chinese 当前IP地址 \~english Current Ipunsigned int nCurrentSubNetMask; ///< [OUT] \~chinese 当前子网掩码 \~english Curtent Subnet Maskunsigned int nDefultGateWay; ///< [OUT] \~chinese 当前网关 \~english Current Gatewayunsigned char chManufacturerName[32]; ///< [OUT] \~chinese 制造商名称 \~english Manufacturer Nameunsigned char chModelName[32]; ///< [OUT] \~chinese 型号名称 \~english Model Nameunsigned char chDeviceVersion[32]; ///< [OUT] \~chinese 设备版本 \~english Device Version unsigned char chManufacturerSpecificInfo[48]; ///< [OUT] \~chinese 制造商的具体信息 \~english Manufacturer Specific Informationunsigned char chSerialNumber[16]; ///< [OUT] \~chinese 序列号 \~english Serial Numberunsigned char chUserDefinedName[16]; ///< [OUT] \~chinese 用户自定义名称 \~english User Defined Name unsigned int nNetExport; ///< [OUT] \~chinese 网口IP地址 \~english NetWork IP Addressunsigned int nReserved[4]; ///< \~chinese 预留 \~english Reserved
}MV_GIGE_DEVICE_INFO;
实现方法:
第一步:枚举相机信息:
// ch:枚举设备 | Enum deviceMV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (MV_OK != nRet){printf("Enum Devices fail! nRet [0x%x]\n", nRet);break;}
第二步:根据相机IP大小,从小到大重新排序(如果想根据其他信息排序,if的判断语句就应该做对应修改,例如,改成chUserDefinedName、序列号等)
for (int i = 0; i < psDevlist->nDeviceNum; i++)
{for (int j = 0; j < psDevlist->nDeviceNum-i-1; j++){//USB相机,SpecialInfo.stGigEInfo就需要变成SpecialInfo.stUSBInfo,换成其他设备信息来排序if(psDevlist->pDeviceInfo[j]->SpecialInfo.stGigEInfo.nCurrentIp > psDevlist->pDeviceInfo[j+1]->SpecialInfo.stGigEInfo.nCurrentIp){MV_CC_DEVICE_INFO* temp = psDevlist->pDeviceInfo[j];psDevlist->pDeviceInfo[j]=psDevlist->pDeviceInfo[j+1];psDevlist->pDeviceInfo[j+1]=temp;}}
}
第三步:正常打开就行
完整代码如下:
//------------------根据ip大小修改默认排序-----------------------
int EnumDeviceBycuirentIp(IN unsigned int nTLayerType,IN OUT MV_CC_DEVICE_INFO_LIST*psDevlist)
{int nRet = MV_CC_EnumDevices(nTLayerType,psDevlist);if (MV_OK != nRet){printf("Enum Devices fail! nRet [0x%x]\n", nRet);return nRet;}for (int i = 0; i < psDevlist->nDeviceNum; i++){for (int j = 0; j < psDevlist->nDeviceNum-i-1; j++){if(psDevlist->pDeviceInfo[j]->SpecialInfo.stGigEInfo.nCurrentIp > psDevlist->pDeviceInfo[j+1]->SpecialInfo.stGigEInfo.nCurrentIp){MV_CC_DEVICE_INFO* temp = psDevlist->pDeviceInfo[j];psDevlist->pDeviceInfo[j]=psDevlist->pDeviceInfo[j+1];psDevlist->pDeviceInfo[j+1]=temp;}}}return nRet;
}
//-------------------主函数部分----------------------------------// ch:枚举设备 | en:Enum deviceMV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));unsigned int nTLayerType=MV_GIGE_DEVICE;MV_CC_DEVICE_INFO_LIST *psDevlist;nRet = EnumDeviceBycuirentIp(nTLayerType,&stDeviceList);if (MV_OK != nRet){printf("Enum Devices fail! nRet [0x%x]\n", nRet);return nRet;}if (stDeviceList.nDeviceNum > 0){for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++){printf("[device %d]:\n", i);MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];if (NULL == pDeviceInfo){break;} PrintDeviceInfo(pDeviceInfo); } } else{printf("Find No Devices!\n");break;}
- 方法2:根据相机序列号或自定义名称指定打开相机
前面讲了,我们可以根据相机信息结构体中设备信息,重新修改排序,那么应该可以做一个简单的循环,比对信息来打开我指定的相机,如下,指定打开一个命名叫“CCDName”的相机
实现方法:
int nRet = 0;char* ccdName={"CCDName"};int nDeviceNum = -1;unsigned int VersionSDK = MV_CC_GetSDKVersion();MV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (MV_OK != nRet){printf("MV_CC_EnumDevices fail! nRet %x\n", nRet);return nRet;}if (stDeviceList.nDeviceNum < 0){return -1;}for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++){if (stDeviceList.pDeviceInfo[i]->nTLayerType == MV_GIGE_DEVICE){if (strcmp((const char*)stDeviceList.pDeviceInfo[i]->SpecialInfo.stGigEInfo.chUserDefinedName, ccdName)==0){nDeviceNum = i;printf("Gige_devicen_nDeviceNum %d\n", nDeviceNum);}}else if (stDeviceList.pDeviceInfo[i]->nTLayerType == MV_USB_DEVICE){if (strcmp((const char*)stDeviceList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chUserDefinedName, ccdName)==0){nDeviceNum = i;printf("USB_devicen_DeviceNum %d\n", nDeviceNum);}}continue;}if (nDeviceNum < 0){return -1;}nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nDeviceNum]);if (MV_OK != nRet){printf("Camera;%s->MV_CC_CreateHandle fail! nRet %x\n", ccdName, nRet);return nRet;}nRet = MV_CC_OpenDevice(handle);if (MV_OK != nRet){printf("Camera;%s->MV_CC_OpenDevice fail! nRet %x\n",ccdName,nRet);return nRet;}
方法3:根据指定的ip地址,打开固定ip的相机
既然我们对相机信息结构体有了一定了解,那么为啥不能自己向里面填充信息呢
下面的代码就是自己填写ip地址,打开固定ip地址的相机,用这种方法呢,可以跳过枚举接口,直接获取信息创建句柄
//指定网卡ip,相机ip打开相机,需注意,不要写错ip地址,否则会报错206问题int nRet = 0;int nDeviceNum = -1;MV_CC_DEVICE_INFO stDevInfo = { 0 };MV_GIGE_DEVICE_INFO stGigEDev = { 0 };stGigEDev.nNetExport = 0x0a403951;//网卡ip地址 10.64.57.81stGigEDev.nCurrentIp = 0x0a40395b;//相机ip地址 10.64.57.91stDevInfo.nTLayerType = MV_GIGE_DEVICE;// ch:仅支持GigE相机 | en:Only support GigE camerastDevInfo.SpecialInfo.stGigEInfo = stGigEDev;nRet = MV_CC_CreateHandle(&handle, &stDevInfo);if (MV_OK != nRet){printf("MV_CC_CreateHandle fail! nRet [%x]\n", nRet);return -1;}nRet = MV_CC_GetDeviceInfo(handle, &stDevInfo);//补全设备信息if (nRet != MV_OK){MV_CC_DestroyHandle(handle);handle = NULL;return false;}nRet = MV_CC_OpenDevice(handle);if (MV_OK != nRet){printf("MV_CC_OpenDevice fail! nRet %x\n", nRet);return nRet;}
以上三种方法,实测可行,如果有更多的方法与思路,可以评论交流
工业相机如何调整SDK枚举顺序或者打开顺序相关推荐
- 输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。
输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分. 我们首先会想到常规方法:创建一个临时数组,遍历所给数组中的所有元素,将偶数 ...
- 奇数位于偶数之前:调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。 如数组:[1,2,3,4,5,6] 调整后可能是:[1, 5, 3, 4, 2, 6]
目录 问题描述: 问题分析: 代码实现: 问题描述: 奇数位于偶数之前 调整数组顺序使得奇数位于偶数之前.调整之后,不关心大小顺序. 如数组:[1,2,3,4,5,6] 调整后可能是:[1, 5, 3 ...
- 调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。
调整数组顺序使得奇数位于偶数之前.调整之后,不关心大小顺序. 如数组:[1,2,3,4,5,6] 调整后可能是:[1, 5, 3, 4, 2, 6] 思路:1.i遇到偶数停止 2. j遇到奇数停止 3 ...
- RxJava2.x是一个非常棒的流式编程,采用的观察者模式思想,事件的产生者产生事间之后发送给绑定的接受者,接受顺序与发送顺序一致.但是 是独立于RxJava1.x存在,本文讲解RxJava2.x的简
RxJava2.x是一个非常棒的流式编程,采用的观察者模式思想,事件的产生者产生事间之后发送给绑定的接受者,接受顺序与发送顺序一致.但是 是独立于RxJava1.x存在,本文讲解RxJava2.x的简 ...
- C++中对象的构造顺序和析构顺序
文章目录 1 C++中单个对象的构造和析构顺序 1.1 单个对象的构造和析构顺序 2 C++中多个对象的构造和析构顺序 2.1 局部对象的构造顺序 2.2 堆对象的构造顺序 2.3 全局对象的构造顺序 ...
- 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...
还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...
- Java黑皮书课后题第7章:7.2(倒置输入的数)编写程序,读取10个整数,然后按照和读入顺序相反的顺序将它们显示出来
7.2(倒置输入的数)编写程序,读取10个整数,然后按照和读入顺序相反的顺序将它们显示出来 题目 题目描述 破题 代码 运行示例 题目 题目描述 7.2(倒置输入的数)编写程序,读取10个整数,然后按 ...
- 【C++深度剖析教程1】C++中的经典问题解析-c++中的对象的构造顺序与析构顺序
c++中的对象的构造顺序与析构顺序 问题一 当程序中存在多个对象时,如何确定这些对象的析构顺序? 一.单个函数创建时构造函数的调用顺序 1.调用父类的构造过程 2.调用成员变量的构造函数(调用顺序与声 ...
- mysql命令书写顺序_MySQL SQL语句书写顺序和执行顺序
SQL语句书写顺序和执行顺序 (7) SELECT (8) DISTINCT (1) FROM (3) JOIN (2) ON (4) WHERE (5) GROUP BY (6) HAVING (9 ...
最新文章
- python判断密码是否正确_第一个python程序-判断登陆用户名和密码是否正确
- Python之多线程
- JQuery实现Ajax功能
- Linux环境下提升普通用户权限(sudo)
- Boost:bind绑定和数据成员的测试程序
- 神经网络中Batch和Epoch之间的区别
- Machine Learning - Coursera week5 cost function and backpropagation 1
- 循环队列(java)
- Spring使用Cache、整合Ehcache
- 大学计算机专业绩点在3.5算好,大学绩点3.5算什么水平 绩点低有哪些补救方法...
- asp提交数据500服务器错误信息,windows2003运行ASP发送HTTP 500 - 内部服务器错误怎么处理啊?...
- 无法安装Visual Studio 2010 Service Pack 1
- 【8】电压比较器的阈值,窗口电压
- 拉格朗日乘数法,一种计算条件极值的方式
- i78700和i78700k区别 i7 8700和i7 8700k 参数对比差多少
- qt - the inferior stopped because it received a signal from the operation system.
- nargin与varargin的用法
- iOS bounds备忘
- w10计算机管理员权限在哪里设置密码,Win10使用管理员权限需要PIN密码的设置方法 三种解决方法...
- 北京最大耐克体验店开业;HH中国首家旗舰店在上海开业 | 美通社头条