目录
7.4 MdigGrab(MilDigitizer, MilImage)
7.5 MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem,&MilDisplay, &MilDigitizer, &MilImage);
7.6 MdigGrabContinuous(MilDigitizer, MilImage)
7.7 MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage)
7.8 MbufClear(MilImageDisp, 0x0)
7.9 MdispSelect(MilDisplay, MilImageDisp)
7.10 MdigControl(MilDigitizer, M_GRAB_SCALE, GrabScale)
7.11 MdigInquire(MilDigitizer, M_SIZE_X,&BufSizeX)
参考链接:
一、软硬件介绍
Basler spL4096-140km Camera Link 相机
Basler相机
图像采集卡
软件运行平台是Win7 64位电脑,Qt版本是msvc2015 64位 Debug版本。
二、Qt中导入MIL库
需要注意的是,如果你没有购买MIL库,会报错提示。
导入步骤:
将MIL库放在工程目录下,并在pro文件中写入如下代码。
#依赖freeglut库以及头文件
INCLUDEPATH += $$PWD/MIL/Include
LIBS += -L$$PWD/MIL/LIB -lMil
使用时,在文件中添加如下代码。
#pragma comment(lib, "mil.lib")
#include <mil.h>
三、相机的默认配置,DCF文件的使用
对相机采集卡的设置在dcf文件中,当程序在初始化各种内存时使用默认时,是按照默认dcf文件进行初始化的。
//分配默认的应用、系统
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, &MilDigitizer, &MilImage);
上面的这句代码,按照默认DCF文件来初始化了应用,系统,相机和图像BUFFER,没有初始化显示器。
注意:如果没有软件配置默认的DCF文件,就会出现即使没有开启相机依然能采到如下图像的情况。这个图像在连续采集的时候,会不断向左移动,亮度从暗到亮不断刷新。
***正确的方法是在MIL Config软件中,配置默认的DCF文件
如下面两张图所示,第一张图是MIL Config的入口(左下角第一行的蓝色字体);第二张图是配置默认的DCF文件(先用官方软件配置好需要用的DCF文件)
四、MIL和Qt之间的数据转换
4.1 MIL_INT转Int
MIL_INT BufSizeX=0;
MIL_INT BufSizeY=0;
//获得相机图像的宽度和高度
MdigInquire(MilDigitizer, M_SIZE_X,&BufSizeX);
MdigInquire(MilDigitizer, M_SIZE_Y,&BufSizeY);
//MIL_INT转换为Int类型,并在Qt的控件中显示
int tempintx=BufSizeX;
int tempinty=BufSizeY;
QString tempstr="图像的宽和高:";
tempstr=tempstr+QString::number(tempintx)+" "+QString::number(tempinty);
ui->DebugText->append(tempstr);
4.2 QString转MIL中的TEXT
//保存图像
ui->DebugText->append("保存第"+QString::number(index)+"张图像");
QString savepath=ui->lineEdit->text();
savepath=savepath.append("/"+QString::number(index));
savepath=savepath.append(".tif");
const wchar_t* savepath_wchar = reinterpret_cast<const wchar_t *>(savepath.utf16());
MbufSave(savepath_wchar,MilImage);
4.3 获取相机采集的图像
//图像数据地址
void *SrcImageDataPtr = NULL;
void *PhysicsImagePtr = NULL;
//相机图像的属性信息
MIL_INT SrcImageDataSize=0;
MIL_INT BufSizeX=0;
MIL_INT BufSizeY=0;
//定义图像格式
QImage::Format format = QImage::Format_Indexed8;
int m_iWidth=BufSizeX;
int m_iHeight=BufSizeY;
//定义QImage对象
QImage img = QImage(m_iWidth,m_iHeight,format);//后面设置为定值
//获取相机图像Buffer中的图像信息
MbufInquire(MilImage, M_HOST_ADDRESS, &SrcImageDataPtr);//数据指针
MbufInquire(MilImage,M_PHYSICAL_ADDRESS,&PhysicsImagePtr);//数据物理地址指针,仅供主线意外的
MbufInquire(MilImage, M_SIZE_BYTE, &SrcImageDataSize);//数据大小
MbufInquire(MilImage,M_SIZE_X,&BufSizeX);
MbufInquire(MilImage,M_SIZE_Y,&BufSizeY);
//将图像数据拷贝到QImage中
memcpy(img.bits(),SrcImageDataPtr,SrcImageDataSize);
4.4 程序运行时间计时器
//抓取图像数量指示
MIL_DOUBLE Time = 0.0;//运行总时间
//重置计时器
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS, M_NULL);
//记录时间,计算帧率
MappTimer(M_DEFAULT, M_TIMER_READ + M_SYNCHRONOUS, &Time);//记录当前运行时间
double temprate=Framecount / Time;//计算每秒触发采集多少张图片
ui->lineEdit_FrameRate->setText(QString::number(temprate,10,4));//在主页面显示帧率
4.5 存储图片到硬盘
//保存图像
//定义保存图片的路径和名称
QString savepath2="D:\\output_image";
savepath2=savepath2.append("/"+QString::number(num*10000+n*100+i));
savepath2=savepath2.append(".tif");
//将路径和名称转换为MIL的字符串类型
const wchar_t* savepath_wchar = reinterpret_cast<const wchar_t *>(savepath2.utf16());
//将MilImage[n*100+i]保存在路径下
MbufSave(savepath_wchar,MilImage[n*100+i]);
savepath2.clear();
五 连续采集图像,并在MIL自带显示器上显示
只要移植MIL库正确,只需要如下两句,即可显示实时图像
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay,&MilDigitizer, &MilImageDisp);
MdigGrabContinuous(MilDigitizer, MilImageDisp);
六 外部电压触发采集,方波
例子:一般100KHz的方波输入,一张图像4096*1000个像素,按应该是100帧每秒
由于线扫相机,每次采集的是一行,即4096*1个像素的图像。所以100KHz即每秒采集100K行。
需要如下函数等待触发采集完成
MdigGrabWait(MilDigitizer, M_GRAB_END);//等待触发抓取完成
触发采集的图像会存储在MilImage[n*100+NbProc] 中
MdigGrab(MilDigitizer, MilImage[n*100+NbProc]);//在 第n个内存块的第NbProc个内存区域 抓取数据
//前期准备工作如下*********************************************************
//存放触发抓取图像的内存空间
MIL_ID MilImage[200];
//每次触发抓取后调用的用户函数
MIL_INT MFTYPE GrabStart(MIL_INT, MIL_ID, void*);
//定义触发的用户数据
typedef struct
{
MIL_INT NbGrabStart;
} UserDataStruct;
//相机图像的属性信息
MIL_INT SrcImageDataSize;
MIL_INT BufSizeX;
MIL_INT BufSizeY;
//开始分配内存*********************************************************
//按照默认的DCF文件,初始化各类ID
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL,&MilDigitizer, &MilImageDisp);
//分配抓取的图像内存
for (int n=0; n<200; n++)
MbufAlloc2d(MilSystem,
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
8L+M_UNSIGNED,
M_DISP+M_IMAGE+M_GRAB+M_PROC, &MilImage[n]);
//开始触发抓取设置和抓取图像*********************************************************
//定义触发事件函数
UserDataStruct UserStruct;//定义触发的 用户数据
UserStruct.NbGrabStart = 0;
//关联触发函数
MdigHookFunction(MilDigitizer, M_GRAB_START, GrabStart, (void *)(&UserStruct));
//设置抓取是同步模式
MdigControl(MilDigitizer, M_GRAB_MODE, M_ASYNCHRONOUS);
//抓取第一个图像,获取图像属性信息
MdigGrab(MilDigitizer, MilImage[0]);
//相机图像的属性信息
SrcImageDataSize=0;//图像的大小,单位像素
BufSizeX=0;//图像的宽度
BufSizeY=0;//图像的高度
//获得相机图像的宽度和高度
MdigInquire(MilDigitizer, M_SIZE_X,&BufSizeX);
MdigInquire(MilDigitizer, M_SIZE_Y,&BufSizeY);
MbufInquire(MilImage[0], M_SIZE_BYTE, &SrcImageDataSize);//数据大小
//连续抓取图像
n=0;//初始化从第0个内存块开始采集
NbProc = 0;//从内存块的第0个位置开始采集
int Framecount=0;//图像的总张数
int Framenum=1;//使用过内存块的次数
//重置计时器
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS, M_NULL);
do {
//抓取下一个图像
MdigGrab(MilDigitizer, MilImage[n*100+NbProc]);//在 第n个内存块的第NbProc个内存区域 抓取数据
MdigGrabWait(MilDigitizer, M_GRAB_END);//等待触发抓取完成
//将图像传递给显示器,这里我是在界面窗口直接显示,没有用MIL自带的显示器
//MimArith(MilImage[n*100+NbProc], M_NULL, MilImageDisp, M_PASS);//取反M_OR
//更新处理的图像数
NbProc++;//下一个图像内存空间
Framecount++;//总图像数加1
//如果点击了关闭采集,退出循环
if(FlagCapture==0)
{
break;
}
//每采集200张计算一下帧率
if(Framecount%200==0)
{
//记录时间,计算帧率
MappTimer(M_DEFAULT, M_TIMER_READ + M_SYNCHRONOUS, &Time);//记录当前运行时间
double temprate=Framecount / Time;//计算每秒触发采集多少张图片
ui->lineEdit_FrameRate->setText(QString::number(temprate,10,4));//在主页面显示帧率
//防止页面卡死
QCoreApplication::processEvents();
}
//如果抓取的图像数量达到了一个内存块的长度,换到下一个内存块。并启动线程存储当前内存块抓取的所有图像
//这一段是我自己所需的
if(NbProc>=100)//一个内存块可以抓取100张图片
{
//如果抓取的图像总数量还没有达到限制数量,传递信息到存储线程中,开始存储图像
if(Framenum<=MaxNum)
{
//发送信号到存储线程
emit SendData(savepath,n,NbProc,Framenum);
}
NbProc=0;//重新 从第0个内存位置开始存储
n = 1-n;//转换内存块
Framenum++;//使用过内存块的次数加1
}
}
while(!MosKbhit());
七、常用MIL函数
7.1 MIL_TEXT
MIL中的字符串,实际是Qt中的wchar_t*类型
MIL_TEXT("Matrox Capture DirectShow filter:\n")
等价于==》
QString savepath=ui->lineEdit->text();
savepath=savepath.append("/"+QString::number(index));
savepath=savepath.append(".tif");
//QString类型转换为MIL_TEXT
const wchar_t* savepath_wchar = reinterpret_cast<const wchar_t *>(savepath.utf16());
7.2 MosGetch()
获取键盘输入
7.3 MdigHalt(MilDigitizer)
暂停连续显示
7.4 MdigGrab(MilDigitizer, MilImage)
获取一张图到Millmage中
7.5 MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem,&MilDisplay, &MilDigitizer, &MilImage);
以默认模式分配所有标识内存
7.6 MdigGrabContinuous(MilDigitizer, MilImage)
连续显示图像
7.7 MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage)
释放所有内存
7.8 MbufClear(MilImageDisp, 0x0)
清空某个标识的内存
7.9 MdispSelect(MilDisplay, MilImageDisp)
在MIL自带显示屏上显示图像
7.10 MdigControl(MilDigitizer, M_GRAB_SCALE, GrabScale)
控制显示器的属性
格式如下:
void MdigControl(DigId, ControlType, Value)
MIL_ID DigId; | Digitizer 标识符 |
long ControlType; | 控制类型 |
double ControlValue; | 控制值 |
控制类型如下:
控制类型 | 描述 |
M_GRAB_SCALE | 控制使用MdigGrab or MdigGrabContinuous函数抓取数据时的水平和竖直缩放因子 典型值:0.25, 0.5, and 1.0。间隔取值方式缩放 |
M_GRAB_SCALE_X | 控制使用MdigGrab or MdigGrabContinuous函数抓取数据时的水平缩放因子 |
M_GRAB_SCALE_Y | 控制使用MdigGrab or MdigGrabContinuous函数抓取数据时的水平和竖直缩放因子 |
M_GRAB_MODE | 控制抓取图像时的同步性 MdigGrab . |
M_GRAB_FIELD_NUM | 控制抓取图像时的区域数量 MdigGrab. |
M_GRAB_FRAME_NUM | 控制抓取图像时的帧数量 MdigGrab. |
M_GRAB_START_MODE | 设置开始抓取图像模式为奇、偶或其他: M_FIELD_START_ODD, M_FIELD_START_EVEN (M_DEFAULT), or M_FIELD_START. |
M_GRAB_HALT_ON_NEXT_FIELD | 无论最后一帧是否有效,停止抓取 M_ENABLE, M_DISABLE or M_DEFAULT (same as M_DISABLE). |
M_GRAB_TRIGGER_SOURCE | 设置抓取触发源 |
M_GRAB_TRIGGER_MODE | 设置硬件触发使能模式 |
M_GRAB_TRIGGER | 设置触发抓取的检测状态 M_DEFAULT, M_ENABLE, M_DISABLE, or M_ACTIVATE. |
M_SOURCE_SIZE_X | 设置输入信号抓取窗的宽度 |
M_SOURCE_SIZE_Y | 设置输入信号抓取窗的高度 |
M_SOURCE_OFFSET_X | 设置输入信号抓取窗的X方向偏移 |
M_SOURCE_OFFSET_Y | 设置输入信号抓取窗的Y方向偏移 |
7.11 MdigInquire(MilDigitizer, M_SIZE_X,&BufSizeX)
获取显示器的属性
格式
long MdigInquire(DigId, ParamToInquire, UserVarPtr)
MIL_ID DigId; | Digitizer 标识符 |
long InquireType; | 获取的属性类型 |
void *UserVarPtr; | 获取属性值的存储位置 |
属性类型 | 描述 |
M_OWNER_SYSTEM | 获取MIL的标识符名称 (MdigAlloc). |
M_NATIVE_ID | The native identifier of the digitizer (if any). |
M_NUMBER | 获取显示器在系统中的排名 (MdigAlloc). |
M_FORMAT | 获取显示器数据格式 (MdigAlloc). |
M_FORMAT_SIZE | 获取显示器数据格式字符串的字符长度 |
M_INIT_FLAG | 获取显示器初始化标志值 (MdigAlloc). |
M_CHANNEL | Current channel of the digitizer (MdigChannel). |
M_CHANNEL+M_SYNC | Current synchronization channel of the digitizer (MdigChannel). |
M_CHANNEL+M_SIGNAL | Current signal channel of the digitizer (MdigChannel). |
M_CHANNEL_NUM | Number of available channels of the device (MdigChannel). |
M_LUT_ID | MIL identifier (MIL_ID) of the LUT associated with the digitizer (MdigLut). |
M_BLACK_REF | 显示器的黑色参考值 (MdigReference). |
M_WHITE_REF | 显示器的白色参考值 (MdigReference). |
M_HUE_REF | 显示器的色彩参考值 (MdigReference). |
M_SATURATION_REF | 显示器的饱和度值 (MdigReference). |
M_BRIGHTNESS_REF | 显示器的明度值 (MdigReference). |
M_CONTRAST_REF | 显示器的对比度值 (MdigReference). |
M_GRAB_SCALE_X | 显示器的水平缩放因子值 (MdigControl). |
M_GRAB_SCALE_Y | 显示器的竖直缩放因子值 (MdigControl). |
M_GRAB_MODE | 抓取同步 (M_SYNCHRONOUS or M_ASYNCHRONOUS) (MdigControl). |
M_GRAB_FRAME_NUM | 抓取帧的数量when MdigGrab is called (MdigControl). |
M_GRAB_FIELD_NUM | 抓取域的数量when MdigGrab is called (MdigControl). |
M_GRAB_START_MODE | 开始抓取模式Type of field on which to grab. |
M_GRAB_HALT_ON_NEXT_FIELD | Whether to stop grabbing as soon as possible, whether the last frame is valid or not. (MdigControl). |
M_GRAB_TRIGGER_SOURCE | Grab trigger source (MdigControl). |
M_GRAB_TRIGGER_MODE | Hardware trigger activation mode (MdigControl). |
M_GRAB_TRIGGER | Grab trigger state (M_ENABLE, M_DISABLE, M_START_GRAB or M_DEFAULT (same as .dcf, if any, or M_DISABLE) (MdigControl). |
M_GRAB_START_HANDLER_PTR | The pointer of the grab hook to start of grab. |
M_GRAB_START_HANDLER_USER_PTR | The user pointer of the grab hook to start of grab. |
M_GRAB_END_HANDLER_PTR | The pointer of the grab hook to end of grab. |
M_GRAB_END_HANDLER_USER_PTR | The user pointer of the grab hook to end of grab. |
M_GRAB_FRAME_START_HANDLER_PTR | The pointer of the grab hook to start of frame grab. |
M_GRAB_FRAME_START_HANDLER_USER_PTR | The user pointer of the grab hook to start of frame grab. |
M_GRAB_FRAME_END_HANDLER_PTR | The pointer of the grab hook to end of frame grab. |
M_GRAB_FRAME_END_HANDLER_USER_PTR | The user pointer of the grab hook to end of frame grab. |
M_FIELD_START_HANDLER_PTR | The pointer of the grab hook to start of field. |
M_FIELD_START_HANDLER_USER_PTR | The user pointer of the grab hook to start of field. |
M_FIELD_START_ODD_HANDLER_PTR | The pointer of the grab hook to start of odd field. |
M_FIELD_START_ODD_HANDLER_USER_PTR | The user pointer of the grab hook to start of odd field. |
M_FIELD_START_EVEN_HANDLER_PTR | The pointer of the grab hook to start of even field. |
M_FIELD_START_EVEN_HANDLER_USER_PTR | The user pointer of the grab hook to start of even field. |
M_GRAB_FIELD_END_HANDLER_PTR | The pointer of the grab hook to end of field grab. |
M_GRAB_FIELD_END_HANDLER_USER_PTR | The user pointer of the grab hook to end of field grab. |
M_GRAB_FIELD_END_ODD_HANDLER_PTR | The pointer of the grab hook to end of odd field grab. |
M_GRAB_FIELD_END_ODD_HANDLER_USER_PTR | The user pointer of the grab hook to end of odd field grab. |
M_GRAB_FIELD_END_EVEN_HANDLER_PTR | The pointer of the grab hook to end of even field grab. |
M_GRAB_FIELD_END_EVEN_HANDLER_USER_PTR | The user pointer of the grab hook to end of even field grab. |
M_FRAME_START_HANDLER_PTR | The pointer of the grab hook to start of frame. |
M_FRAME_START_HANDLER_USER_PTR | The user pointer of the grab hook to start of frame. |
M_SIZE_X | 显示器输入宽度Digitizer input width. |
M_SIZE_Y | 显示器输入高度Digitizer input height. |
M_SIZE_BAND | Number of input color bands of the digitizer. |
M_SIZE_BAND_LUT | Number of input color bands of the input LUT (if any) associated with the digitizer. |
M_SIZE_BIT | 显示器的位数 |
M_SIGN | 显示器的数据范围 (M_SIGNED or M_UNSIGNED). |
M_TYPE | 显示器的数据类型 (number of bits + M_SIGNED or M_UNSIGNED). |
M_SOURCE_SIZE_X | 输入信号抓取窗口的宽度 |
M_SOURCE_SIZE_Y | 输入信号抓取窗口的高度 |
M_SOURCE_OFFSET_X | 输入信号抓取窗口的X偏移 |
M_SOURCE_OFFSET_Y | 输入信号抓取窗口的Y偏移 |
M_COLOR_MODE | Monochrome or color input. |
M_SCAN_MODE | Scan mode (M_INTERLACE, M_PROGRESSIVE, or M_LINESCAN). |
M_INPUT_MODE | 模拟或者数字输入 |