如何将 AVDepthData 的内在特性和失真与当前视频流关联起来?

问题描述 投票:0回答:1

我正在计算机视觉的背景下编写一个小型测试应用程序。最终的应用程序将需要使用相机校准,因此现在我的测试应用程序创建一个捕获会话,启用内在矩阵的传递并记录它。

举个例子,这段代码:

let calibrationPayload = CMGetAttachment(sampleBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil)
    if let data = calibrationPayload as? Data {
        let matrix: matrix_float3x3 = data.withUnsafeBytes { $0.pointee }
        print(matrix)
}

在 iPhone 13 Pro 后置摄像头上运行可以给我带来:

simd_float3x3([[4220.394, 0.0, 0.0], [0.0, 4220.394, 0.0], [941.9231, 533.648, 1.0]])

// Corresponding matrix (which makes sense for an 1920x1080 camera):
// [4220.394,    0.0,   941.9231]
// [   0.0,   4220.394, 533.648]
// [   0.0,      0.0,      1.0]

但是,我现在还想了解与该镜头相关的畸变。为此,我更改了我的应用程序以请求类型为

.builtInDualCamera
的设备,并启用深度数据流,因为只有 AVDepthData 缓冲区具有一些伴随失真数据(在其 cameraCalibrationData 属性中)。

在深度捕获委托调用中,我正在记录畸变中心、查找表以及相机内在函数:

guard let calibrationData = depthData.cameraCalibrationData else {
    return
}
print("Intrinsics = \(calibrationData.intrinsicMatrix)")

let distoCenter = calibrationData.lensDistortionCenter
print("Distortion center: \(distoCenter)")

// More code to log the LUT data too

然而,在这种情况下,内在函数有很大不同,实际上对于 1920x1080 相机来说没有任何意义(两个内在矩阵之间似乎存在

2.20
的比例因子):

Intrinsics = simd_float3x3([[9284.896, 0.0, 0.0], [0.0, 9284.896, 0.0], [2072.8423, 1174.5812, 1.0]])

// Corresponding matrix:
// [9284.896, 0.0, 2072.8423]
// [0.0, 9284.896,1174.5812]
// [0.0, 0.0, 1.0]

Distortion center: (2072.839599609375, 1174.5499267578125)
  1. 有人可以向我解释一下这个 2.20 比率是从哪里来的吗?
  2. 是否可以根据对捕获会话的一些查询来预先计算它,或者是否必须根据内在矩阵中的焦距进行估计?
  3. 正确应用LUT来校正图像需要计算距畸变中心的距离,我认为这必须考虑到额外的重新缩放?
// Example code in AVCalibrationData.h to rectify a point:
// Determine the maximum radius.
float delta_ocx_max = MAX( opticalCenter.x, imageSize.width  - opticalCenter.x );
float delta_ocy_max = MAX( opticalCenter.y, imageSize.height - opticalCenter.y );
float r_max = sqrtf( delta_ocx_max * delta_ocx_max + delta_ocy_max * delta_ocy_max );
 
// Determine the vector from the optical center to the given point.
float v_point_x = point.x - opticalCenter.x;
float v_point_y = point.y - opticalCenter.y;
 
// Determine the radius of the given point.
float r_point = sqrtf( v_point_x * v_point_x + v_point_y * v_point_y );
 
// Look up the relative radial magnification to apply in the provided lookup table
float magnification;
const float *lookupTableValues = lookupTable.bytes;
NSUInteger lookupTableCount = lookupTable.length / sizeof(float);
 
if ( r_point < r_max ) {
  ...
}
ios avcapturedevice avcaptureoutput avdepthdata
1个回答
0
投票

你找到解决办法了吗?我刚刚遇到 https://developer.apple.com/documentation/avfoundation/avcapturephotosettings/3192193-virtualdeviceconstituentphotodel 我想知道如果您启用多摄像头设置,您的 photoOutput 回调(对于每个摄像头)将包含宽幅的 AVCameraCalibrationData和电话。到目前为止,我只使用了双摄像头设置,但还没有使用默认的广角摄像头。

© www.soinside.com 2019 - 2024. All rights reserved.