Strange vertical disparity between wide-angle and telephoto frames on iPhone 12 Pro

I'm capturing video using builtInDualCamera, two outputs, and an AVCaptureDataOutputSynchronizer, for use in computer vision. I'm cropping the wide-angle camera image so the fields of view match.

Since the wide-angle and telephoto devices are only physically displaced along the horizontal camera axis, on the iPhone 12 Pro at least, I'm expecting depth disparity only along the horizontal image axis. This mostly holds up, except for one weird issue:

If and only if I hold the device roughly upright in landscape orientation, there is a slight vertical disparity between the images, corresponding to roughly 11 pixels in the wide-angle frame at 1920x1080. However, if I hold the device upright in portrait orientation, or hold it flat (parallel to the ground), the image-space vertical disparity vanishes. It's a gradual transition, so the closer I am to upright and landscape, the more of the vertical disparity I get.

Since the problem is definitely dependent on the physical device orientation, it seems like the gyro has to be involved somehow. The thing is, I'm not currently using the gyro anywhere in my app. Is there any AVFoundation setting that would make it utilise the gyro somehow? The only one I can think of is video stabilisation, but that's definitely turned off.

Any suggestions or insights welcome. Thanks for reading.

Accepted Reply

Solved it. As detailed in this WWDC talk, you have to correct for the intrinsic matrices to relate video frames from the respective cameras to each other.

Oddly, it seems that AVCaptureConnection's isCameraIntrinsicMatrixDeliverySupported returns false unless both connections have been added to the session, in which case it returns true (given the session topology in question).

The intrinsic matrices of the respective cameras do change in real time, which accounts for the unexpected vertical disparity.
This WWDC talk describes the intrinsic matrix in a bit more detail.

Replies

From 36:28, this WWDC talk strongly implies you need to correct for the constituent devices' intrinsic matrices in order to relate the images to each other. This is probably the issue. Unfortunately, isCameraIntrinsicMatrixDeliverySupported returns false for both of my connections, even though my capture session is set up exactly as described in the talk.

Does anyone know why isCameraIntrinsicMatrixDeliverySupported would be false? To see my capture session topology, please check out the slides on AVDualCam shown in the WWDC talk above.

Solved it. As detailed in this WWDC talk, you have to correct for the intrinsic matrices to relate video frames from the respective cameras to each other.

Oddly, it seems that AVCaptureConnection's isCameraIntrinsicMatrixDeliverySupported returns false unless both connections have been added to the session, in which case it returns true (given the session topology in question).

The intrinsic matrices of the respective cameras do change in real time, which accounts for the unexpected vertical disparity.
This WWDC talk describes the intrinsic matrix in a bit more detail.