目录
一、简介
该实验模块进行摄像机校准(失真、摄像机内外参数提取),计算并保存输入图像的内在参数。该实验建立在OpenCV之上,但目的是为没有校准或计算机视觉背景的人(或像我这样懒惰的人)简化过程。
注意:我们的目标不是拥有最好的校准工具箱,而是最简单的。如果需要非常高质量的校准,我相信一定有许多其他的工具箱有更好的外部参数估计工具。
非常重要:OpenPose需要一个上三角矩阵的内在相机矩阵。如果您打算使用您自己的相机特性,请注意这一点。
二、安装校准模块
查看doc/installation.md#calibration-module了解安装步骤。
三、运行
注意:为了最大限度地提高校准质量,不要重复使用同一视频序列进行内部和外部参数估计。内在参数校准应逐个摄像机进行,其中每个记录的视频序列应聚焦于摄像机视图的所有区域,并从多个距离重复。
在外部序列中,这个视频序列应该被聚焦,以确保在同一时间至少有2个摄像机可以看到棋盘。因此,对于3个摄像机的校准,每个摄像机需要一个视频序列,以及外部参数校准的最终视频序列。
3.1 常规小技巧
- 保持网格的方向相同,即相对于其中心旋转不超过15-30度(即从一个 w ∗ h w * h w∗h的方块数到一个 h ∗ w h * w h∗w的方块数)。我们的算法假设原点是左上方的角,因此,对网格进行圆周旋转会改变这个原点,导致在最终的标定中会有很多帧被拒绝,从而降低标定精度。
- 覆盖几个距离,在每个距离内,覆盖图像视图的所有部分(所有角落和中心)。
- 保存图像为PNG格式(默认),以提高校准质量。PNG图像比等效的JPG图像大,但不会因压缩而丢失信息。
- 使用一个尽可能大的网格,最好是一个至少有8x6个正方形,每个正方形网格边长至少100毫米。它将特别影响外部校准质量。
- 内在特性:推荐约400图像视图,以高质量的校准。要想得到一个较好的校准结果,您至少应该准备150幅图像,而不超过500幅。使用100幅左右的图像校正一部相机约需3分钟、200幅左右约1.5小时,450幅左右约9.5小时。所需的RAM内存也呈指数级增长。
- 其它:为了进行高质量校准,建议每个相机至少有250幅图像。
3.2 Step 1 - 对失真和内在参数进行校准
- 运行OpenPose并使用您的相机保存图像。使用网格(棋盘)模式并围绕所有图像区域进行移动。不同的图像来源的校准方式:
i. 网络摄像头校准:./build/examples/openpose/openpose.bin --num_gpu 0 --write_images {intrinsic_images_folder_path}。
ii. Flir照相机校准:将语句--flir_camera --flir_camera_index 0(或所需的flir相机序列号)添加到webcam命令。
iii. 视频序列校准:将语句--video {video_path}添加到webcam命令。
iv. 其他品牌相机:只需将图像保存在{intrinsic_images_folder_path}中,文件名无关紧要。 - 通过运行
·--help语句来熟悉上述iii中的参数校准:./build/examples/calibration/calibration.bin --help - 提取并保存内部参数:
./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 40.0 --grid_number_inner_corners "9x5" --camera_serial_number 18079958 --calibration_image_dir {intrinsic_images_folder_path} - 在本例中,内部参数将被保存在
{intrinsic_images_folder_path}/18079958.xml文件中。 - 为每个相机执行步骤1-4。
- 在您校准了相机特性之后,您使用这些相机运行OpenPose时,您会看到现实生活中的线呈现在图像中(几乎)是完美的。另外,如果没有校准好相机。试着通过以下方式检查类似墙壁或天花板边缘等呈直线的图案:
# With distortion (straight lines might not look as straight lines but rather with a more circular shape) ./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 0 # Without distortion (straight lines should look as straight lines) ./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 0 --frame_undistort
样例:
- 针对图片、视频、网络视频的完整样例:
# Ubuntu and Mac # Get images for calibration (only if target is not `--image_dir`) # If video ./build/examples/openpose/openpose.bin --num_gpu 0 --video examples/media/video_chessboard.avi --write_images ~/Desktop/Calib_intrinsics # If webcam ./build/examples/openpose/openpose.bin --num_gpu 0 --webcam --write_images ~/Desktop/Calib_intrinsics # Run calibration ./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 30.0 --grid_number_inner_corners "8x6" --calibration_image_dir ~/Desktop/Calib_intrinsics/ --camera_parameter_folder models/cameraParameters/ --camera_serial_number frame_intrinsics # Output: {OpenPose path}/models/cameraParameters/frame_intrinsics.xml # Visualize undistorted images ./build/examples/openpose/openpose.bin --num_gpu 0 --image_dir ~/Desktop/Calib_intrinsics/ --frame_undistort --camera_parameter_path "models/cameraParameters/frame_intrinsics.xml" # If video ./build/examples/openpose/openpose.bin --num_gpu 0 --video examples/media/video_chessboard.avi --frame_undistort --camera_parameter_path "models/cameraParameters/frame_intrinsics.xml" # If webcam ./build/examples/openpose/openpose.bin --num_gpu 0 --webcam --frame_undistort --camera_parameter_path "models/cameraParameters/frame_intrinsics.xml" - 针对4-view Flir/Point Grey相机系统的完整样例:
# Ubuntu and Mac
# Get images for calibration
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 0 --write_images ~/Desktop/intrinsics_0
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 1 --write_images ~/Desktop/intrinsics_1
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 2 --write_images ~/Desktop/intrinsics_2
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --flir_camera_index 3 --write_images ~/Desktop/intrinsics_3
# Run calibration
# - Note: If your computer has enough RAM memory, you can run all of them at the same time in order to speed up the time (they are not internally multi-threaded).
./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 127.0 --grid_number_inner_corners "9x6" --camera_serial_number 17012332 --calibration_image_dir ~/Desktop/intrinsics_0
./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 127.0 --grid_number_inner_corners "9x6" --camera_serial_number 17092861 --calibration_image_dir ~/Desktop/intrinsics_1
./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 127.0 --grid_number_inner_corners "9x6" --camera_serial_number 17092865 --calibration_image_dir ~/Desktop/intrinsics_2
./build/examples/calibration/calibration.bin --mode 1 --grid_square_size_mm 127.0 --grid_number_inner_corners "9x6" --camera_serial_number 18079957 --calibration_image_dir ~/Desktop/intrinsics_3
# Visualize undistorted images
# - Camera parameters will be saved on their respective serial number files, so OpenPose will automatically find them
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --frame_undistort
- 针对Windows,只需运行
build\x64\Release\calibration.exe(或者可移植二进制演示样例中的语句)与上述语句具有相同效果。
3.3 Step 2 - 校准外部参数
-
非常重要:如果你想在同一特性的XML文件上重新运行外部参数校准(例如,如果你移动相机位置,但你知道它们的相机特性是相同的),那么,你必须手动将用于
--combine_cam0_extrinsics的每个XML文件的摄像机矩阵重新设置为1 0 0 0 0 1 0 0 0 0 1 0。 -
相机的内在特性校准后,保存所有相机视图的未失真图像:
./build/examples/openpose/openpose.bin --num_gpu 0 --flir_camera --frame_undistort --write_images ~/Desktop/extrinsics -
在每对近距离摄像机之间运行外部校准工具。在本样例中:
- 我们假设0号摄像机在右边,1号在中间的右边,2号在中间的左边,3号在左边。
- 我们假设1号摄像机是坐标原点。
# Ubuntu and Mac ./build/examples/calibration/calibration.bin --mode 2 --grid_square_size_mm 127.0 --grid_number_inner_corners 9x6 --omit_distortion --calibration_image_dir ~/Desktop/extrinsics/ --cam0 1 --cam1 0 ./build/examples/calibration/calibration.bin --mode 2 --grid_square_size_mm 127.0 --grid_number_inner_corners 9x6 --omit_distortion --calibration_image_dir ~/Desktop/extrinsics/ --cam0 1 --cam1 2 ./build/examples/calibration/calibration.bin --mode 2 --grid_square_size_mm 127.0 --grid_number_inner_corners 9x6 --omit_distortion --calibration_image_dir ~/Desktop/extrinsics/ --cam0 1 --cam1 3 # Potentially more accurate equivalent for the calibration between cameras 1 and 3: If camera 3 and 1 are too far from each other and the calibration chessboard is not visible from both cameras at the same time enough times, the calibration can be run between camera 3 and camera 2, which is closer to 3. In that case, the `combine_cam0_extrinsics` flag is required, which tells the calibration toolbox that cam0 is not the global origin (in this case is camera 1). # Note: Wait until calibration of camera index 2 with respect to 1 is completed, as information from camera 2 XML calibration file will be used: ./build/examples/calibration/calibration.bin --mode 2 --grid_square_size_mm 127.0 --grid_number_inner_corners 9x6 --omit_distortion --calibration_image_dir ~/Desktop/extrinsics/ --cam0 2 --cam1 3 --combine_cam0_extrinsics:: Windows :: build\x64\Release\calibration.exe with the same flags as above -
如果您使用Ceres求解器(在CMake中使用
WITH_CERES标志),那么可以通过在之前的结果之上执行额外的Bundle调整优化步骤来改进校准结果。
我们使用0号摄像机作为内部计算的基线,因此尽量避免0号摄像机与其他摄像机完全隔离的奇怪配置。
理想情况下,0号相机在物理上应该是最接近其他所有相机的(也就是说,居中的那个)。
但在实践中,精度几乎没有提高(只要它离其他相机不是太远)。
要针对上面的示例执行此bundle调整优化,只需运行以下语句:# Ubuntu and Mac ./build/examples/calibration/calibration.bin --mode 3 --grid_square_size_mm 127.0 --grid_number_inner_corners 9x6 --omit_distortion --calibration_image_dir ~/Desktop/extrinsics/ --number_cameras 4:: Windows :: Ceres-compatible version not implemented for Windows yet. Make a pull request if you have a working version in Windows. -
验证外部校准成功的提示
i. 我们最终的bundle调整步骤的重投影误差(在重新标定之后)通常是0.1-0.15像素。
ii. 平移向量:
a. 从标志--camera_parameter_path所指示的文件夹中手动打开每个生成的XML文件(如果未使用前者,则由--help标志指示的默认值)
b.CameraMatrix是一个3×4矩阵(该文件中的rows=3,而cols=4)
c. 将矩阵排列成3 * 4的形状(比如,通过在不同的文本文件中复制3行4列的形状)
d. CameraMatrix最后一列的前3个分量定义了相对于全局原点的全局translation(单位为米)
e. 因此,该摄像机和1号原点摄像机之间的距离应该(近似)等于平移向量的L2 -范数。
iii. 平移向量,x-y-z的相对距离:
a. 3x1平移向量分别表示到原点摄像机的x、y和z距离。摄像机沿着正z轴,y轴向下,x轴向右。这应该匹配两个相机之间的真实距离。
四、摄像机矩阵的输出格式
CameraMatrix格式如下:
<CameraMatrix type_id="opencv-matrix">
<rows>3</rows>
<cols>4</cols>
<dt>d</dt>
<data>
8.4965260991319647e-01 1.1164693980389649e-01 -5.1538859446064478e-01 2.1494190603291283e+00
-1.5848315388246692e-01 9.8621217567379460e-01 -4.7630184633558698e-02 -4.5237471366168569e-01
5.0296474270386005e-01 1.2214952060972525e-01 8.5563190813085876e-01 1.1418502919988400e+00
</data>
</CameraMatrix>
这是一个3x4矩阵,它表示旋转(R为3x3矩阵)和平移(t为3x1矩阵),格式如下:[R | t]。它们代表了相对于世界原点的旋转和平移。当使用OpenPose校准时,我们设置了一个摄像机作为原点,但是这可以通过一些手动的后处理很容易地进行修改。
五、使用不同品牌的相机
如果您计划在不使用OpenPose的情况下使用校准工具,您可以手动将所需相机的视频序列保存到每个相机图像文件夹中(也就是更改上面样例中的~/Desktop/intrinsics_0,~/Desktop/intrinsics_1等文件夹)
如果你最终想用OpenPose运行相机,可以查看doc/modules/3d_reconstruction_module.md#using-a-different-camera-brand文档。
六、输出图像的命名约定
保存的图像的命名约定如下:[%12d]_rendered[CAMERA_NUMBER_MINUS_1].png,其中[CAMERA_NUMBER_MINUS_1]是0号相机,_1是1号相机,_2是2号相机,等。比如,对于4个相机来说,输出图像命名如下:
000000000000_rendered.png
000000000000_rendered_1.png
000000000000_rendered_2.png
000000000000_rendered_3.png
000000000001_rendered.png
000000000001_rendered_1.png
000000000001_rendered_2.png
000000000001_rendered_3.png
[...]
OpenPose使用形如[%12d]_rendered的名字生成它们。理想情况下,只要尾名[CAMERA_NUMBER_MINUS_1]与所有相机视图保持一致,任何其他基数都应该工作。比如,假设你有4个相机,也可以通过以下方式命名:
a.png, a_1.png, a_2.png, a_3.png,
b.png, b_1.png, b_2.png, b_3.png,
etc.
再次强调,将文件尾名固定为_1,_2等,使其保持一致很重要。
本文档介绍了OpenPose的摄像机校准模块,包括失真和内在参数的校准,以及外部参数的校准步骤。推荐使用PNG格式的图像以提高校准质量,并建议使用大型棋盘格和多样化的拍摄角度。完成校准后,可以提高OpenPose在现实世界中的线性表现。
935

被折叠的 条评论
为什么被折叠?



