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

在开发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 -> ETH
int Type = (pucl->uci[i].dwDeviceID >= 1000); // 网口的ID要+1000

// If ETH camera
if(Type == 1)
{
	// 网口
}
// If USB camera
else if(Type == 0)
{
	// USB
}
所以日了狗了。所以在打开指定相机的时候可以先获取相机数及其各相机的参数,也就是PUEYE_CAMERA_LIST数据结构,然后对其特定信息进行比对(比如SerNo属性),就可以打开对应的相机。完整打开相机的正确姿势如下:

bool open(QString usr_select_serno){ // 用户选择的相机SN号
	
	// 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
		if (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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值