apple/VisionOS, ARKit

[ARKit] #6 ARKit in iOS

lgvv 2023. 8. 15. 14:55

ARKit in iOS

 

iOS 디바이스 카메라 모션 기능 등 우리의 앱에서 증강 현실 경험을 생성하는 방법에 대해서 알아보자.

 

 

# 장치 권한 확인(Verifying Device Support and User Permission)

 - 앱이 ARKit을 사용할 수 있고, 사용중에 그 권한이 있는지 확인해야 한다. 

 

 - ARKit은 iOS 11.0 이상 그리고 A9 프로세서 이상이 필수적임. 몇몇 ARKit 기능들은 더 특정 디바이스의 더 최신버전이 필요함. ARKit은 또한 디바이스의 카메라를 사용하고, 그래서 iOS의 privacy 권한을 유저로부터 허용받아야 함.

 

장치의 호환성을 우리가 다루는 방법을 ARKit을 우리가 어떻게 사용하냐에 따라 다름.

 

- 만약 후면 카메라를 이용한 AR의 기본적인 기능만 사용한다면 UIRequiredDeviceCapabilities를 info.plist 섹션에 추가한다. 이것을 사용하면 ARKit이 호환되는 디바이스에서만 우리가 만든 앱을 사용할 수 있다.

 

 - 만약 AR앱이 보조 기능은 경우에는, 현재 디바이스가 ARConfiguration의 isSupported 프로퍼티를 통해서 현재 AR Configuration를 지원하고 있는지 확인한다.

 

 - 만약 얼굴을 트래킹하는 AR 기능을 사용한다면, 얼굴을 추적하는 경우에는 전면 TrueDepth 카메라(아이폰 X)가 필요하다. ARFaceTrackingConfiguration.isSuppoted를 통해 현재 디바이스에서 얼굴 추적할 수 있는지 확인한다.

 

 - 💡 Tip 

앱의 UI에 AR 기능을 노출하기 전에 isSupported 프로퍼티를 체크해서 지원하지 장치인지 먼저 확인하여 사용자가 지원하지 않는 기기에서 AR을 쓰려고 시도할 때 적절한 뷰를 제공해 사용자 경험을 떨어뜨리지 말자.

 

# 개인정보 및 유저 동의 처리 (Handle User Consent and Privacy)

ARKit을 우리 앱에서 사용하기 위해서 명시적으로 카메라 권한을 얻어야 함. ARKit은 자동적으로 우리 앱이 처음 실행되고, AR Session이 나타날 때 권한을 요청해줌. 

 

iOS에서는 시스템 카메라 및 microphone 권한을 요청할 때 정적인 메시지를 제공하기를 보여줌. 우리 앱에 NSCameraUsageDescription key를 info.plist에 반드시 포함해야한다. 이건 우리가 왜 카메라 사용하는지 설명할 수 있다.

 

만약 ARFaceTrackingConfiguration을 사용한다면, ARKit은 개인 얼굴 정보를 제공한다. ARKit 얼굴 추적 기능을 사용하는 경우 얼굴 추적 및 얼굴 데이터를 사용하는 방법을 사용자에게 설명하는 개인 정보 보호 정책을 앱에 포함해야 합니다. 

 

얼굴 추적과 관련한 내용은 아래 애플 앱 심사 가이드라인을 참고하자.

 

# ARSession

모션 트래킹, 카메라 pass through, 이미지 분석 등 모든 AR 경험과 관련된 주요 작업을 관리하는 객체
 
class ARSession : NSObject

 

ARSession은 AR 경험을 만들기 위해 ARKit이 사용자를 대신해 주요한 프로세스를 대신함. 

동작을 감지하여 하드웨어에서 데이트 읽기, 장치의 내장 카메라 제어 및 캡쳐된 카메라 이미지 분석 등을 수행하고, ARSession은 이러한 모든 결과를 종합해 디바이스에 위치하는 실제 공간과 AR 컨텐츠를 모델링하는 가상 공간간의 관계를 연결함.

 

세션을 만들고

let session = ARSession()
session.delegate = self

세션을 실행하기 위해서는 configuration이 필요하다. ARConfiguration은 ARKit이 실제 공간을 기준으로 위치, 동작 등을 트래킹하는 방법을 결정하므로 생성하는 AR 경험의 종류를 결정함. 예를 들면은 ARWorldTrackingConfiguration 후면 카메라 통해 주변 세게에 대해 유저의 시야를 확대할 수도 있음.

ARConfiguration, ARFaceConfiguration, ARWorldTrackingConfiguration 등이 ARSeesion을 실행하기 위한 configuration에 해당함. configuration이 많아서 이는 추후에 하나의 카테고리로 포스팅 

세션을 구성하는건 크게 이렇게 있음

 

 

# Responding Event in ARSession

weak var delegate: ARSessionDelegate? { get set }

캡처된 비디오 이미지 및 추적 정보를 수신하거나 세션 상태 변경에 응답하기 위해 제공

 

 - ARSCNView 또는 ARSKView 클래스를 사용한다면, 세션에서 delegate는 필요하지 않음. 이러한 뷰들은 자동으로 캡쳐된 이미지를 보여주고 SceneKit 또는 SpriteKit 콘텐츠를 관리하고 장치 및 카메라 동작을 추적합니다.

 

- 만약 Metal 또는 기타 렌더링 기술을 사용하여 AR 경험을 위한 고유한 시각화를 생성하는 경우에는 session에 delegate를 설정해야한다. 대리자 개체는 ARFrame 세션에서 캡처한 객체를 주기적으로 받습니다. 이러한 객체에는 표시할 비디오 프레임 이미지와 렌더링하는 scene elements의 coordinate display하는데 사용할 수 있는 AR scene 정보가 포함되어 있습니다.

 

# ARSessionDelegate

 

AR 세션에서 캡처된 비디오 프레임 이미지 및 추적 상태를 수신하기 위해 구현할 수 있는 방법

protocol ARSessionDelegate

ARFrame 세션에서 캡처한 객체로 직접 작업을 할 수 있으면 추적된 ARAnchor 객체 집합에 대한 변경사항을 직접 따라야 하는 경우 이 프로토콜을 구현. 일반적으로 AR 컨텐츠를 표시하기 위해 커스텀 뷰를 구축할 때 이 프로토콜을 채택함. SceneKit 또는 SpriteKit을 사용하여 컨텐츠를 표시하는 경우 ARSCNViewDelgate 그리고 ARSKViewDelegate 프로토콜과 비슷한 정보를 제공하고 그리고 이러한 기술들을 통합될 수 있음.

 

이 프로토콜은 ARSessionObserver 프로토콜로 확장되었고, 그래서 session delegate는 session 변화에 대한 것도 감지할 수 있음.

 

 - 카메라 프레임을 받는법

func session(ARSession, didUpdate: ARFrame)
// 새로 촬영된 카메라 이미지와 그에 따른 AR 정보를 델리게이트에게 제공

- 콘텐트 update를 다루는법

func session(ARSession, didAdd: [ARAnchor])
// Tells the delegate that one or more anchors have been added to the session.

func session(ARSession, didUpdate: [ARAnchor])
// Tells the delegate that the session has adjusted the properties of one or more anchors.

func session(ARSession, didRemove: [ARAnchor])
// Tells the delegate that one or more anchors have been removed from the session.

 

# ARAnchor

물리 공간에서 특정 위치와 방향을 정하는 객체

class ARAnchor : NSObject

카메라를 기준으로 실제 또는 가상 객체의 정적 위치 및 방향을 추적하려면 add(anchor:)를 AR 세션에 추가한다.

 

- 💡Tip 

세션에 앵커를 추가하면 ARKit이 해당 앵커 주변 영역에서 world-tracking을 최적화하여 가상 개체가 실제 공간에 비해 제자리에 유지되는 것처럼 보입니다. 가상 물체가 움직이면 이전 위치에서 해당 앵커를 제거하고 새 위치에 하나를 추가합니다.

 

몇몇 ARKit의 기능들은 자동적으로 앵커를 추가한다. ARPlainAnchor, ARObjectAnchor 그리고 ARImageAnchor 객체 등을 만약  특정 기능을 활성화하면 추가할 수 있고, 얼굴 추적에 있어서는 ARFaceAnchor를 추가할 수 있다.

 

ARAnchor가상 콘텐츠의 실제 위치를 추적하기 위해 고유한 인스턴스를 생성하는 것 외에도 ARAnchor사용자 정의 데이터를 생성한 앵커와 연결하기 위해 하위 클래스를 만들 수도 있음. ARKit이 프레임을 업데이트하거나 다음에서 앵커를 저장 및 로드할 때 앵커 클래스가 WorldMap안에서 올바르게 작동하는지 확인하기 

 

 - world map 정보를 저장하고자 할때 ARTrackable을 채택하지 않은 앵커들만 저장할 수 있음. (face 같은거 안된다는 말)

 

# ARFrame

위치 추적 정보가 있는 세션의 일부로 캡처된 비디오 이미지.

class ARFrame : NSObject

 

실행 중인 세션은 디바이스의 카메라에서 비디오 프레임을 지속적으로 캡처하는 반면 ARKit은 캡처를 분석하여 실제 세계에서 사용자의 위치를 ​​결정합니다. ARKit은 ARFrame 안에서 다음 두 가지 방법으로 이 정보를 제공할 수 있음.

 

 - 경우에 따라서는, ARSession의 객체의 currentFrame에 접근

 - 지속적으로 session(_: didUpdate:)를 통해서 스트림 콜백받기

 

자동으로 캡쳐링을 받기 위해서는 ARSession에 우리가 사용하는 객체에 해당하는 delegate를 채택할 것

 

각 프레임에는 EXIF(exifData)와 같은 추가 데이터 또는 frameSemantics 활성화한 특정 데이터를 기반으로 하는 데이터가 포함될 수 있음. frameSemantics는 다음 글에서 작성.

 

# ARCamera

프레임을 캡처하는데 사용되는 카메라 위치, 방향 및 이미징 매개변수에 대한 정보

@NSCopying
var camera: ARCamera { get }

 

 - 카메라 데이터에 접근

var capturedImage: CVPixelBuffer
// 카메라가 캡처한 이미지를 포함하는 픽셀 버퍼
 discussion:
 ARKit은 ITU R. 601-4 표준에 따라 풀 레인지 평면 YCbCr 형식(YUV라고도 함)으로 픽셀 버퍼를 캡처.
 (kCVimageBufferYCbCrMatrixKey 픽셀 버퍼 첨부 파일을 확인하여 이를 확인할 수 있음.)
   - kCVimageBufferYCbCrMatrixKey이란?
   - 이미지 버퍼에 대한 YCbCr에서 RGB로 색상 변환을 위한 매트릭스 키
   - ARKit은 비디오 범위 값이 아닌 전ㄴ체 범위 색 공간 값을 캡처 
   - 
 
var timestamp: TimeInterval
// 프레임이 캡처된 시간

var cameraGrainIntensity: Float
// 카메라 그레인 텍스처에 있는 그레인의 양을 지정하는 값
 discussion:
 [0...1] 사이에서 정규화되고 0이면 그레인 없음 1이면 최대 그레인 양.
 이 값에 깊이 값 구성요소를 적용하면 개념적으로 cameraGrainTexture 시각적 이미지 노이즈 데이터 변형중 선택.

var cameraGrainTexture: MTLTexture?
// 현재 비디오 스트림의 시각적 특성과 일치하도록 ARKit에서 만든 타일 가능한 금속 텍스처.
 discussion:
 카메라 그레인은 앱의 가상 콘텐츠가 카메라 피드에서 자연적으로 발생하는 유사한 이미지 노이즈 특성을
 가질 수 있도록 하여 사용자 경험의 실제 및 증강 측면의 시각적 응집력을 향상.

var exifData: [String : Any]
// 캡처된 이미지에 대한 보조 데이터
 discussion:
 카메라 제조업체, 방향, 압축, 해사도, 노출, 노출이 발생할 날짜 및 시간 등을 포함

 

- var capturedImage: CVPixelBuffer

 

메탈을 통해 AR 경험을 보여주는 예제도 있다.

https://developer.apple.com/documentation/arkit/arkit_in_ios/displaying_an_ar_experience_with_metal

 

 

- var cameraGrainTexture: MTLTexture?

 

만약 너의 렌더러가 ARSCNView인 경우 SceneKit은 앱의 가상 콘텐츠에 카메라 그레인을 적용합니다.

MTLTexture은 메탈을 공부하면서 더 알아보도록 하자.

가상 콘텐츠에 노이즈를 적용하면 더 사실저깅어 보인다!!

커스텀 렌더러에서 이미지 노이즈 활성화(Enable Image Noise on a Custom Renderer)하는 법에 대해 알아보자.

 

커스텀 Metal 렌더러를 사용하여 AR 경험을 표시하는 앱의 경우 ARKit은 현재 비디오 스트림에서 감지한 노이즈와 일치하는 cameraGrainTexture를 제공합니다. 렌더러에 노이즈 텍스처를 설정하여 그 특성을 가상 콘텐츠에 적용.

 

이미지 노이즈 텍스처의 깊이 차원에는 현재 프레임의 cameraGrainIntensity을 기준으로 런타임에 선택하는 변형이 포함.

 

 

 

- var rendersMotionBlur: Bool { get set }

뷰가 모션 블러를 렌더링 하는지의 여부를 결정하는데, 이 값은 기본적으로 활성화되어 있으며, ARKit이 카메라 피드에서 관찰하는 모션 블러의 시각적 특성과 일치하는 렌더링된 콘텐츠에 모션 블러를 자동으로 추가. 

 

SCNCamera의 motionBluerIntensity의 값을 덮어씀.

 

블러~!

 

 

- Accessing scene data

var lightEstimate: ARLightEstimate?
// 카메라 이미지를 기반으로 한 예상 조명 조건

func displayTransform(for: UIInterfaceOrientation, viewportSize: CGSize) -> CGAffineTransform
// 정규화된 이미지 좌표와 카메라 이미지를 화면에 렌더링하는 데 적합한 좌표 공간 간의 변환을 위한 CGAffineTransform

var rawFeaturePoints: ARPointCloud?
// ARKit이 worldMap을 트래킹하는데 사용하는 장면 분석의 현재 중간 결과.
 discussion:
 ARSession world에 있는 좌표 공간의 point값

var capturedDepthData: AVDepthData?
// 전면 카메라 경험에서 캡처한 깊이 데이터

var capturedDepthDataTimestamp: TimeInterval
// 프레임에 대한 깊이 데이터(있는 경우)가 캡처된 시간.

var sceneDepth: ARDepthData?
// AR 경험에서 디바이스의 후면 카메라와 실제 물체 사이의 거리에 대한 데이터

var smoothedSceneDepth: ARDepthData?
// 장치의 후면 카메라와 AR 경험에서 더 부드러운 시각적 효과를 생성하는 실제 물체 사이의 평균 거리 측정

 

 

 

 

 

 

 

 

 

(참고)

https://developer.apple.com/documentation/arkit/verifying_device_support_and_user_permission#2970474

 

Verifying Device Support and User Permission | Apple Developer Documentation

Check whether your app can use ARKit and respect user privacy at runtime.

developer.apple.com

https://developer.apple.com/support/terms/

 

Support - Apple Developer

Feedback Assistant Submit feedback, report bugs, and request enhancements to APIs and developer tools. Send us feedback

developer.apple.com

https://developer.apple.com/documentation/arkit/arsession/2865614-delegate

 

delegate | Apple Developer Documentation

An object you provide to receive captured video images and tracking information, or to respond to changes in session status.

developer.apple.com

https://developer.apple.com/documentation/arkit/arframe

 

ARFrame | Apple Developer Documentation

A video image captured as part of a session with position-tracking information.

developer.apple.com

https://developer.apple.com/documentation/arkit/arconfiguration/3089121-framesemantics

 

frameSemantics | Apple Developer Documentation

The set of active semantics on the frame.

developer.apple.com

https://developer.apple.com/documentation/arkit/arconfiguration/framesemantics

 

ARConfiguration.FrameSemantics | Apple Developer Documentation

Types of optional frame features you can enable in your app.

developer.apple.com

https://developer.apple.com/documentation/arkit/arframe/3255174-detectedbody

 

detectedBody | Apple Developer Documentation

The screen position information of a body that ARKit recognizes in the camera image.

developer.apple.com

https://developer.apple.com/documentation/arkit/arframe/3255173-cameragraintexture

 

cameraGrainTexture | Apple Developer Documentation

A tileable Metal texture created by ARKit to match the visual characteristics of the current video stream.

developer.apple.com

https://developer.apple.com/documentation/arkit/arkit_in_ios/displaying_an_ar_experience_with_metal

 

Displaying an AR Experience with Metal | Apple Developer Documentation

Control rendering of your app's virtual content on top of a camera feed.

developer.apple.com

https://developer.apple.com/documentation/corevideo/cvpixelbuffer

 

CVPixelBuffer | Apple Developer Documentation

A reference to a Core Video pixel buffer object.

developer.apple.com

https://developer.apple.com/documentation/arkit/arkit_in_ios/content_anchors/visualizing_and_interacting_with_a_reconstructed_scene

 

Visualizing and Interacting with a Reconstructed Scene | Apple Developer Documentation

Estimate the shape of the physical environment using a polygonal mesh.

developer.apple.com

https://developer.apple.com/documentation/metal/mtltexture

 

MTLTexture | Apple Developer Documentation

A resource that holds formatted image data.

developer.apple.com

 

'apple > VisionOS, ARKit' 카테고리의 다른 글

[ARKit] #7 frameSemantics  (0) 2023.08.15
[SceneKit] #5 SCNSceneRendererDelegate  (0) 2023.08.15
[SceneKit] #4 SCNAction  (1) 2023.08.13
[SceneKit] #3 Animating SceneKit Content  (0) 2023.08.13
[SceneKit] #2 Geometry 다뤄보기  (0) 2023.08.13