IDS Cameras: Get Properties and Information
Introduction
I came into possession of a couple of older model IDS cameras and proceeded to learn how to code and deploy them using one of IDS arm64 api’s together with opencv and gstreamer. In the process of doing this, I found it useful to understand the properties and features of these two particular models in a way that goes beyond simply reading their data sheets. I present here the code of a C++ program that does this.
Preliminaries
IDS cameras are not UVC cameras even though they interface USB 3.0. Therefore, the kernels of machines running Linux operating systems do not have the support to operate them without the drivers provided by IDS.
The two machines upon which the IDS api was installed were a Raspberry Pi 5 and a Jetson Nano, both of which run a version of Ubuntu. The particular installation of deb files used in shown in the following directory:
ueye_4.96.1.2054_arm64.deb
ueye_4.96.1.2054_arm64.deb.tar*
ueye-api_4.96.1.2054_arm64.deb
ueye-common_4.96.1.2054_arm64.deb
ueye-demos_4.96.1.2054_arm64.deb
ueye-dev_4.96.1.2054_arm64.deb
ueye-driver-eth_4.96.1.2054_arm64.deb
ueye-drivers_4.96.1.2054_arm64.deb
ueye-driver-usb_4.96.1.2054_arm64.deb
ueye-interfaces-halcon_4.96.1.2054_arm64.deb
ueye-manual-de_4.96.1.2054_arm64.deb
ueye-manual-en_4.96.1.2054_arm64.deb
ueye-manuals_4.96.1.2054_arm64.deb
ueye-tools-cli_4.96.1.2054_arm64.deb
ueye-tools-qt5_4.96.1.2054_arm64.deb
There is some interdependence so the installation of the deb files should be done in the order they are arranged in the directory.
When building the C++ program the configuration needs to specify the include file as well as the api library.
-I /opt/ids/ueye/include
and
-L /opt/ids/ueye/lib/aarch64-linux-gnu/libueye_api.so
The Main Code
Here is the complete file.
#include <iostream>
#include <bitset>
#include <string>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include "ueye.h"
using namespace std;
//When color mode changes this value may change. Is determined in
//initialization, and then used in get frames to allocate memory.
static INT pixdepth = 0;
/*U3-3270CP-C-HQ REV.2.2(AB12784)
static INT max_width = 2064;
static INT max_height = 1544;
*/
/*U1-3270LE-C-HQ (AB00904)*/
static INT max_width = 2056;
static INT max_height = 1542;
CAMINFO info;
void initializeCameraInterface(HIDS* hCam_internal){
// Open cam and see if it was succesfull
INT nRet = is_InitCamera (hCam_internal, NULL);
if (nRet == IS_SUCCESS){
cout << "Camera initialized!" << endl;
}else{
cout << "error = " << nRet << endl;
}
// Setting the pixel clock to retrieve data
UINT nPixelClockDefault = 21;
nRet = is_PixelClock(*hCam_internal, IS_PIXELCLOCK_CMD_SET, (void*)&nPixelClockDefault, sizeof(nPixelClockDefault));
if (nRet == IS_SUCCESS){
cout << "Camera pixel clock succesfully set!" << endl;
}else if(nRet == IS_NOT_SUPPORTED){
cout << "Camera pixel clock setting is not supported!" << endl;
}
// Set the color mode of the camera
// INT colorMode = IS_CM_MONO8; //IS_CM_BGR8_PACKED, IS_CM_JPEG
INT colorMode = IS_CM_BGR8_PACKED;
nRet = is_SetColorMode(*hCam_internal,colorMode);
if (nRet == IS_SUCCESS){
cout << "Camera color mode succesfully set!" << endl;
}
//now obtain the pixel depth of the color mode.
nRet = is_SetColorMode(*hCam_internal, IS_GET_BITS_PER_PIXEL);
cout << "bits per pixel = " << nRet << endl;
pixdepth = nRet;
nRet = is_SetColorConverter (*hCam_internal, IS_CM_BGR8_PACKED, IS_CONV_MODE_SOFTWARE_3X3);
if (nRet == IS_SUCCESS){
cout << "Camera color converter succesfully set!" << endl;
}
// Store image in camera memory --> option to chose data capture method
// Then access that memory to retrieve the data
INT displayMode = IS_SET_DM_DIB;
// INT displayMode = IS_SET_DM_OPENGL; //returns IS_NOT_SUPPORTED
nRet = is_SetDisplayMode (*hCam_internal, displayMode);
cout << "display mode return = " << nRet << endl;
//Enable auto gain control:
double dEnable = 1;
int ret = is_SetAutoParameter (*hCam_internal, IS_SET_ENABLE_AUTO_GAIN, &dEnable, 0);
//Set brightness setpoint to 128:
double nominal = 128;
ret = is_SetAutoParameter (*hCam_internal, IS_SET_AUTO_REFERENCE, &nominal, 0);
//Return shutter control limit:
double maxShutter;
ret = is_SetAutoParameter (*hCam_internal, IS_GET_AUTO_SHUTTER_MAX, &maxShutter, 0);
}
void get_type(unsigned char type);
int main()
{
// ---------------------------------------------------------------------------------------------------------------
// START BY CONFIGURING THE INTERFACE WITH THE UEYE CAMERA
// ---------------------------------------------------------------------------------------------------------------
// Camera initialisation
// Index 0 means taking the first camera available
HIDS hCam = 0;
initializeCameraInterface(&hCam);
//get camera info
printf("\n");
int ret = is_GetCameraInfo(hCam, &info);
if (ret == IS_SUCCESS){
cout << "Camera Info" << endl;
}else{
cout << "got cam info error : " << ret << endl;
}
int len = sizeof(info);
cout << "size of info struct is: " << len << endl;
cout << "serial no. " << info.SerNo << endl;
cout << "ID : " << info.ID << endl;
cout << "Date : " << info.Date << endl;
cout << "select : " << info.Select << endl;
cout << "version : " << info.Version << endl;
cout << "Type coded : " << info.Type << endl;
cout << "Type decoded : " << endl;
get_type(info.Type);
printf("\n");
// At least one camera must be available
INT nNumCam;
if( is_GetNumberOfCameras( &nNumCam ) == IS_SUCCESS) {
if( nNumCam >= 1 ) {
// Create new list with suitable size
UEYE_CAMERA_LIST* pucl;
pucl = (UEYE_CAMERA_LIST*) new BYTE [sizeof (DWORD) + nNumCam * sizeof (UEYE_CAMERA_INFO)];
pucl->dwCount = nNumCam;
//Retrieve camera info
if (is_GetCameraList(pucl) == IS_SUCCESS) {
int iCamera;
for (iCamera = 0; iCamera < (int)pucl->dwCount; iCamera++) {
//Test output of camera info on the screen
printf("Camera %i Id: %d\n", iCamera,
pucl->uci[iCamera].dwCameraID);
printf("Camera full model name %s\n",
pucl->uci[iCamera].FullModelName);
}
}
delete [] pucl;
}
}
printf("\n");
// get auto info
UEYE_AUTO_INFO auto_info{}; ret = is_GetAutoInfo (hCam, &auto_info);
if ( ret == IS_SUCCESS ){
cout << "Auto Features Info (True if not zero) " << endl;
}else{
cout << "got auto info error :" << ret << endl;
}
cout << "autoability value = " << bitset<12>{static_cast<unsigned long long>(auto_info.AutoAbility)} << endl;
cout << "autoability gain internal: " << (auto_info.AutoAbility & (AC_SENSOR_GAIN | AC_SENSOR_GAIN_SHUTTER)) << endl;
cout << "autoability shutter internal: " << (auto_info.AutoAbility & (AC_SENSOR_SHUTTER | AC_SENSOR_GAIN_SHUTTER)) << endl;
cout << "autoability WB internal: " << (auto_info.AutoAbility & AC_SENSOR_WB) << endl;
cout << "autoability frame rate internal: " << (auto_info.AutoAbility & (AC_SENSOR_FRAMERATE)) << endl;
cout << "autoability gain : " << AC_GAIN << endl;
cout << "autoability Whitebal: " << (auto_info.AutoAbility & (AC_WHITEBAL)) << endl;
cout << "autoaability frame rate: " << (auto_info.AutoAbility & AC_FRAMERATE) << endl;
cout << "autoability shutter: " << (auto_info.AutoAbility & AC_SHUTTER) << endl;
printf("Autoability value in hex = 0x%hhX\n", auto_info.AutoAbility );
printf("\n");
cout << "Definitions of Features (encoded in a binary number) :" << endl;
cout << "AC_SENSOR_WB = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_WB)} << endl;
cout << "AC_SENSOR_FRAMERATE = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_FRAMERATE)} << endl;
cout << "AC_SENSOR_GAIN_SHUTTER = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_GAIN_SHUTTER)} << endl;
cout << "AC_SENSOR_GAIN = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_GAIN)} << endl;
cout << "AC_SENSOR_SHUTTER = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_SHUTTER)} << endl;
cout << "AC_FRAMERATE = " << bitset<12>{static_cast<unsigned long long>(AC_FRAMERATE)} << endl;
cout << "AC_WHITEBAL = " << bitset<12>{static_cast<unsigned long long>(AC_WHITEBAL)} << endl;
cout << "AC_GAIN = " << bitset<12>{static_cast<unsigned long long>(AC_GAIN)} << endl;
cout << "AC_SHUTTER = " << bitset<12>{static_cast<unsigned long long>(AC_SHUTTER)} << endl;
cout << "AC_SENSOR_AUTO_CONTRAST_CORRECTION = " << bitset<12>{static_cast<unsigned long long>(AC_SENSOR_AUTO_CONTRAST_CORRECTION)} << endl;
printf("\n");
SENSORINFO SensInfo;
ret = is_GetSensorInfo ( hCam, &SensInfo);
if ( ret == IS_SUCCESS ){
cout << "Sensor Info " << endl;
}else{
cout << "got sensor info error :" << ret << endl;
}
cout << "sensor name: " << SensInfo.strSensorName << endl;
switch(SensInfo.nColorMode){
case 1:
cout << "IS_COLORMODE_MONOCHROME" << endl;
break;
case 2:
cout << "IS_COLORMODE_BAYER" << endl;
break;
case 4:
cout << "IS_COLORMODE_CBYCRY" << endl;
break;
case 8:
cout << "IS_COLORMODE_JPEG" << endl;
break;
case 0:
cout << "IS_COLORMODE_INVALID" << endl;
break;
default:
cout << "no match" << endl;
}
cout << "Max width = " << SensInfo.nMaxWidth << endl;
cout << "Max height = " << SensInfo.nMaxHeight << endl;
cout << "Has master analog gain? " << SensInfo.bMasterGain << endl;
cout << "Has red analog gain? " << SensInfo.bRGain << endl;
cout << "Has green analog gain? " << SensInfo.bGGain << endl;
cout << "Has blue analog gain? " << SensInfo.bBGain << endl;
cout << "sensor pixel size in um = " << float(SensInfo.wPixelSize)/100. << endl;
switch(SensInfo.bGlobShutter){
case TRUE:
cout << "has global shutter" << endl;
break;
case FALSE:
cout << "has rolling shutter" << endl;
}
cout << SensInfo.nUpperLeftBayerPixel << endl;
switch(SensInfo.nUpperLeftBayerPixel){
case '0':
cout << "color of the first pixel (top left): " << BAYER_PIXEL_RED << endl;
break;
case '1':
cout << "color of the first pixel (top left): " << BAYER_PIXEL_GREEN << endl;
break;
cout << "color of the first pixel (top left): " << BAYER_PIXEL_BLUE << endl;
default:
printf("SensInfo.nUpperLeftBayerPixel value as a hex 0x%hhX \n", SensInfo.nUpperLeftBayerPixel);
cout << "if value is 0x0 means NULL" << endl;
}
printf("\n");
is_ExitCamera(hCam);
return 0;
}
void get_type(unsigned char type){
switch(type){
case IS_CAMERA_TYPE_UEYE_USB3_CP:
cout << "USB 3 uEye CP/USB 3 uEye CP Rev. 2" << endl;
break;
case IS_CAMERA_TYPE_UEYE_USB3_LE:
cout << "USB 3 uEye LE" << endl;
break;
case IS_CAMERA_TYPE_UEYE_USB3_ML:
cout << "USB 3 uEye ML" << endl;
break;
case IS_CAMERA_TYPE_UEYE_USB_LE:
cout << "USB uEye LE/USB uEye LE Rev. 2" << endl;
break;
case IS_CAMERA_TYPE_UEYE_USB_ML:
cout << "USB uEye ML" << endl;
break;
case IS_CAMERA_TYPE_UEYE_USB_SE:
cout << "USB uEye SE" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_CP_R2:
cout << "GigE uEye CP/GigE uEye CP Rev. 2" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_CP:
cout << "GigE uEye CP" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_FA:
cout << "GigE uEye FA" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_LE:
cout << "GigE uEye LE" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_REP:
cout << "GigE uEye RE PoE" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_SE_R4:
cout << "GigE uEye SE Rev. 4" << endl;
break;
case IS_CAMERA_TYPE_UEYE_ETH_SE:
cout << "GigE uEye SE" << endl;
break;
case IS_CAMERA_TYPE_UEYE_PMC:
cout << "Virtual multicast camera" << endl;
break;
default:
cout << "Camera Type not available" << endl;
}
}
It is noted that for all of the api invoked functions to work the camera must be connected and also note that the code also initializes the camera.
Output Example
One of the two models was inspected resulting in this output.
Camera initialized!
Camera color mode succesfully set!
bits per pixel = 24
Camera color converter succesfully set!
display mode return = 0
Camera Info
size of info struct is: 64
serial no. 4103344611
ID : IDS GmbH
Date : 05.07.2018
select :
version :
Type coded : b
Type decoded :
USB 3 uEye LE
Camera 0 Id: 1
Camera full model name UI327xLE-C
Auto Features Info (True if not zero)
autoability value = 000001000111
autoability gain internal: 0
autoability shutter internal: 0
autoability WB internal: 0
autoability frame rate internal: 0
autoability gain : 2
autoability Whitebal: 4
autoaability frame rate: 64
autoability shutter: 1
Autoability value in hex = 0x47
Definitions of Features (encoded in a binary number) :
AC_SENSOR_WB = 100000000000
AC_SENSOR_FRAMERATE = 010000000000
AC_SENSOR_GAIN_SHUTTER = 001000000000
AC_SENSOR_GAIN = 000100000000
AC_SENSOR_SHUTTER = 000010000000
AC_FRAMERATE = 000001000000
AC_WHITEBAL = 000000000100
AC_GAIN = 000000000010
AC_SHUTTER = 000000000001
AC_SENSOR_AUTO_CONTRAST_CORRECTION = 000000000000
Sensor Info
sensor name: UI327xLE-C
IS_COLORMODE_BAYER
Max width = 2056
Max height = 1542
Has master analog gain? 1
Has red analog gain? 1
Has green analog gain? 1
Has blue analog gain? 1
sensor pixel size in um = 3.45
has global shutter
SensInfo.nUpperLeftBayerPixel value as a hex 0x0
if value is 0x0 means NULL
Description of Output
After some initialization information the output consists of three sets of information: camera information, automatic features, and sensor information.
The camera info is mostly encoded in a struct and the program interprets it. As can be seen in the example some fields can be empty.
The automatic features are instead encoded in a binary number. The features are grouped as either sensor internal support or simple support. These features are exposure shutter control, frame rate control, gain control, and white balance control. An non zero output indicates that feature is present. The output shows the encoding of all features (i. e., their definitions).
Finally, the sensor information is printed. In this example the color of the upper left Bayer pixel is not available. This is indicated by the returned value NULL (0x0).
TBD
The auto features list is more extensive than listed here. The next planned step is add code to report the complete set.

Recent Comments