Solução de problemas

Caminho binário do Python ausente

A mensagem de erro:

ERROR: An error occurred during the fetch of repository 'local_execution_config_python':
  Traceback (most recent call last):
       File "/sandbox_path/external/org_tensorflow/third_party/py/python_configure.bzl", line 208
               get_python_bin(repository_ctx)
    ...
Repository command failed

geralmente indica que o Bazel não consegue encontrar o binário local do Python. Para resolver esse problema, primeiro descubra onde o binário Python está e adicione --action_env PYTHON_BIN_PATH=<path to python binary> ao comando do Bazel. Por exemplo, é possível alternar para usar o binário python3 padrão do sistema com o seguinte comando:

bazel build -c opt \
  --define MEDIAPIPE_DISABLE_GPU=1 \
  --action_env PYTHON_BIN_PATH=$(which python3) \
  mediapipe/examples/desktop/hello_world

Ausência de pacotes Python necessários

A mensagem de erro:

ImportError: No module named numpy
Is numpy installed?

geralmente indica que alguns pacotes Python não estão instalados. Execute pip install ou pip3 install, dependendo da sua versão binária do Python, para instalar esses pacotes.

Falha ao buscar repositórios de dependência remotas

A mensagem de erro:

ERROR: An error occurred during the fetch of repository 'org_tensorflow':
   java.io.IOException: Error downloading [https://mirror.bazel.build/github.com/tensorflow/tensorflow/archive/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz, https://github.com/tensorflow/tensorflow/archive/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz] to /sandbox_path/external/org_tensorflow/77e9ffb9b2bfb1a4f7056e62d84039626923e328.tar.gz: Tried to reconnect at offset 9,944,151 but server didn't support it

or

WARNING: Download from https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/rules_swift/releases/download/0.12.1/rules_swift.0.12.1.tar.gz failed: class java.net.ConnectException Connection timed out (Connection timed out)

geralmente indica que o Bazel não faz o download dos repositórios de dependência necessários de que o MediaPipe precisa. O MedaiPipe tem vários repositórios de dependência hospedados por sites do Google. Em algumas regiões, pode ser necessário configurar um proxy de rede ou usar uma VPN para acessar esses recursos. Talvez também seja necessário anexar --host_jvm_args "-DsocksProxyHost=<ip address> -DsocksProxyPort=<port number>" ao comando do Bazel. Veja este problema no GitHub (em inglês) para saber mais.

Se você acredita que não é um problema de rede, outra possibilidade é que alguns recursos estejam temporariamente indisponíveis. Execute bazel clean --expunge e tente de novo mais tarde. Se ainda não funcionar, registre um problema no GitHub com a mensagem de erro detalhada.

Configuração incorreta do MediaPipe OpenCV

A mensagem de erro:

error: undefined reference to 'cv::String::deallocate()'
error: undefined reference to 'cv::String::allocate(unsigned long)'
error: undefined reference to 'cv::VideoCapture::VideoCapture(cv::String const&)'
...
error: undefined reference to 'cv::putText(cv::InputOutputArray const&, cv::String const&, cv::Point, int, double, cv::Scalar, int, int, bool)'

geralmente indica que o OpenCV não está configurado corretamente para o MediaPipe. Consulte as seções "Instalar OpenCV e FFmpeg" em Instalação para ver como modificar os arquivos WORKSPACE e linux_opencv/macos_opencv/windows_opencv.BUILD para suas bibliotecas opencv locais. Este problema do GitHub também pode ajudar.

Falha na instalação do pip do Python

A mensagem de erro:

ERROR: Could not find a version that satisfies the requirement mediapipe
ERROR: No matching distribution found for mediapipe

após a execução de pip install mediapipe, isso geralmente indica que não há MediaPipe Python qualificado para seu sistema. O MediaPipe Python PyPI é oficialmente compatível com a versão de 64 bits do Python 3.7 a 3.10 no seguinte SO:

  • Linux x86_64
  • x86_64 macOS 10.15 ou mais recente
  • Windows amd64

Se o SO for compatível e você ainda vir esse erro, verifique se o binário Python e pip são para Python 3.7 a 3.10. Caso contrário, considere criar o pacote MediaPipe Python localmente seguindo as instruções aqui.

Falha ao carregar DLLs do Python no Windows

A mensagem de erro:

ImportError: DLL load failed: The specified module could not be found

geralmente indica que o sistema local do Windows não tem pacotes redistribuíveis do Visual C++ e/ou DLLs do ambiente de execução do Visual C++. Isso pode ser resolvido com a instalação do vc_redist.x64.exe oficial ou com a instalação do pacote Python "msvc-runtime" executando

$ python -m pip install msvc-runtime

O pacote "msvc-runtime" do Python não foi lançado nem mantido pela Microsoft.

Método nativo não encontrado

A mensagem de erro:

java.lang.UnsatisfiedLinkError: No implementation found for void com.google.wick.Wick.nativeWick

geralmente indica que uma biblioteca nativa necessária, como /libwickjni.so, não foi carregada ou não foi incluída nas dependências do app ou não pode ser encontrada por algum motivo. Observe que o Java exige que todas as bibliotecas nativas sejam carregadas explicitamente usando a função System.loadLibrary.

Nenhuma calculadora registrada foi encontrada

A mensagem de erro:

No registered object with name: OurNewCalculator; Unable to find Calculator "OurNewCalculator"

geralmente indica que OurNewCalculator é referenciado por nome em um CalculatorGraphConfig, mas que o destino da biblioteca para OurNewCalculator não foi vinculado ao binário do aplicativo. Quando uma nova calculadora é adicionada a um gráfico da calculadora, ela também precisa ser incluída como uma dependência de build dos aplicativos que usam esse gráfico.

Esse erro é detectado no momento da execução porque os gráficos de calculadora fazem referência a elas pelo nome no campo CalculatorGraphConfig::Node:calculator. Quando a biblioteca de uma calculadora é vinculada a um binário do aplicativo, a calculadora é registrada automaticamente pelo nome usando a macro REGISTER_CALCULATOR usando a biblioteca registration.h. Observe que REGISTER_CALCULATOR pode registrar uma calculadora com um prefixo de namespace, idêntico ao namespace C++. Nesse caso, o gráfico da calculadora também precisa usar o mesmo prefixo de namespace.

Erro de falta de memória

O esgotamento da memória pode ser um sintoma de muitos pacotes acumulando em um gráfico do MediaPipe em execução. Isso pode ocorrer por vários motivos, como:

  1. Algumas calculadoras no gráfico simplesmente não conseguem acompanhar a chegada de pacotes de um stream de entrada em tempo real, como uma câmera de vídeo.
  2. Algumas calculadoras estão esperando pacotes que não vão chegar.

Para o problema (1), pode ser necessário descartar alguns pacotes antigos em pacotes mais antigos para processar os mais recentes. Para conferir algumas dicas, consulte How to process realtime input streams.

Para o problema (2), pode ser que um stream de entrada não tenha pacotes por algum motivo. Um dispositivo ou uma calculadora pode ser configurado incorretamente ou produzir pacotes apenas esporadicamente. Isso pode fazer com que as calculadoras downstream aguardem muitos pacotes que nunca chegarão, o que, por sua vez, faz com que os pacotes se acumulem em alguns dos streams de entrada. O MediaPipe resolve esse tipo de problema usando "limites de carimbo de data/hora". Para conferir algumas dicas, consulte How to process realtime input streams.

A configuração CalculatorGraphConfig::max_queue_size do MediaPipe limita o número de pacotes enfileirados em qualquer stream de entrada limitando as entradas no gráfico. Para streams de entrada em tempo real, o número de pacotes em fila em um stream de entrada quase sempre deve ser zero ou um. Se esse não for o caso, você poderá ver a seguinte mensagem de aviso:

Resolved a deadlock by increasing max_queue_size of input stream

Além disso, a configuração CalculatorGraphConfig::report_deadlock pode ser definida para fazer com que a execução do gráfico falhe e exiba o impasse como um erro, de modo que max_queue_size aja como um limite de uso de memória.

O gráfico trava

Muitos aplicativos chamam CalculatorGraph::CloseAllPacketSources e CalculatorGraph::WaitUntilDone para finalizar ou suspender a execução de um gráfico do MediaPipe. O objetivo é permitir que calculadoras ou pacotes pendentes concluam o processamento e depois encerrem o gráfico. Se tudo correr bem, todos os fluxos no gráfico alcançarão Timestamp::Done e todas as calculadoras alcanrão CalculatorBase::Close, e então CalculatorGraph::WaitUntilDone será concluído.

Se algumas calculadoras ou streams não atingirem o estado Timestamp::Done ou CalculatorBase::Close, o método CalculatorGraph::Cancel pode ser chamado para encerrar a execução do grafo sem esperar a conclusão de todas as calculadoras e pacotes pendentes.

O tempo de saída é irregular

Alguns gráficos do MediaPipe em tempo real produzem uma série de frames de vídeo para visualização como um efeito de vídeo ou como um diagnóstico de vídeo. Às vezes, um gráfico do MediaPipe produz esses frames em clusters, por exemplo, quando vários frames de saída são extrapolados do mesmo cluster de frames de entrada. Se as saídas forem apresentadas conforme são produzidas, alguns frames de saída serão imediatamente substituídos por outros posteriores no mesmo cluster, o que dificulta a visualização e a avaliação dos resultados. Nesses casos, a visualização de saída pode ser aprimorada com a apresentação dos frames em intervalos regulares e em tempo real.

O MediaPipe resolve esse caso de uso mapeando os carimbos de data/hora para pontos em tempo real. Cada carimbo de data/hora indica um horário em microssegundos, e uma calculadora como LiveClockSyncCalculator pode atrasar a saída de pacotes para corresponder aos carimbos de data/hora. Esse tipo de calculadora ajusta o tempo dos resultados para que:

  1. O tempo entre as saídas corresponde ao tempo entre os carimbos de data/hora o mais próximo possível.
  2. As saídas são produzidas com o menor atraso possível.

Atrasos das entradas do CalculatorGraph

Para muitos gráficos do MediaPipe em tempo real, a baixa latência é um objetivo. O MediaPipe oferece suporte ao processamento paralelo de estilo "pipeline" para iniciar o processamento de cada pacote o mais cedo possível. Normalmente, a menor latência possível é o tempo total exigido por cada calculadora em um "caminho crítico" de cálculos sucessivos. A latência de um gráfico MediaPipe pode ser pior do que o ideal devido a atrasos introduzidos para exibir frames em intervalos pares, conforme descrito em O tempo de saída é irregular.

Se algumas das calculadoras no gráfico não acompanharem os streams de entrada em tempo real, a latência continuará aumentando, e será necessário descartar alguns pacotes de entrada. A técnica recomendada é usar as calculadoras do MediaPipe criadas especificamente para essa finalidade, como o FlowLimiterCalculator, conforme descrito em How to process realtime input streams.