【祥哥带你玩Hololens开发】Spactator View Calibration 校准篇
为什么需要校准?
首先来看这张设备架设起来的照片,HoloLens和相机的镜头位置高度差别至少会有10CM以上,另外相机镜头焦距都是可变,这两个因素会决定相机拍HoloLens里面看到的视角会有不同,如果跳过校对直接合成画面那将很可能出现画面中的全息物体的位置和在HoloLens里看到的位置不一致。
声明:
1. 另外还要注意不要用广角镜头,广角镜头的可视角度更大导致畸变更大,在校准的时候很难校准。
2. 不要直接把相机指向浅色的墙壁,因为opencv似乎在这个背景下识别棋盘格校对板有问题,应用程序可能内存不足。
所需软件
- spectator view 项目代码
- Blackmagic 采集卡 SDK 在"Latest Downloads"找Desktop Video Developer SDK .
- [Blackmagic Desktop Video Runtime.]在"Latest Downloads"找Desktop Video Software,版本要与Desktop Video Developer SDK相对应
- OpenCV 3.1, (实际最新的3.2也可以)这个在校准时候用,还在没有 官方推荐的Blackmagic、Elgato两种采集卡的情况下需要用。
配置环境
用Visual Stuido 打开 Calibration\Calibration.sln 校准项目
配置依赖SDK库位置
解决方案中的 dependencies.props,这个文件是Calibration和Compositor两个解决方案共享的,只需修改一次。
dependencies.props 这个文件的注释里也写了各个sdk的下载地址,下载完后根据自己的实际路径修改此文件。
其中 OpenCV_vc14 必须要有,DeckLink_inc 和 Elgato_Filter 就根据你用的采集卡只需要配置对应的就行,如果使用了佳能相机就可以下载配置 Canon_SDK 路径
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<!-- OpenCV_vc14下载地址,这个是必须的: https://github.com/opencv/opencv/releases -->
<OpenCV_vc14>D:\software\Spactator View\opencv\build\x64\vc14</OpenCV_vc14>
<!--用的DeckLink采集卡的话在这里下载对应的sdk: https://www.blackmagicdesign.com/support -->
<DeckLink_inc>D:\software\Spactator View\Blackmagic DeckLink SDK 10.9.3\Win\include</DeckLink_inc>
<!-- 用佳能相机的,SDK下载: https://www.usa.canon.com/internet/portal/us/home/explore/solutions-services/digital-camera-sdk-information -->
<Canon_SDK>C:\CanonSDK\Windows</Canon_SDK>
<!-- 用Elgato采集卡的下载: https://github.com/elgatosf/gamecapture -->
<Elgato_Filter>D:\software\Spactator View\gamecapture-master\VideoCaptureFilter</Elgato_Filter>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup />
<ItemGroup />
</Project>
相机设置
- 用HDMI数据线将相机与采集卡HDMI In接口相连
- 将相机设置为视频输出模式,选择HDMI输出,设置输出画面质量
- 相机设置为手动拍摄模式
- 相机镜头的焦距调整后,在校准后不能改变焦距,只能按照校准时使用的焦距合成画面
- 相机根据现场光线情况尽量使用较快的快门和较小的光圈以获得更好的画面质量
- 相机要调整到看到的校对版画面是清晰的
校对版
按照上一节 HoloLens Spactator View 硬件配件篇 中介绍的准备一个。
修改代码
在Calibration 项目中修改stdafx.h 文件:
- HOLOLENS_USER 与 HOLOLENS_PW 修改为你HoloLens设备Web Portal的账号与密码
- CHESS_SQUARE_SIZE 修改为你打印出来的校对版的单个棋盘格方块的尺寸大小,单位是米
- GRID_CELLS_X 与 GRID_CELLS_Y 根据你校对版实际的水平和垂直的格子数设置
- HOLOLENS_ADDRESS 这个就看你是用usb还是WiFi连设备了,usb的话默认不用改了
修改 SharedHeaders 项目的 CompositorShared.h
// FrameProvider type - Exactly 1 of these should be true:
//TODO: Set this to true if using a BlackMagic DeckLink capture card.
#define USE_DECKLINK TRUE
//TODO: Set this to true if using an Elgato capture card.
#define USE_ELGATO FALSE
//TODO: Set this to true if using OpenCV to get frames from a camera or capture card.
#define USE_OPENCV FALSE
这里如果用的是那个品牌的采集卡就把哪个设置为TRUE,其它为FALSE;如果你BlackMagic和Elgato两种都不是那么你就USE_OPENCV 设置为TRUE,其它为FALSE,并且OpenCVFrameProvider.h 中的 CAMERA_ID 改为采集设备的索引索引号,这个可以尝试修改。
// Frame Dimensions and buffer lengths
//TODO: change this to match video dimensions from your tethered camera.
//默认是1080P的,我这里用的720P的分辨率
#define FRAME_WIDTH 1280
#define FRAME_HEIGHT 720
假如你视频输入到采集卡的尺寸不是1080P的那么还需要,根据你实际的视频尺寸设置 CompositorShared.h 中的 FRAME_WIDTH 和 FRAME_HEIGHT 参数
校对
- 如果你上述部分都配置正确,设备也都正常连接,那么运行Calibration就可以在窗口中看到通过相机拍摄到的画面。
- 如果是蓝屏,那么必然有地方配置的不正确,并且在debug output输出中可以看到错误提示
- 如果是黑屏那么说明sdk库什么的肯定是都正确了,只是没有正确接收或解码视频图像,请检查相机是否能正常拍摄画面,镜头是否正常打开,CompositorShared.h中视频的宽高是否配置正确
- 在镜头前用棋盘格校对板按照下面图片里这样重复上下左右重复移动,程序会通过HoloLens和相机同时获取到画面自动识别校对板,注意不要旋转校对版
- 按回车键可以停止/继续校对
- 生成的文件会放在 *我的文档/CalibrationFiles 目录下的 CalibrationData.txt 文件中。
- 将 CalibrationData.txt 放到Unity项目的 "Assets" 目录下
CalibrationData.txt内容
# Stereo RMS calibration error (Lower numbers are better)
RMS: 44.5421
# DSLR RMS calibration error (Lower numbers are better)
DSLR RMS: 0.203851
# HoloLens RMS calibration error (Lower numbers are better)
HoloLens RMS: 0.34048
# Delta in meters of Hololens from Camera:
Translation: -0.00211806, -0.0910024, 0.00956102
# Row Major Matrix3x3 (This should be close to identity)
Rotation: 0.999703, -0.0181576, -0.0162388, 0.0187252, 0.999194, 0.0355101, 0.0155809, -0.0358036, 0.999237
# Field of View of DSLR:
DSLR_fov: 75.9442, 47.5184
# Field of View of HoloLens:
Holo_fov: 47.7189, 27.9294
# DSLR distortion coefficients:
DSLR_distortion: -0.130447, 0.0715056, -0.00174504, -0.000724455, -0.00542177
# DSLR camera Matrix: fx, fy, cx, cy:
DSLR_camera_Matrix: 901.984, 899.587, 705.553, 378.074
## Calibration
常见问题:
0. 编译缺少库可能是你的NuGet包没有自动下载下来,手动去 **工具->NuGet包管理器->管理解决方案的NuGet包** 更新或者安装 “cpprestsdk” 和 “directxtk_desktop”库
1. CompositorShared.h 中的 FRAME_WIDTH 和 FRAME_HEIGHT 视频分辨率设置与相机实际输出不符
2. 帧率不符,比如相机输出的是1080i5994 但是在程序里默认都是用的1080p5994,这个时候就需要修改代码了,比如DeckLink采集卡就需要修改DeckLinkManager.cpp 的 **videoDisplayMode** 将 ** bmdModeHD1080p5994 ** 改为 ** bmdModeHD1080i5994**
```
HRESULT DekLinkManager::Initialize(ID3D11ShaderResourceView* colorSRV, ID3D11Texture2D* outputTexture)
........
BMDDisplayMode videoDisplayMode;
if (FRAME_HEIGHT < 1080)
{
videoDisplayMode = bmdModeHD720p5994;
}
else if (FRAME_HEIGHT >= 1080 && FRAME_HEIGHT < 2160)
{
videoDisplayMode = bmdModeHD1080p5994;
}
else if (FRAME_HEIGHT == 2160)
{
videoDisplayMode = bmdMode4K2160p5994;
}
else if (FRAME_HEIGHT > 2160)
{
videoDisplayMode = bmdMode4kDCI2398;
}
```
总之遇到有问题多关注debug时输出的信息