通过VS2017和OpenCV,实现ids工业相机与电控位移台同步控制及数据采集
- 目录
-
- 项目环境配置
- 代码流程及思路
- 项目架构
- 项目开发运行效果
- 开发关键
- ids相机配置
- 位移台环境配置
- 相机头文件
- 相机参数设置
- 保存图像函数设置
- 电控位移台头文件
- 电控位移台设置参数
- 最后就是通过main函数进行调用和控制,需要注意的是,最好能加上sleep函数,这样采集图像不容易出问题
目录
光学数据采集系统中,经常需要采集几万个样本点进行数据分析,如果通过人工数据采集,人工成本太高,同时容易出现测量误差等因素。因此需要根据项目功能开发一套自动化采集图像和位移控制的工程项目,以下是具体内容:
项目环境配置
代码环境:
VS2017
OpenCV3.4.2
ids开发包,包括.lib、.dll、.h文件等
LBtek电控五相位移平台,.dll、.h文件
代码流程及思路
- 相机初始化,根据图像尺寸申请内存地址;
- 导出图像内存指针,设置传感器参数
- 初始化位移台,新建类
- 通过dll查找位移台函数指针,调用函数
- 设置边界条件及步进电机参数
- 通过函数返回值与延时等机制,实现相机同步
- 批量化图像采集与数据处理
项目架构
项目开发运行效果
开发关键
相机和位移台属于商业产品,商家不提供完整程序包,只给出dll动态链接库,需要通过函数指针调用接口。
通过算法自定义位移台运行模式;
提升图像增益及伽马校正,自定义图像采集AOI,提升采集帧率;
ids相机配置
本文是基于debug x64模式下,C++ 环境运行,需要一老OpenCV的部分库函数,进行图像展示和保存。
OpenCV环境配置:具体配置方法CSDN其他博客都有记录,是通用的,
比如我之前配置旧版本的环境,大家可以参考: link
;
大家要注意,将这里的语言 符合模式 设置为否,原因是ids相机开发包里面存储文件的时候,使用的是wchat_t *的格式,调试过程中很容易出问题。如下图设置
相机环境配置完成。
位移台环境配置
由于开发包里面只提供了配置文件、.dll文件、.h文件,函数实现方法是不知道的,因此调用函数的时候是将这三个文件放置到项目代码包中,通过函数指针调用函数,配置说明书摸索函数功能。
这一部分环境配置就是将这几个文件放置到工程项目文件夹中即可。
相机头文件
#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(wchar_t* fileName);
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; // 垂直翻转标志
};
相机参数设置
int SetParasofCamera(HIDS hCam, uint nPixelClockSet, double nFramePerSecondSet, double nExposureTimeSet) {
// 像素时钟查询与设置
UINT nPixelClockDefault, nPixelClockCurrent;
INT nRet;
/*
// 获取默认像素时钟
nRet = is_PixelClock(hCam, IS_PIXELCLOCK_CMD_GET_DEFAULT, (void*)&nPixelClockDefault, sizeof(nPixelClockDefault));
if (nRet == IS_SUCCESS) {
cout << "Success, and default pixel clock is : " << nPixelClockDefault << " MHz." << endl;
}
else {
cout << "Failed to get default pixel clock" << endl;
return IS_NO_SUCCESS;
}
*/
// 设置该像素时钟
//nPixelClockSet = 86; //设置为80MHz
nRet = is_PixelClock(hCam, IS_PIXELCLOCK_CMD_SET, (void*)&nPixelClockSet, sizeof(nPixelClockSet));
if (nRet == IS_SUCCESS) {
cout << "Success, and user set pixel clock is : " << nPixelClockSet << " MHz." << endl;
}
else {
cout << "Failed to set pixel clock" << endl;
return IS_NO_SUCCESS;
}
// 获取当前像素时钟
nRet = is_PixelClock(hCam, IS_PIXELCLOCK_CMD_GET, (void*)&nPixelClockCurrent, sizeof(nPixelClockCurrent));
if (nRet == IS_SUCCESS) {
cout << "Success, and current pixel clock is : " << nPixelClockCurrent << " MHz." << endl;
}
else {
cout << "Failed to get current pixel clock" << endl;
return IS_NO_SUCCESS;
}
cout << "***********************************************************************************" << endl;
/*
// 相机帧率范围查询与设置
double nFrameMin, nFrameMax, nFrameIntervall;
nRet = is_GetFrameTimeRange(hCam, &nFrameMin, &nFrameMax, &nFrameIntervall);
if (nRet == IS_SUCCESS) {
cout << "Success, Min Frame = " << 1 / nFrameMax << "fps, Max Frame = " << 1 / nFrameMin << "fps, and Frame Intervall = " << nFrameIntervall << "fps." << endl;
}
else {
cout << "Failed to get nFrameMin, nFrameMax, nFrameIntervall." << endl;
return IS_NO_SUCCESS;
}
*/
// 设置、并查询 当前相机采集帧率
double nFramesPerSecondCurrent;
nRet = is_SetFrameRate(hCam