首页 > 编程知识 正文

IDS-uEye相机SDK实现多相机功能

时间:2023-05-04 12:42:46 阅读:278454 作者:3952

在开发IDS-ueye多相机程序的时候发现了一个郁闷的问题,就是官方提供的SDK中打开相机的API咋一看不能指定打开哪个相机,其API原型如下所示:

IDSEXP is_InitCamera (HIDS* phCam, HWND hWnd);看这个打开相机的API,很显然,如果想指定其打开某个特定的相机,其输入参数只能是HIDS* phCam,然而联系官方提供的demo源码上下文会发现phCam这个值并不是我们指定的,而是传入initCamera函数后底层自动返回的一个数。代码段如下所示:

m_hCam = (HIDS)0;nRet = initCamera(&m_hCam, m_hWndDisplay);HIDS是int的重定义,很显然通过取地址,m_hCam是个输出类型的参数。所以这个就比较郁闷了,现在接了好几个相机,如何才能指定打开哪个相机呢···后来,经过一番的郁闷,发现了解决方案。在浏览多相机demo的时候发现了一个猫腻。代码如下:

m_Camera.hCam = ((HIDS)(GetDocument()->m_nCamDevID | IS_USE_DEVICE_ID)); nRet = InitCamera(&m_Camera.hCam, m_hWnd);这个时候初始化HIDS m_Camera.hCam的时候并不是用0来初始化,难道这个参数可以用来指定打开哪个相机么···,可是我也试过将这个参数初始化为1或者2或者3,都无济于事啊!那到底是什么原因捏(注:GetDocument()->m_nCamDevID 是MFC界面上用户选择后的控件文本)。后来在另一处发现了这个值要怎么指定···。这边有一个数据结构PUEYE_CAMERA_LIST,如下所示:

typedef struct _UEYE_CAMERA_LIST{ ULONG dwCount; UEYE_CAMERA_INFO uci[1];}UEYE_CAMERA_LIST, *PUEYE_CAMERA_LIST;typedef struct _UEYE_CAMERA_INFO{ DWORD dwCameraID; /*<! brief this is the user definable camera ID */ DWORD dwDeviceID; /*<! brief this is the systems enumeration ID */ DWORD dwSensorID; /*<! brief this is the sensor ID e.g. IS_SENSOR_UI141X_M */ DWORD dwInUse; /*<! brief flag, indicates whether the camera is in use or not */ IS_CHAR SerNo[16]; /*<! brief zero terminated serial number string */ IS_CHAR Model[16]; /*<! brief zero terminated short model name string */ DWORD dwStatus; /*<! brief various flags with camera status */ DWORD dwReserved[2]; /*<! brief reserved */ IS_CHAR FullModelName[32]; /*<! brief zero terminated full model name string, note Use this string for display purpose only! Do not depend on the contents of this string! */ DWORD dwReserved2[5]; /*<! brief reserved */}UEYE_CAMERA_INFO, *PUEYE_CAMERA_INFO;经过下面的这一段代码会发现GetDocument()->m_nCamDevID的值其实就是dwDeviceID。代码如下:
// first request number of cameras to determine the array size int nCameraCount = 0; // get number of cameras if (is_GetNumberOfCameras(&nCameraCount) == IS_SUCCESS) { // allocate the required list size PUEYE_CAMERA_LIST pucl = (PUEYE_CAMERA_LIST)new char[sizeof(DWORD) + nCameraCount * sizeof(UEYE_CAMERA_INFO)]; pucl->dwCount = nCameraCount; // receive the camera list // receive the camera list if(is_GetCameraList(pucl) == IS_SUCCESS) { for(int i = 0; i < nCameraCount; i++) { int ix = 1; int icon = 0; // Type = 0 -> USB, Type = 1 -> ETH int Type = (pucl->uci[i].dwDeviceID >= 1000); // If ETH camera if(Type == 1) { // If device is not used if(pucl->uci[i].dwInUse == 0) { // Check if starter firmware is compatible to the driver (Only SE) if((pucl->uci[i].dwStatus & DEVSTS_INCLUDED_STARTER_FIRMWARE_INCOMPATIBLE) != 0) { icon = 8; strTemp = L"Yes"; } else { icon = 3; strTemp = L"Yes"; } } else { icon = 4; strTemp = L"No"; } m_ctrlCameras.InsertItem( i, strTemp, icon); m_ctrlCameras.SetItemText( i, ix++, L"ETH"); } // If USB camera else if(Type == 0) { bool FirmwareDownloadSupported = (pucl->uci[i].dwStatus & FIRMWARE_DOWNLOAD_NOT_SUPPORTED) == 0; bool InterfaceSpeedSupported = (pucl->uci[i].dwStatus & INTERFACE_SPEED_NOT_SUPPORTED) == 0; // If device is not used if(pucl->uci[i].dwInUse == 0) { if(FirmwareDownloadSupported && InterfaceSpeedSupported) { icon = 0; strTemp = L"Yes"; } else { icon = 1; strTemp = L"No"; } } else { icon = 1; strTemp = L"No"; } m_ctrlCameras.InsertItem( i, strTemp, icon); m_ctrlCameras.SetItemText( i, ix++, L"USB"); } // Camera ID strTemp.Format(L"%d", pucl->uci[i].dwCameraID ); m_ctrlCameras.SetItemText( i, ix++, strTemp); // Device ID strTemp.Format(L"%d", pucl->uci[i].dwDeviceID ); m_ctrlCameras.SetItemText( i, ix++, strTemp); // Model WCHAR temp[100]; mbstowcs(temp, pucl->uci[i].Model, 100); strTemp.Format(L"%s", temp); m_ctrlCameras.SetItemText( i, ix++, strTemp); // Serial Number mbstowcs(temp, pucl->uci[i].SerNo, 100); strTemp.Format(L"%s", temp); m_ctrlCameras.SetItemText( i, ix++, strTemp); // Firmware compatibility if((pucl->uci[i].dwStatus & DEVSTS_INCLUDED_STARTER_FIRMWARE_INCOMPATIBLE) != 0) { m_ctrlCameras.SetItemText(i, ix++, L"1"); } else { m_ctrlCameras.SetItemText(i, ix++, L"0"); } // set data to the device ID m_ctrlCameras.SetItemData(i, pucl->uci[i].dwDeviceID); } } else { strTemp = L"Could not receive camera list"; AfxMessageBox(strTemp); } /* free allocated memory */ delete pucl; } else { strTemp = L"Could not receive camera count"; AfxMessageBox(strTemp); }

通过上面那段代码还会发现为什么我初始化HIDS m_Cam为0或者1,2的时候还是会打开错误,因为我用的是IDS的网口相机,所对应的m_Cam这个值必须加上1000,也就是要指定为1000,1001或者1002,证据如下:

// Type = 0 -> USB, Type = 1 -> ETHint Type = (pucl->uci[i].dwDeviceID >= 1000); // 网口的ID要+1000// If ETH cameraif(Type == 1){// 网口}// If USB cameraelse if(Type == 0){// USB}所以日了狗了。所以在打开指定相机的时候可以先获取相机数及其各相机的参数,也就是PUEYE_CAMERA_LIST数据结构,然后对其特定信息进行比对(比如SerNo属性),就可以打开对应的相机。完整打开相机的正确姿势如下:

bool open(QString usr_select_serno){ // 用户选择的相机SN号// first request number of cameras to determine the array sizeint nCameraCount = 0;// get number of camerasif (is_GetNumberOfCameras(&nCameraCount) == IS_SUCCESS){// allocate the required list sizePUEYE_CAMERA_LIST pucl = (PUEYE_CAMERA_LIST)new char[sizeof(DWORD) + nCameraCount * sizeof(UEYE_CAMERA_INFO)];pucl->dwCount = nCameraCount;// receive the camera listif (is_GetCameraList(pucl) == IS_SUCCESS) return true;else return false;}else{return false;}int usr_select_index = -1;for (int i = 0; i < pucl->dwCount; i++){QString SerNo = QString(pucl->uci[i].SerNo);if (SerNo == usr_select_serno){// 相机SN等于用户选择的相机SN,即打开对应的相机。usr_select_index = i;}}// init camera (open next available camera)m_hCam = (HIDS)pucl->uci[usr_select_index].dwDeviceID | IS_USE_DEVICE_ID;int nRet = initCamera(&m_hCam, NULL);if (nRet == IS_SUCCESS) return true;else return false;}OK,大功告成(注:界面用Qt做的,所以用QString)。





版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。