由于科研项目需要,需要使用 Matlab 控制高速相机拍摄小鼠行为,并与三光子显微镜成像同步,在此总结下,如何使用 Matlab 来控制相机进行采集图像和录制视频
相机情况简介
相机名:Basler acA1440-220um
相机参数:拍摄速度最高 227FPS,分辨率最高 1440 px x 1080 px
使用简介
相机需要使用USB 3.0 连接电脑,Basler Pylon Viewer 软件可以对相机进行参数设置并保存配置。
控制相机
-
软件:自带Pylon Viewer
-
代码
- Matlab Gentl Toolbox(不支持使用webcam、winvideo检测相机)
- Python:basler/pypylon-samples (github.com)
Pylon Viewer的使用
下载地址:pylon Software for Image Capture (如果需要保存为mp4,需要额外下载 pylon Supplementary Package for MPEG-4 Windows)
一些设置经验总结
- 设置分别率,即图像尺寸大小。
-
设置相机曝光时间(曝光时间越短,快门速度越快,越能抓拍高速运动的物体)
帧率只决定曝光时间的上限,如果帧率提高抓拍依然模糊,可以适当缩短曝光时间,虽然会造成图片亮度不足
- 增加相机输出图像的亮度:提高 gain(应该类似于相机的iso,亮度会提高,噪声也会提高)
- 保存用户配置,实测除了拍摄图像的分辨率大小外,其他设置的参数比如帧率、曝光时间等都是能在Matlab用的。
- 软件设置录制:上方菜单【Window】→【Record Settings】
Matlab 环境配置和文档总结
-
Matlab 环境配置:需要安装两个 Toolbox
- GenTL Support from Image Acquisition Toolbox
- Image Acquisition Toolbox
-
videoinput 文档:Create video input object - MATLAB - MathWorks 中国,主要使用的函数总结
预览和结束预览
控制相机开始采集图像
-
start
:获取相机专属使用权 【Ref】Data logging is controlled with the
TriggerType
property.Trigger Type Logging Behavior 'hardware'
Data logging occurs when the condition specified in the object’s TriggerCondition
property is met via theTriggerSource
.'immediate'
Data logging occurs immediately. 'manual'
Data logging occurs when the trigger
function is call -
trigger
:如果triggerconfig(vid,"manual")
,则start
后,需要trigger
相机才会开始采集;【Ref】 -
vid.FramesPerTrigger
:specifies the number of frames the video input object acquires each time it executes a trigger using the selected video source. 【Ref】- When the
FramesPerTrigger
property is set toInf
, the object ignores the value of theTriggerRepeat
property.
- When the
-
stop
:停止相机采集 【Ref】 -
wait
:Wait until image acquisition object stops running or logging, locks the MATLAB® command line until the video input objectobj
stops running 【Ref】
LoggingMode 设置
LoggingMode
:“memory” (default) | “disk” | “disk&memory”
-
memory,不提取数据只会把照片保存到内存,需要手动提取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27vid = videoinput('gentl',1,'Mono8',"LoggingMode","memory");
vid.FramesPerTrigger = Inf;
triggerconfig(vid,"manual");
% 获取相机使用权
start(vid); %start 这一句可能存在延迟,不要放在实际相机开始拍的调用里面
% 开始采集
trigger(vid);
% 等待采集完成
pause(5);
% 停止采集
stop(vid);
close(writerObj);
% 录制结束后,需要手动提取frame,保存到视频里
writerObj = VideoWriter('./test.mp4','MPEG-4');
writerObj.FrameRate = 150; %<=150
open(writerObj);
frame = getdata(vid,vid.FramesAcquired);
writeVideo(writerObj,frame);
close(writerObj); -
disk:直接边采集边保存。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30%%%%% 录制视频代码
% log到硬盘
vid = videoinput('gentl',1,'Mono8',"LoggingMode","disk");
set(vid, 'ROIPosition', [400 0 960 640 ]);
vid.FramesPerTrigger = Inf; % 一次Trigger后一直接收帧,直到接收到stop信号
triggerconfig(vid,"manual");
writerObj = VideoWriter('./test.mp4','MPEG-4');
writerObj.FrameRate = 150; %<=150
vid.DiskLogger = writerObj;
preview(vid);
% 获取相机使用权
start(vid); %start 这一句可能存在延迟,不要放在实际相机开始拍的调用里面
% 开始采集
trigger(vid);
% 等待采集完成
pause(5);
% 停止采集
stop(vid);
close(writerObj);
% disconnect video
delete(vid)
clear "vid" -
disk&memory:disk 一份,memory 一份,没必要
获取相机信息
1 | %%%%% 获取相机信息 |
测试帧率和帧率稳定性
- 直接通过预览获取信息:通过预览
preview(vid)
判断相机预设的帧率和 Matlab 获取的帧率是否一致
-
计算实际帧率:通过代码连续获取很多帧,并计时,计算帧率
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24%%%%%% 计算实际帧率
vid = videoinput('gentl',1,'Mono8');
vid.FramesPerTrigger = 1; % 一次触发获取一帧
triggerconfig(vid,"manual"); % 设置手动触发,必须设置,否则每次触发相机都相当于要开机,延迟久
start(vid);
FPS = zeros(1,10);
for iy = 1:10 % 测试十次
Num = 1000; % 每次获取一千帧
tic
for inum = 1:Num
Img = getsnapshot(vid); % getsnapshot相当于手动触发
end
h = toc; % 获取一千帧的耗时
FPS(iy) = Num/h; % 计算FPS
end
plot(1:10,FPS);
% 停止采集
stop(vid);
delete(vid);
clear
- 测试录制视频帧率实际稳定性:控制相机拍摄手机秒表录制一段视频,potplayer 前进一秒,看看视频里的秒表是不是也是前进一秒;严格测试是视频逐帧前进,看秒表前进的时间和计算的是否一致,(注意手机的屏幕刷新率注意需要提高到 120Hz)。
录制视频
录制视频代码
1 | %%%%% 录制视频代码 |
Matlab 怎么缩小 Gentl 协议相机视频分辨率
使用 Basler 自带 Pylon Viewer 软件,设置的视频分辨率,无法在 Matlab 里设置,所以需要额外设置
1 | vid = videoinput('gentl',1,'Mono8'); |
Parameters | Explanation |
---|---|
XOffset |
Position of the upper left corner of the ROI, measured in pixels. |
YOffset |
Position of the upper left corner of the ROI, measured in pixels. |
Width |
Width of the ROI, measured in pixels. The sum of XOffset and Width cannot exceed the width specified in VideoResolution . |
Height |
Height of the ROI, measured in pixels. The sum of YOffset and Height cannot exceed the height specified in VideoResolution . |