工业相机IDS开发

 

       最近项目中要用到一款IDS的相机,型号是UI-3060CP ,这是一款USB3.0相机。IDS官网提供了不同操作系统的开发包,有相当详细开发说明。注册后便可以下载,链接为:https://en.ids-imaging.com/download-ueye-win32.html

       工业相机IDS开发_第1张图片

         首先下载了windows下的开发包,默认安装后可以正常打相机,然后开始尝试利用vs2010+opencv进行二次开发。

      1.配置环境,ids的软件包默认安装目录为C:\Program Files\IDS\uEye 

      2.新建工程文件并配置链接库,vs2010下配置过程类似于opencv的配置  

           ①【配置属性】 ->【C/C++】 ->【常规】->【附加包含目录】

                     添加路径   C:\Program Files\IDS\uEye\Develop\include;

        ②【链接器】 ->【常规】 ->【附加库目录】中

              添加路径   C:\Program Files\IDS\uEye\Develop\Lib;

        ③链接库的附加依赖项的配置:【链接器】 ->【输入】 ->【附加依赖项】

           添加 

kernel32.lib   user32.lib  gdi32.lib   winspool.lib   comdlg32.lib    advapi32.lib  shell32.lib

ole32.lib   oleaut32.lib  uuid.lib    odbc32.lib  odbccp32.lib  ueye_api.lib

工业相机IDS开发_第2张图片工业相机IDS开发_第3张图片工业相机IDS开发_第4张图片

至此开发环境配置完成。

   3.主体程序部分,相机的使用主要包括以下部分

(1)初始化相机 

      通过 is_InitCamera()函数可以初始化相机,并为相机分配一个唯一的句柄,后续可以通过该句柄来访问相机。

 (2)查询相机信息 

     is_GetCameraList();

     通过is_GetSensorInfo( )函数可以获取相机传感器的信息,根据该信息可以得知相机色彩模式等可以设置的类型。 

 (3)选择显示模式 

             is_SetDisplayMode();

            本款IDS相机有三种模式:Direct3D、OpenGL、位图(DIB)模式

           其中Direct3D仅用于windows系统,opengl需要硬件支持、位图模式支持所有平台并可以直接访问内存。

     由于需要对图像进行访问选择了位图模式,在该模式下需要手动分配内存,并在捕捉图像之前激活内存。

 (4)捕捉图像 

            is_SetExternalTrigger();  

      is_CaptureVideo();

      首先设定相机的预期模式分为自由运行模式和触发模式,在自由运行模式下相机传感器以设定的帧率捕捉一张张图像,并可以连续传送图像。

      选择触发模式时,传感器处于待机状态,收硬件或者软件的触发信号时才开始曝光。

    (5)保存图像     

      is_ImageFile();       

          (6)保存图像    

                         只有在“与设备无关位图”(DIB)显示模式才可以进行AVI录像。

                        AVI 捕捉流程图:先初始化 AVI 接口,然后创建一个空的 AVI 文件并设置相关参数。

       (7)调整相机参数

      •   帧率   is_SetFrameRate() 用于在自由运行模式(实况模式)下设置传感器帧率。  帧率的变化影响曝光时间的设置值范围。
      •  曝光时间  is_Exposure()     用于查询相机支持的曝光时间范围并设置新的曝光时间。
      • 色彩模式  is_SetColorMode()  用于设置显卡在保存或显示图像数据时所使用的色彩模式
      • 色彩校正  is_SetColorCorrection()在彩色相机上, 用于在 uEye 驱动内启用色彩校正。
      • 自动图像控制 is_SetAutoParameter()  用于控制自动增益、曝光快门、帧率和白平衡控制值。
      • 默认值   is_ResetToDefault()          将相机参数重置为默认值。
        (8)关闭相机 

      • 保存参数 is_ParameterSet()  用于将当前相机的参数保存到文件或相机 EEPROM 中,然后从文件或EEPROM中加载参数集。
      • 关闭相机 is_ExitCamera()     用于禁用hCam 相机句柄并释放uEye相机占用的数据结构和内存。

相机会自动释放经is_AllocImageMem() 函数分配的图像内存。所有之前设置的相机参数将会丢失。

      • 下次打开应用程序的时候,只需使用同一函数加载设置即可。
         为方便相机的调用创建了一个Idscam的C++类。

     其头文件如下: 

  

#include "ueye.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

class Idscam{
    
public:
    Idscam();
    INT InitCamera (HIDS *hCam, HWND hWnd);   //初始化相机   hWnd指向显示图像窗口的指针,若用DIB模式可以令hWnd=NULL  
    bool OpenCamera();
    void ExitCamera();
    int  InitDisplayMode(); 
    void GetMaxImageSize(INT *pnSizeX, INT *pnSizeY);//查询相机支持的图像格式
    void SaveImage( );
    bool GetiplImgFormMem(); //从视频数据流中将图像数据拷贝给IplImage
    // uEye varibles
    HIDS	m_hCam;				// 相机句柄
    HWND	m_hWndDisplay;		 // window显示句柄
    INT		m_nColorMode;		// Y8/RGB16/RGB24/REG32
    INT		m_nBitsPerPixel;	// 图像位深
    INT		m_nSizeX;		// 图像宽度
    INT		m_nSizeY;		// 图像高度
    INT		m_nPosX;		// 图像左偏移
    INT		m_nPosY;		// 图像右偏移
    cv::Mat CamMat;
    IplImage *iplImg;
    char *m_pLastBuffer;

private:
    
    // 使用位图模式进行实时显示需要的内存  
    INT	 m_lMemoryId;	        // camera memory - buffer ID
    char*	m_pcImageMemory;	// camera memory - pointer to buffer
    SENSORINFO m_sInfo;		// sensor information struct
    INT     m_nRenderMode;		// render  mode
    INT     m_nFlipHor;		// 水平翻转标志
    INT     m_nFlipVert;		// 垂直翻转标志

};
  对应实现为:

#include"Idscam.h"
#include <string>
#include <iostream>
using namespace std;

Idscam::Idscam(){
	m_pcImageMemory = NULL;
	m_lMemoryId = 0;
	m_hCam = 0;   //初始化相机句柄为0
    m_nRenderMode = IS_RENDER_FIT_TO_WINDOW;  //设置显示模式为适应窗口大小
    m_nPosX = 0;
    m_nPosY = 0;
    m_nFlipHor = 0;
    m_nFlipVert = 0;
    iplImg=cvCreateImageHeader( cvSize(1936,1216),8,4 );
	OpenCamera();		
}

bool Idscam::OpenCamera(){
    INT nRet = IS_NO_SUCCESS;
    ExitCamera();
    
    m_hCam = (HIDS) 0;								    
    nRet = InitCamera(&m_hCam, m_hWndDisplay);  //  1.初始化相机
    
    if (nRet == IS_SUCCESS){   //  打开相机成功
            // 查询相机所用传感器的类型
            is_GetSensorInfo(m_hCam, &m_sInfo);     //2.查询信息
            GetMaxImageSize(&m_nSizeX, &m_nSizeY);
            nRet = InitDisplayMode();             //3.选择显示模式(位图)
    
            if (nRet == IS_SUCCESS)
            {
                // 允许接受消息
                is_EnableMessage(m_hCam, IS_DEVICE_REMOVED, NULL);
                is_EnableMessage(m_hCam, IS_DEVICE_RECONNECTED, NULL);
                is_EnableMessage(m_hCam, IS_FRAME, NULL);
                 is_CaptureVideo( m_hCam, IS_WAIT );   //4.设定捕捉模式:自由运行模式下的实时模式
                 return true;
            }
            else{
              printf("初始化显示模式失败!");
              return false;
            }
        }
    else{
        printf("没有发现uEye相机!");
        return false;
    }
}

void Idscam:: ExitCamera()
{
	if( m_hCam != 0 ) 
	{
		// 调用 hWnd = NULL函数禁用Windows消息
		is_EnableMessage( m_hCam, IS_FRAME, NULL );
		// 在曝光未开始时停止实时模式或取消硬件触发的图像捕捉
		is_StopLiveVideo( m_hCam, IS_WAIT );
		// 释放分配的图像内存
		if( m_pcImageMemory != NULL )
  			is_FreeImageMem( m_hCam, m_pcImageMemory, m_lMemoryId );
		m_pcImageMemory = NULL;
		// 关闭相机
		is_ExitCamera( m_hCam );
        m_hCam = NULL;
	}
}

//1.初始化相机
INT Idscam::InitCamera (HIDS *hCam, HWND hWnd)
{
    INT nRet = is_InitCamera (hCam, hWnd);	
    if (nRet == IS_STARTER_FW_UPLOAD_NEEDED)//相机的启动程序固件和驱动不兼容,需要更新固件版本 
    {
  
        INT nUploadTime = 25000; //默认更新时间为25S
        is_GetDuration (*hCam, IS_STARTER_FW_UPLOAD, &nUploadTime);

        printf("This camera requires a new firmware !\n");
        printf("The upload will take about %f seconds. Please wait ...\n",nUploadTime/1000);

		//再次打开相机并自动更新固件
        *hCam = (HIDS) (((INT)*hCam) | IS_ALLOW_STARTER_FW_UPLOAD); 
        nRet = is_InitCamera (hCam, NULL); 
    }
    printf("初始化相机成功 !\n");
    return nRet;
}


int Idscam::InitDisplayMode()
{
    INT nRet = IS_NO_SUCCESS;
    
    if (m_hCam == NULL)
        return IS_NO_SUCCESS;

    if (m_pcImageMemory != NULL) //释放通过 is_AllocImageMem() 函数分配的图像内存
    { 
        is_FreeImageMem( m_hCam, m_pcImageMemory, m_lMemoryId );
	    //如果图像内存不是通过SDK分配,则需调用 is_FreeImageMem() 函数。否则驱动会继续尝试访问该内存。
       //但是这并不能释放内存。因此,必须确保可再次释放内存。
    }
    m_pcImageMemory = NULL;

	// 设置位图模式
    nRet = is_SetDisplayMode(m_hCam, IS_SET_DM_DIB);

	if (m_sInfo.nColorMode == IS_COLORMODE_BAYER)
    {
		// 如果是拜耳色 则设置位深为当前窗口的设置,linux 下不可以这么设置
		// 用于检索当前Windows桌面的颜色设置并返回每像素位深及相匹配的uEye色彩模式
        is_GetColorDepth(m_hCam, &m_nBitsPerPixel, &m_nColorMode);
    }
    else if (m_sInfo.nColorMode == IS_COLORMODE_CBYCRY)
    {
        m_nColorMode = IS_CM_BGRA8_PACKED;
        m_nBitsPerPixel = 32;
    }
    else
    {
        m_nColorMode = IS_CM_MONO8;
        m_nBitsPerPixel = 8;
    }

    // 分配图像内存,图像尺寸有 m_nSizeX和m_nSizeY确定,色彩位深由m_nBitsPerPixel确定,m_pcImageMemory返回起始地址,m_lMemoryId 返回已分配内存的ID
    if (is_AllocImageMem(m_hCam, m_nSizeX, m_nSizeY, m_nBitsPerPixel, &m_pcImageMemory, &m_lMemoryId ) != IS_SUCCESS)
    {
       		printf("相机内存分配出错!");
    }
    else
        is_SetImageMem( m_hCam, m_pcImageMemory, m_lMemoryId );
	/*    INT is_SetImageMem (HIDS hCam, char* pcImgMem, INT id)用于将指定的图像内存变为活动内存。
			只有活动图像内存可以接收图像数据。
		在调用 is_FreezeVideo() 时,捕捉的图像会存储在 pcImgMem 和 id 指定的图像缓冲区中。
		捕捉的图像会存储在 pcImgMem 和 id 指定的图像缓冲区中。对于 pcImgMem,
		您必须传递 is_AllocImageMem() 创建的指针,传递任何其他指针均会发出错误信息。
		您可以多次传递同样的指针。     */

    if (nRet == IS_SUCCESS)
    {
        // 设置显卡在保存或显示图像数据时所使用的色彩模
        is_SetColorMode(m_hCam, m_nColorMode);

        // set the image size to capture
        IS_SIZE_2D imageSize;
        imageSize.s32Width = m_nSizeX;
        imageSize.s32Height = m_nSizeY;
       //设置图像感兴趣区域(AOI)的大小和位置
        is_AOI(m_hCam, IS_AOI_IMAGE_SET_SIZE, (void*)&imageSize, sizeof(imageSize));
    }   

    return nRet;
}

void Idscam::GetMaxImageSize(INT *pnSizeX, INT *pnSizeY)
{
    INT nAOISupported = 0;
    BOOL bAOISupported = TRUE;
    if (is_ImageFormat(m_hCam,
                       IMGFRMT_CMD_GET_ARBITRARY_AOI_SUPPORTED, 
                       (void*)&nAOISupported, 
                       sizeof(nAOISupported)) == IS_SUCCESS)
    {
        bAOISupported = (nAOISupported != 0);
    }

    if (bAOISupported)
    {  
        // All other sensors
        // Get maximum image size
	    SENSORINFO sInfo;
	    is_GetSensorInfo (m_hCam, &sInfo);
	    *pnSizeX = sInfo.nMaxWidth;
	    *pnSizeY = sInfo.nMaxHeight;
    }
    else
    {
        // Only ueye xs
		// Get image size of the current format
		IS_SIZE_2D imageSize;
		is_AOI(m_hCam, IS_AOI_IMAGE_GET_SIZE, (void*)&imageSize, sizeof(imageSize));

		*pnSizeX = imageSize.s32Width;
		*pnSizeY = imageSize.s32Height;
    }
}
bool Idscam::GetiplImgFormMem(){  //实时获取图像时需要不断刷新此函数

 if(!m_hCam) return false;
  char *pLast = NULL, *pMem = NULL;
  INT dummy = 0;
  //确定当前用于捕捉图像的图像内存 pMem,最后一个用于捕捉图像的图像内存pLast
  is_GetActSeqBuf (m_hCam, &dummy, &pMem, &pLast);
  m_pLastBuffer = pLast;

   if (m_pLastBuffer)
	{
		iplImg->imageData = m_pLastBuffer;  //将图像首地址传给iplImg
		return true;
	}
   else
	   return false;
}

void Idscam::SaveImage( ){
	IMAGE_FILE_PARAMS ImageFileParams;
 
	ImageFileParams.pwchFileName = NULL;
	ImageFileParams.pnImageID = NULL;
	ImageFileParams.ppcImageMem = NULL;
	ImageFileParams.nQuality = 0;
 
	ImageFileParams.nFileType = IS_IMG_BMP;
	INT nRet = is_ImageFile(m_hCam, IS_IMAGE_FILE_CMD_SAVE, (void*)&ImageFileParams,
						   sizeof(ImageFileParams));
 
	//保存活动内存中的jpeg图像,图像画质为100
	ImageFileParams.pwchFileName = L"CamIds.jpg";
	ImageFileParams.nFileType = IS_IMG_JPG; //待保存文件的类型
	ImageFileParams.nQuality = 100;  //100为最佳图像画质(无压缩)
	nRet = is_ImageFile(m_hCam, IS_IMAGE_FILE_CMD_SAVE, (void*)&ImageFileParams,
					   sizeof(ImageFileParams));

}

  在主程序中创建一个Idscam类,默认初始化会直接打开相机,调用函数GetiplImgFormMem()和变量iplImg即可得到相机获取的图片。

      这里并没有创建线程一直刷新相机,所以获取只能获取初始捕捉到的画面。

      主程序为:

#include <cv.h>
#include <highgui.h>
#include"Idscam.h"
char* window_name = "Source Video";

int main()
{  
	Idscam *mycam;
	mycam = new Idscam();
	if(mycam->GetiplImgFormMem())
        cvShowImage(window_name,mycam->iplImg);
	cvWaitKey(3000);
	return 0;

}
  成功打开相机并得到相机画面。

工业相机IDS开发_第5张图片

   

  由于项目环境是linux,故对windows下的开发并未做过多研究。








你可能感兴趣的:(工业相机IDS开发)