Table of Contents

Requisitos de dados do frame de entrada para fontes externas de dados de frame

Para que uma fonte externa de dados de frame funcione corretamente, a tarefa mais importante e também a parte mais difícil é garantir a correção dos dados. Este artigo descreve os requisitos de dados do frame de entrada para fontes externas de dados de frame.

Antes de começar

Tipos de dados do frame de entrada

No Unity, uma fonte externa de dados de frame normalmente precisa receber dados diferentes em dois momentos diferentes. De acordo com o tempo de entrada dos dados externos e as características dos dados, esses dois grupos de dados são chamados de:

  1. dados do frame da câmera (camera frame data)
  2. dados do frame de renderização (rendering frame data)

Diferentes tipos de fontes externas de dados de frame têm requisitos diferentes para esses dois grupos de dados:

  • Extensão de entrada de dados de imagem e movimento do dispositivo: requer dados do frame da câmera e dados do frame de renderização
  • Extensão de entrada de imagem: requer apenas dados do frame da câmera

Dados do frame da câmera

Requisitos de dados:

  1. timestamp
  2. dados brutos de imagem da câmera física (raw camera image data)
  3. intrínsecos (intrinsics, incluindo tamanho da imagem, distância focal e ponto principal. Se houver distorção, o modelo e os parâmetros de distorção também são necessários)
  4. extrínsecos (extrinsics, Tcw ou Twc, matriz calibrada que expressa o deslocamento físico da câmera física em relação ao pose origin do dispositivo/cabeça)
  5. status de rastreamento (tracking status)
  6. pose do dispositivo (device pose)

Tempo dos dados:

  • Ponto médio da exposição da câmera física

Uso dos dados:

  • Tempo de chamada da API: pode variar de acordo com o design do código externo. Um método comum usado pela maioria dos dispositivos é consultar durante a atualização de renderização do 3D engine e então decidir, de acordo com o timestamp dos dados do dispositivo, se os dados serão processados adicionalmente
  • Thread de chamada da API: o game thread do 3D engine, ou qualquer outro thread se todas as APIs externas usadas forem thread-safe

O exemplo de chamada de API no Unity é o seguinte:

void TryInputCameraFrameData()
{
    double timestamp;

    if (timestamp == curTimestamp) { return; }
    curTimestamp = timestamp;

    PixelFormat format;
    Vector2Int size;
    Vector2Int pixelSize;
    int bufferSize;

    var bufferO = TryAcquireBuffer(bufferSize);
    if (bufferO.OnNone) { return; }
    var buffer = bufferO.Value;

    IntPtr imageData;
    buffer.tryCopyFrom(imageData, 0, 0, bufferSize);

    var historicalHeadPose = new Pose();
    MotionTrackingStatus trackingStatus = (MotionTrackingStatus)(-1);

    using (buffer)
    using (var image = Image.create(buffer, format, size.x, size.y, pixelSize.x, pixelSize.y))
    {
        HandleCameraFrameData(deviceCamera, timestamp, image, cameraParameters, historicalHeadPose, trackingStatus);
    }
}

Renderizar frame data

Requisitos de dados:

  1. Timestamp
  2. Tracking status
  3. Device pose

Tempo dos dados:

  • Momento de apresentação na tela. TimeWarp não é incluído. Os dados de device pose no mesmo momento serão usados externamente, por exemplo pelo device SDK, para definir o transform da câmera virtual ao renderizar o frame atual.
Nota

TimeWarp, às vezes também chamado de Reprojection ou ATW/PTW, é uma técnica comum em headsets VR/AR para reduzir latência. Depois que a renderização é concluída, ela distorce novamente a imagem de acordo com a pose de cabeça mais recente para compensar o movimento da cabeça gerado durante a renderização. O que o EasyAR precisa é o momento correspondente à pose usada para definir a câmera virtual no início da renderização, não o momento real de apresentação na tela após o TimeWarp.

Uso dos dados:

  • Tempo de chamada da API: cada frame de renderização do 3D engine
  • Thread de chamada da API: o game thread do 3D engine

O exemplo de chamada de API no Unity é o seguinte:

private void InputRenderFrameMotionData()
{
    double timestamp = 0e-9;
    var headPose = new Pose();
    MotionTrackingStatus trackingStatus = (MotionTrackingStatus)(-1);
    HandleRenderFrameData(timestamp, headPose, trackingStatus);
}

Detalhes dos requisitos de dados

Dados de imagem da câmera física:

  • Sistema de coordenadas da imagem: os dados adquiridos quando o sensor está horizontal também devem ser horizontais. Os dados devem usar o canto superior esquerdo como origin e ser armazenados em ordem row-major. A imagem não deve ser espelhada nem invertida.
  • FPS da imagem: dados normais de 30 ou 60 fps são aceitáveis. Se fps alto tiver impacto especial, a taxa mínima de frames aceitável para obter resultados razoáveis do algoritmo é 2. Recomenda-se usar fps acima de 2; normalmente a taxa de frames original dos dados pode ser usada.
  • Tamanho da imagem: para obter melhores resultados de cálculo, o lado mais longo deve ser 960 ou maior. Normalmente não se recomenda fazer redimensionamento de imagem demorado na cadeia de dados. Recomenda-se usar diretamente os dados originais, a menos que o tempo de cópia dos dados em tamanho completo já seja inaceitavelmente longo. A resolução da imagem não pode ser menor que 640*480.
  • Formato de pixel: priorizando o efeito de rastreamento e considerando desempenho, a ordem de preferência comum é YUV > RGB > RGBA > Gray (o componente Y em YUV). Ao usar dados YUV, é necessária uma definição completa dos dados, incluindo detalhes de empacotamento e padding. Em comparação com imagens de canal único, imagens coloridas dão melhores resultados no Mega, mas têm pouco efeito em outros recursos.
  • Acesso aos dados: ponteiro de dados ou implementação equivalente. É melhor eliminar todas as cópias possivelmente desnecessárias na cadeia de dados. Em HandleRenderFrameData, o EasyAR copia uma cópia dos dados e depois a usa de forma assíncrona. Depois que a chamada síncrona termina, os dados de imagem não são mais usados. Preste atenção à propriedade dos dados.

Timestamps:

  • Todos os timestamps devem estar sincronizados por relógio, preferencialmente por hardware. A unidade dos dados é segundos, mas a precisão deve chegar a nanossegundos ou ser a mais alta possível.

Status de tracking:

  • O status de tracking é definido pelo dispositivo e deve incluir o estado de tracking perdido, quando VIO não está disponível. Se houver mais níveis, melhor.

Pose do dispositivo:

  • Todas as pose, incluindo o transform da câmera virtual no motor 3D, devem usar a mesma origem.
  • Todas as pose e extrinsics devem usar o mesmo sistema de eixos de coordenadas.
  • No Unity, o tipo de sistema de eixos de coordenadas dos dados de pose deve ser o sistema de eixos do Unity ou do EasyAR. Se a input extension for implementada pelo EasyAR e usar outra definição de sistema de eixos, forneça uma definição clara ou um método de conversão para o sistema do Unity ou do EasyAR.
  • No Unity, se o framework Unity XR for usado, basta compatibilidade com o modo XROrigin.TrackingOriginMode.Device.

Intrinsics:

  • Todos os valores devem corresponder aos dados da imagem. Se necessário, escale os intrinsics antes de inseri-los no EasyAR.
  • Se a input extension for implementada pelo EasyAR, indique se os intrinsics mudam a cada frame, pois isso determina se a API correspondente deve ser chamada uma vez ou a cada frame.

Extrinsics:

  • Em headsets, dados reais devem ser fornecidos.
  • Esta é uma matriz de calibração que expressa o offset físico da câmera física em relação à origem da pose do dispositivo/cabeça. Se a pose do dispositivo e a pose da câmera física forem iguais, ela deve ser uma matriz identidade.
  • A interface correspondente do Apple Vision Pro é CameraFrame.Sample.Parameters.extrinsics. Observe que sua definição de dados difere dos dados exigidos pela interface, e o EasyAR a usa internamente após conversão.
  • No Unity, o tipo de sistema de eixos de coordenadas dos extrinsics deve ser o sistema do Unity ou do EasyAR. Se a input extension for implementada pelo EasyAR e usar outra definição de sistema de eixos, forneça uma definição clara ou um método de conversão para o sistema do Unity ou do EasyAR.
  • Em dispositivos headset, geralmente existem vários sistemas de coordenadas com definições diferentes, incluindo diferenças de origem, orientação e representação canhota/destra. Extrinsics devem ser calculados no mesmo sistema de coordenadas. Os dados desta interface exigem transformação de coordenadas dentro do mesmo sistema, não uma matriz de transformação entre dois sistemas com definições diferentes.

Desempenho:

  • Os dados devem ser fornecidos com eficiência ideal. Na maioria das implementações, chamadas de API ocorrem durante a renderização; portanto, mesmo que operações demoradas sejam necessárias em camada inferior, não bloqueie chamadas de API ou use essas APIs de forma razoável.
  • Se a input extension for implementada pelo EasyAR, descreva todas as chamadas de API demoradas.

Multi-câmera:

  • Dados de pelo menos uma câmera são necessários. Essa câmera pode ser RGB, VST, de localização etc. Em headsets, se apenas dados de uma câmera forem inseridos, normalmente recomenda-se usar uma câmera RGB ou VST no centro ou perto dos olhos.
  • Usar várias câmeras pode melhorar o resultado do algoritmo EasyAR. Os dados de frame de todas as câmeras disponíveis em um determinado momento devem ser inseridos simultaneamente no mesmo ponto temporal.

Multi-câmera ainda não é totalmente suportado. Entre em contato com EasyAR para mais detalhes.

Próximas etapas

Tópicos relacionados