我正在计算机视觉的背景下编写一个小型测试应用程序。最终的应用程序将需要使用相机校准,因此现在我的测试应用程序创建一个捕获会话,启用内在矩阵的传递并记录它。
举个例子,这段代码:
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)
// 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 ) {
...
}
你找到解决办法了吗?我刚刚遇到 https://developer.apple.com/documentation/avfoundation/avcapturephotosettings/3192193-virtualdeviceconstituentphotodel 我想知道如果您启用多摄像头设置,您的 photoOutput 回调(对于每个摄像头)将包含宽幅的 AVCameraCalibrationData和电话。到目前为止,我只使用了双摄像头设置,但还没有使用默认的广角摄像头。