3

My problem is simple, but I'm having a hard time with the actual code. I'm using a camera (ARCamera from ARKit) that displays the video feed onto the screen. The iPhone camera is wide (camera space), whereas the screen only shows part of it (screen space).

The Vision framework gives me a CGRect (boundingBox) that is relative to the camera sensor. For example, it may tell me that a face was detected in the camera sensor at (x: 1, y: 1, width: foo, height: bar).

The problem is that the origin (1, 1) is in the left side of the camera space, but should not be visible in the screen space.

I think want to scale transform, then translate transform the CGRect from the camera frame to the screen's frame.

private func transformBoundingBox(bound: CGRect) -> CGRect {
    // iPhone camera res is 1920 x 1440
    // iPhone screen pts is 375 x 812
    let xFactor = CGFloat(self.cameraResolution.width/self.cameraResolution.height)     // 1.333
    let scaledWidth = view.frame.width*xFactor                                          // 500

    // this part works, converting the Vision CGRect to a CGRect
    // that is too wide for the current screen, but is properly oriented
    let visionTransform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -view.frame.height)
    let screenScale = CGAffineTransform.identity.scaledBy(x: scaledWidth, y: view.frame.height)
    let screenBound = bound.applying(screenScale).applying(visionTransform)

    // this part is broken, the translate transform
    // (intended to adjust the X origin so that what is not visible is off screen)
    // this code seems to perform "OK" on the left half of the screen
    let widthAdjustment = -(scaledWidth - view.frame.width) * xFactor * (1/2)
    let cameraTranslate = CGAffineTransform(scaleX: 1, y: 1).translatedBy(x: widthAdjustment, y: 0)
    let updatedBound = screenBound.applying(cameraTranslate)

    return updatedBound
}

I've tried the code ABOVE (and many variations), but it's not working. It's particularly having issues on the right side.

For reference, the code BELOW works to re-orient & fit the camera's frame to the screen frame. But this is incorrect as elements which are outside of the screen space are mapped to the screen space.

    let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -view.frame.height)
    let translate = CGAffineTransform.identity.scaledBy(x: view.frame.width, y: view.frame.height)

    let transformedBound = bound.applying(translate).applying(transform)

What is the correct way to transform a CGRect that is too big for the iPhone screen so that the sides/edges (left & right in this case) are cropped out?

xta
  • 729
  • 2
  • 8
  • 29

0 Answers0