Câmera ao vivo com Vision
VisionPoseProvider (módulo KinesiaMotionVision, só iOS) abre a câmera, roda o detector de corpo 2D do Vision em cada quadro e entrega poses que já cumprem o contrato de Pose.
import KinesiaMotionVision
let camera = VisionPoseProvider( camera: .front, // .front ou .back minimumConfidence: 0.3 // pontos abaixo disso são descartados)Permissão
Seção intitulada “Permissão”if !VisionPoseProvider.isAuthorized { let granted = await VisionPoseProvider.requestAccess() guard granted else { // Mostre como ativar a câmera nos Ajustes return }}Lembre-se da chave NSCameraUsageDescription no Info.plist (Instalação).
Ciclo de vida
Seção intitulada “Ciclo de vida”A câmera liga sozinha quando alguém começa a iterar poses() e desliga sozinha quando para. Com MotionSession isso significa:
session.start(with: camera) // ligasession.stop() // desligaNão é preciso chamar startRunning() nem stopRunning() em captureSession.
Mostrar a imagem
Seção intitulada “Mostrar a imagem”captureSession é um AVCaptureSession comum: passe-o a um AVCaptureVideoPreviewLayer. O exemplo completo de CameraPreview para SwiftUI está no início rápido.
Com a câmera frontal a pré-visualização aparece espelhada (como um espelho), mas as poses trazem os lados reais do paciente. Se desenhar os pontos por cima, espelhe o x ao desenhar, não ao medir.
O que faz por dentro
Seção intitulada “O que faz por dentro”- Resolução VGA (640×480): suficiente para o detector e leve para a bateria.
- Descarta quadros atrasados: se seu código estiver lento, você sempre recebe a pose mais nova.
- Converte as coordenadas do Vision (normalizadas, origem embaixo) para pixels com
ypara baixo, numa imagem vertical. - Com a câmera frontal troca esquerda e direita.
- Também envia poses vazias quando não detecta ninguém.
Os dois lados com uma câmera
Seção intitulada “Os dois lados com uma câmera”É assim que o app da Kinesia faz: uma câmera, uma sessão por lado.
let camera = VisionPoseProvider(camera: .front)let left = MotionSession(exercise: exercise, side: .left)let right = MotionSession(exercise: exercise, side: .right)
let task = Task { @MainActor in for await pose in camera.poses() { left.process(pose) right.process(pose) }}// Para terminar: task.cancel() → a câmera desliga