스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Vision에서 3D 신체 포즈와 사람 분리 탐색하기
Vision에서 사람 중심 기능을 구축하는 방법을 발견해 보세요. 사람의 신체 포즈를 감지하여 3D 공간에서 개별 관절 위치를 측정하는 법을 알아보세요. 사람 분리 API를 사용해 하나의 이미지에서 4명의 사람을 구분하고 분리하는 방법을 보여줍니다. VIsion의 최신 기능에 대해 더 알아보고 싶다면, WWDC23 'Vision에서 동물 포즈 감지하기' 세션을 확인하세요.
리소스
관련 비디오
WWDC23
WWDC22
WWDC20
-
다운로드
♪ ♪
Vision 소프트웨어 엔지니어 Andrew Rauh입니다 오늘 이야기할 주제는 인간 신체 포즈 Vision 프레임워크에서의 깊이 사용 인스턴스 마스크로 이미지에서 사람을 분리하는 방법입니다
사람을 감지하고 이해하는 건 항상 Vision의 중심이 됩니다 몇 년 동안 Vision은 2D로 신체 포즈를 제공했죠 2D로 표현한 신체 포즈는 입력 이미지에 일치하는 골격에 정의된 랜드마크의 정규화된 픽셀 좌표로 관찰 내용을 반환합니다 더 자세히 알고 싶다면 아래의 세션을 시청해 보시길 바랍니다 Vision은 이제 VNDetectHumanBodyPose3DRequest라는 새 요청을 통해 주변 환경에서 사람을 캡처해 3D로 보여줍니다 17개 관절을 가진 골격을 3D 관찰 결과로 생성하죠 관절은 하나의 컬렉션인 관절 이름이나 관절 그룹명을 제공하여 접근할 수 있습니다 Vision에서 인식되어 좌측 하단 원점에 정규화되어 반환되는 점들과는 다르게 3D 관절 포지션은 루트 관절을 원점으로 하여 현실에서 포착한 씬과 연관시켜 미터값으로 반환됩니다 이 최초 검토는 프레임에서 감지된 가장 두드러지는 사람에 대한 골격을 반환하죠 피트니스 앱을 만들어 이 체육관 이미지에서 요청을 한다고 하면 관찰 결과는 카메라에 가장 가까운 여자와 일치하게 될 것입니다 3D 뼈대의 구조를 잘 보여드리기 위해 다음 요가 포즈를 분해해 보겠습니다 당연하게도 3D 신체 골격은 중앙에 있는 점과 머리 상단의 점을 포함하는 머리 그룹으로 시작됩니다 다음은 몸통 그룹인데요 여기에는 어깨 좌우 관절 척추, 루트 관절, 힙 관절이 포함되고 루트 관절은 힙 중앙에 있죠 일부 관절은 다양한 그룹으로 반환된다는 걸 기억하세요 팔의 경우 좌우 팔 그룹이 있고 팔목, 어깨, 팔꿈치가 있습니다 좌우는 인간을 기준으로 말씀드리는 겁니다 이미지의 좌우가 아니라요 마지막으로 좌우 다리 그룹이 있습니다 각각 힙, 무릎, 발목 관절이 있고요 이 새 요청도 다른 요청과 동일한 작업흐름을 따라가세요 이전에 코드에서 Vision을 사용해 보셨다면 익숙할 겁니다 DetectHumanBodyPose3DRequest라는 인스턴스를 만드시고 감지를 원하는 이미지 에셋에 대해 이미지 요청 핸들러를 초기화하시면 됩니다 실행을 위해 요청 인스턴스를 perform 함수에 전달하세요 요청이 성공적이라면 VNHumanBodyPose3DObservation이 오류 없이 반환될 겁니다 모든 사진은 3D 세계의 사람을 2D로 재현합니다 Vision에서는 이제 ARKit이나 ARSession 없이 이미지에서 3D 포지션을 불러오는 게 가능합니다 3D 공간 속 대상을 이해하는 강력하고 가벼운 옵션이며 앱에서 완전히 새로운 기능의 기회를 열어줄 겁니다 이해와 시각화를 돕기 위해 샘플 앱을 만들어 봤는데요 이걸 열면 제 사진첩에서 아무 이미지나 선택 가능합니다
동료들과 저는 앞서 보신 요가 지도자의 평온함에 영감을 받아서 휴식 시간을 가졌습니다 밖에 나가 우리끼리 포즈를 좀 취해봤죠 그 선생님만큼 유연하지는 않지만 이 포즈가 그래도 꽤 괜찮게 나와서 3D에서는 분명 더 멋지게 나올 겁니다
요청을 실행해 저를 3차원으로 가져와 보죠
요청이 성공해서 입력 이미지의 저와 일치하는 3D 골격이 나타났네요 이 씬을 회전시키면 제 팔은 더 길어지고 제가 서 있는 곳을 기반으로 다리도 힙과 잘 맞는 것 같죠 피라미드 모양은 이미지가 캡처됐을 때 카메라의 포지션을 나타냅니다 아래에 있는 Switch Perspective 버튼을 누르면 뷰가 카메라의 포지션에서 보는 것으로 바뀝니다 이제 앱에서 3D 신체 포즈를 사용한 멋진 경험을 선사하도록 관련된 코드와 개념을 안내해 드릴게요
앱 구축은 관찰에서 반환된 점 사용으로 시작됩니다 점을 불러오는 데에는 두 개의 주요 API가 있는데요 특정 관절 포지션에 접근하는 recognizedPoint와 특정 그룹명이 있는 관절들에 접근하는 recognizedPoints가 있습니다 이 핵심 메서드 외에도 관찰 결과는 도움이 되는 추가 정보를 제공합니다 먼저 bodyHeight은 미터로 대상의 측정 높이를 알려줍니다 이 높이는 이용 가능한 깊이 메타데이터에 따라 더 정확한 측정 높이나 1.8m 참조 높이가 됩니다 이 Depth와 Vision에 대해 좀더 말씀드릴게요 여러분은 heightEstimation 프로퍼티를 사용해 높이 계산 사용 기법을 결정할 수 있습니다 다음으로 cameraOriginMatrix를 통해 카메라 포지션을 확인합니다 실제 카메라는 대상을 정확히 바라보고 있지 않을 수 있어서 프레임이 캡처됐을 때 카메라가 그 사람과 어디에서 관련되는지 이해하기에 유용합니다 관찰 결과는 API를 제공해 관절 좌표 2D 투영도 합니다 반환된 값을 입력 이미지에 덮어 씌우고 싶을 때 아주 우용하죠 사람이 비슷한 두 이미지에서 움직이는 방식을 이해하기 위해 API를 이용해서 카메라와 연관된 대상 관절의 포지션을 얻을 수 있습니다
3D 신체 포인트 사용법을 보여드리기 이전에 Vision이 상속한 새 기하 클래스를 소개할게요 VNPoint3D는 3D 포지션 저장을 위해 simd_float 4x4 행렬을 규정하는 기본 클래스입니다 이 표현은 ARKit과 같은 다른 Apple 프레임워크와 일치하고 이용 가능한 회전 및 번역 정보 모두를 포함합니다 다음은 VNRecognizedPoint3D인데요 이 포지션을 상속하기도 하고 식별자를 추가하기도 합니다 관절명과 같은 해당 정보를 저장하기 위해 사용되죠 마지막은 VNHumanBodyRecognizedPoint3D인데요 이건 로컬 포지션과 부모 관절을 추가합니다 이에 대해서 더 자세히 알아보도록 하겠습니다 recognizedPoint API를 사용해서 좌측 팔목 포지션을 불러왔는데요 관절 모델 포지션 즉 포인트의 포지션 프로퍼티는 항상 힙 중앙에 있는 이 루트 포인트와 관련됩니다 포지션 행렬에서 초점을 3열로 가져가 보면 번역된 값이 있습니다 좌측 팔목에 대한 y 값은 피규어 힙 0.9m 위에 있고 딱 이 포즈에 맞아 보이죠 다음으로 반환된 포인트의 localPosition 프로퍼티인데요 이건 부모 관절과 연관되는 포지션입니다 이 경우 좌측 팔꿈치가 좌측 손목의 부모 관절입니다 마지막 열은 값이 x축에 대해 -0.1m 값임을 보여주죠 이것도 맞는 것으로 보입니다 값의 음양은 참조점에 의해 결정됩니다 그리고 이 포즈에서 손목은 팔꿈치의 왼쪽에 있죠 몸의 한 영역에서 작동하는 앱에는 localPosition이 유용합니다 자식 관절과 부모 관절 사이 각 결정도 단순화하고요 코드로 이 각도 계산법을 금방 보여드릴게요 반환된 3D 포인트로 작업하는 것과 관련하여 앱 구축에 도움이 될 만한 개념들이 좀 있습니다 먼저 자식과 부모 관절 사이의 각도를 결정해야 하는데요 calculateLocalAngleToParent 메서드에서 부모 관절과 관련된 포지션은 이 각도를 찾기 위해 사용되죠 노드의 회전은 x, y, z 축 각각의 회전 롤, 피치, 요로 구성됩니다 피치의 경우 아래를 향하는 기본 방향에서 골격에 더 적절한 방향으로 SceneKit 노드 기하를 포지션하기 위해 90도 회전이 사용됩니다 요에서는 적절한 각도를 얻기 위해 벡터 길이로 나뉜 z 좌표의 아크코사인을 사용합니다 롤의 각도 측정 결과는 y, x 좌표의 아크탄젠트로 얻을 수 있고요 이제 제 샘플 앱에서처럼 반환된 3D 포지션을 원본 이미지와 연결해야 할 것입니다 제 시각화에서는 pointInImage API를 통해 이미지 평면의 크기와 번역을 바꿨습니다 이미지 평면을 반환 포인트 비율에 맞게 조절해야 하는데요 3D, 2D 모두에 대해서 어깨 중앙과 척추 간 거리처럼 알려진 두 관절 사이의 거리를 가져오겠습니다 그리고 비율에 맞게 연결해 이미지 평면 크기를 조절할게요 번역 컴포넌트의 경우 pointInImage API를 사용해 2D 이미지에서 루트 관절의 위치를 가져왔죠 이 메서드는 그 위치를 사용해 x, y 축에 대한 이미지 평면의 전환을 결정합니다 VNPoint 좌표의 좌측 하단 원점과 이미지 중앙에 있는 렌더링 환경 좌표를 전환하면서요 마지막으로 카메라의 관점에서 씬을 보고 싶다던가 이 위치에서 포인트를 렌더링하고 싶을 때에는 cameraOriginMatrix에서 이걸 불러오시면 됩니다 올바른 위치는 렌더링 환경에 따라 달라질 겁니다 하지만 저는 피벗 트랜스폼을 사용한 트랜스폼 정보로 노드를 포지션시켰는데요 노드의 로컬 좌표 시스템을 나머지 씬에 연결시켰습니다 cameraOriginMatrix에서는 회전 정보를 사용했고요 인버스 트랜스폼을 사용한 이 코드를 통해 카메라를 바라보게 만들었죠
여기서는 회전 정보만 필요하기 때문에 마지막 열의 번역 정보는 무시됩니다 이 모든 걸 합치면 샘플 앱에 그 씬이 나타나죠 이제 Depth를 포함해 Vision에 추가된 멋진 기능들을 몇 가지 소개하겠습니다 Vision 프레임워크는 이제 이미지나 프레임 버퍼와 함께 '깊이'도 입력 정보로 받아들입니다 VNImageRequestHandler는 AVDepthData에 대해 새 매개변수를 수용하는 cvPixelBuffer, cmSampleBuffer에 대해 초기화 API를 추가했습니다 또한 이미 파일에 Depth 데이터가 포함된 경우 기존 API를 수정 없이 사용할 수 있습니다 그럼 Vision은 파일에서 자동으로 Depth를 가져오죠 Apple SDK에서 Depth 작업 시 AVDepthData는 Depth 메타데이터를 인터페이스하는 컨테이너 클래스 역할을 합니다 카메라 센서가 캡처한 Depth 메타데이터에는 Disparity나 Depth 포맷으로 표현되는 Depth 맵이 포함됩니다 이 포맷은 교체 가능하며 AVFoundation를 사용해 서로 전환도 가능합니다 Depth 메타데이터는 3D 씬 재구축에 필요한 내부, 외부, 렌즈 굴절 등 카메라 교정 데이터도 포함됩니다 구체적으로 알고 싶다면 2022년의 다음 세션을 시청해 보시길 바랍니다 Depth는 카메라 캡처 세션이나 이전 캡처 파일에서 얻을 수 있습니다 인물 사진 모드처럼 카메라 앱에서 캡처된 이미지는 Depth를 디스패리티 맵으로 교정 메타데이터와 저장합니다 라이브 캡처 세션에서 Depth를 캡처하는 경우 디바이스가 지원한다면 세션이 LiDAR를 사용하도록 지정할 수 있는 추가 이득도 있고요 LiDAR는 강력합니다 씬의 정확한 크기와 측정을 가능하게 하거든요 Vision은 한 이미지에서 한 명 이상의 사람이 상호작용할 수 있는 API를 도입할 겁니다
현재 Vision에서는 GeneratePersonSegmentation 요청으로 사람을 주변 씬에서 분리하는 기능을 제공하는데요 프레임 내 모든 사람을 포함한 싱글 마스크를 반환합니다 이제는 새로운 사람의 인스턴스 마스크 요청으로 더 선별적으로 이용할 수 있게 됐습니다 여기서는 사람 4명의 마스크를 산출하는데요 각각 신뢰 점수를 가집니다 이제 이미지 하나에서 친구들을 개별적으로 선택할 수 있습니다 사람 말고 물채를 선택해 꺼내려면 VisionKit에서 대상 리프팅 API나 Vision 프레임워크에서 전경 인스턴스 마스크 요청을 사용할 수 있습니다 더 많은 정보를 원한다면 아래의 세션을 확인해 보세요 이미지에서 원하는 사람의 인스턴스를 고르는 방법을 다음 샘플 코드를 통해 확인해 보세요 현재 이건 모든 인스턴스의 반환을 지정하고 있지만 인스턴스 1과 2 중 선택할 수 있습니다 이미지에서 집중하고픈 친구가 누군지에 따라서요 배경을 얻으려면 인스턴스 0을 사용해야 하죠 이 새 요청은 최대 4인까지 분할합니다 그래서 이미지에 사람이 네 명 이상인 경우 코드에서 처리해야 할 조건문이 이외에도 더 있습니다 씬에 사람이 많을 경우 반환된 관찰 결과는 사람들을 놓치거나 결합할 수 있습니다 보통 이건 배경에 사람들이 존재하는 경우 발생하죠 사람이 바글바글한 씬을 처리해야 하는 경우 가능한 한 최고의 경험을 위해 사용할 수 있는 전략이 있는데요 Vision의 얼굴 인식 API는 이미지 얼굴 수를 셀 수 있죠 그래서 사람이 4명 이상 있는 이미지는 넘길 수도 있습니다 아니면 기존의 Person Segmentation 요청을 사용해 모두에 대해 하나의 마스크를 가지게 할 수도 있고요
Vision은 이제 Depth의 도움으로 사람과 환경을 이해하는 강력한 방법을 제공합니다 3D 인간 신체 포즈와 사람의 인스턴스 마스크 말이죠 하지만 올해 Vision은 더 많은 걸 선사할 겁니다 다음 세션에서는 사람을 넘어 털복숭이 친구들의 이미지로 놀라운 경험을 선사해 보도록 하죠 감사합니다, 멋진 결과물 기다리고 있겠습니다 ♪ ♪
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.