Metadados XMP de Photo Spheres

O espaço de nome de panorama descrito neste documento contém propriedades que fornecem informações relacionadas à criação e à renderização de photo spheres, também conhecidas como panoramas, como as criadas pelo recurso Photo Sphere da câmera do Android 4.2. Os metadados devem ser serializados e incorporados na photo sphere, conforme descrito pelo Adobe XMP (consulte as referências no final desta página).

O URI do namespace é http://ns.google.com/photos/1.0/panorama/

Propriedades de metadados

O diagrama e a tabela abaixo mostram as propriedades de uma photo sphere. Os desenvolvedores que criam esses metadados devem seguir as convenções de ângulo de Euler apresentadas posteriormente neste documento. Os desenvolvedores que editam e visualizam as photo spheres devem confirmar e atualizar os metadados adequadamente, conforme descrito posteriormente neste documento.

Nome Tipo Obrigatório Valor padrão
(visualizador presumido)
Descrição da propriedade Ação necessária se a imagem for modificada
GPano:UsePanoramaViewer Booleano Não True Se a imagem deve ser mostrada em um visualizador de photo sphere em vez de como uma imagem plana normal. Pode ser especificado com base nas preferências do usuário ou pelo software de montagem. O aplicativo que exibe ou ingere a imagem pode optar por ignorar isso. redimensionar/cortar:
nenhuma alteração. Um aplicativo pode decidir alterar esse valor para False se o campo de visão estiver abaixo de um determinado valor.
GPano:CaptureSoftware String Não n/a Se a captura for realizada com um aplicativo para dispositivo móvel, como um celular Android, o nome do aplicativo usado (como “Photo Sphere”). Deve ser deixado em branco se as imagens de origem forem capturadas manualmente, como com o uso de uma DSLR em um tripé. n/a
GPano:StitchingSoftware String Não n/a O software usado para criar a photo sphere final. Pode ter o mesmo valor de  GPano:CaptureSoftware. n/a
GPano:ProjectionType Escolha livre de texto Sim

equirectangular

Tipo de projeção usado no arquivo de imagem. No momento, os produtos do Google permitem o valor equirretangular. redimensionar/cortar: nenhuma alteração.
GPano:PoseHeadingDegrees Número real Não, mas é obrigatório para exibição no Google Maps n/a Direção da bússola, medida em graus, em relação ao centro da imagem. O valor deve ser >= 0 e < 360. redimensionar/cortar: nenhuma alteração.
GPano:PosePitchDegrees Número real Não 0 Inclinação, medida em graus, em relação ao centro da imagem. O valor deve ser >= -90 e < 90. redimensionar/cortar: nenhuma alteração.
GPano:PoseRollDegrees Número real Não 0 Rolagem, medida em graus, da imagem em que o nivelamento com o horizonte é 0. O valor deve ser > -180 e <= 180. redimensionar/cortar: nenhuma alteração.
GPano:InitialViewHeadingDegrees Número inteiro Não 0 O ângulo da direção da visualização inicial, em graus. redimensionar/cortar: nenhuma alteração.
GPano:InitialViewPitchDegrees Número inteiro Não 0 O ângulo de inclinação da visualização inicial, em graus. redimensionar/cortar: nenhuma alteração.
GPano:InitialViewRollDegrees Número inteiro Não 0 O ângulo de rolagem da visualização inicial, em graus. redimensionar/cortar: nenhuma alteração.
GPano:InitialHorizontalFOVDegrees Número real Não n/a O campo horizontal inicial da visualização que deve ser apresentada ao usuário (em graus). Similar ao nível de zoom. n/a
GPano:FirstPhotoDate Data Não n/a A data e a hora da primeira imagem criada na photo sphere. redimensionar/cortar: nenhuma alteração.
GPano:LastPhotoDate Data Não n/a A data e a hora da última imagem criada na photo sphere. redimensionar/cortar: nenhuma alteração.
GPano:SourcePhotosCount Número inteiro Não n/a Número de imagens de origem usadas para criar a photo sphere. redimensionar/cortar: nenhuma alteração.
GPano:ExposureLockUsed Booleano Não n/a Se a configuração de exposição da câmera estava bloqueada quando as fotografias de origem individuais foram capturadas. n/a
GPano:CroppedAreaImageWidthPixels Número inteiro Sim n/a Largura original da imagem em pixels (igual à largura da imagem real para imagens não editadas). redimensionar/cortar: essa propriedade precisa ser atualizada para refletir o novo tamanho da imagem.
GPano:CroppedAreaImageHeightPixels Número inteiro Sim n/a Altura original da imagem em pixels (igual à altura da imagem real para imagens não editadas). redimensionar/cortar: essa propriedade precisa ser atualizada para refletir o novo tamanho da imagem.
GPano:FullPanoWidthPixels Número inteiro Sim n/a Largura original total a partir da qual a imagem foi cortada. Se somente uma photo sphere parcial foi capturada, essa propriedade especifica a largura total que a photo sphere teria. cortar: nenhuma alteração.
redimensionar: essa propriedade deve ser dimensionada apropriadamente.
GPano:FullPanoHeightPixels Número inteiro Sim n/a Altura original total a partir da qual a imagem foi cortada. Se somente uma photo sphere parcial foi capturada, essa propriedade especifica a altura total que a photo sphere teria. cortar: nenhuma alteração.
redimensionar: essa propriedade deve ser dimensionada apropriadamente.
GPano:CroppedAreaLeftPixels Número inteiro Sim n/a Coluna onde a borda esquerda da imagem foi cortada a partir da photo sphere de tamanho original. cortar: se o corte esquerdo da imagem foi alterado, esse valor deve ser atualizado.
redimensionar: essa propriedade deve ser dimensionada apropriadamente.
GPano:CroppedAreaTopPixels Número inteiro Sim n/a Linha onde a borda superior da imagem foi cortada a partir da photo sphere de tamanho original. cortar: se o corte superior da imagem foi alterado, esse valor deve ser atualizado.
redimensionar: essa propriedade deve ser dimensionada apropriadamente.
GPano:InitialCameraDolly Número real Não 0 Esse parâmetro opcional move a posição da câmera virtual ao longo da linha de visão para longe do centro da photo sphere. Uma posição de superfície traseira é representada pelo valor -1.0 e uma posição de superfície frontal é representada por 1.0. Para visualização normal, esse parâmetro deve ser definido como 0. n/a

Exemplo de uma photo sphere completa

Não programadores podem adicionar o exemplo de metadados abaixo a photo spheres completas (360 graus x 180 graus) com apenas algumas pequenas modificações. Isso pode ser feito em produtos de edição de imagem, como o Adobe Photoshop.

  1. altere qualquer ocorrência de 4000 e 2000 para igualar os valores à largura e à altura da sua imagem em pixels
  2. atualize PoseHeadingDegrees se quiser que o Google Maps consiga exibir sua photo sphere; caso contrário, esse parâmetro pode ser removido
  3. atualize ou remova parâmetros opcionais (conforme listagem acima)
<rdf:Description rdf:about="" xmlns:GPano="http://ns.google.com/photos/1.0/panorama/">
    <GPano:UsePanoramaViewer>True</GPano:UsePanoramaViewer>
    <GPano:CaptureSoftware>Photo Sphere</GPano:CaptureSoftware>
    <GPano:StitchingSoftware>Photo Sphere</GPano:StitchingSoftware>
    <GPano:ProjectionType>equirectangular</GPano:ProjectionType>
    <GPano:PoseHeadingDegrees>350.0</GPano:PoseHeadingDegrees>
    <GPano:InitialViewHeadingDegrees>90.0</GPano:InitialViewHeadingDegrees>
    <GPano:InitialViewPitchDegrees>0.0</GPano:InitialViewPitchDegrees>
    <GPano:InitialViewRollDegrees>0.0</GPano:InitialViewRollDegrees>
    <GPano:InitialHorizontalFOVDegrees>75.0</GPano:InitialHorizontalFOVDegrees>
    <GPano:CroppedAreaLeftPixels>0</GPano:CroppedAreaLeftPixels>
    <GPano:CroppedAreaTopPixels>0</GPano:CroppedAreaTopPixels>
    <GPano:CroppedAreaImageWidthPixels>4000</GPano:CroppedAreaImageWidthPixels>
    <GPano:CroppedAreaImageHeightPixels>2000</GPano:CroppedAreaImageHeightPixels>
    <GPano:FullPanoWidthPixels>4000</GPano:FullPanoWidthPixels>
    <GPano:FullPanoHeightPixels>2000</GPano:FullPanoHeightPixels>
    <GPano:FirstPhotoDate>2012-11-07T21:03:13.465Z</GPano:FirstPhotoDate>
    <GPano:LastPhotoDate>2012-11-07T21:04:10.897Z</GPano:LastPhotoDate>
    <GPano:SourcePhotosCount>50</GPano:SourcePhotosCount>
    <GPano:ExposureLockUsed>False</GPano:ExposureLockUsed>
</rdf:Description>

Exemplo de uma photo sphere parcial

<rdf:Description rdf:about="" xmlns:GPano="http://ns.google.com/photos/1.0/panorama/">
    <GPano:UsePanoramaViewer>True</GPano:UsePanoramaViewer>
    <GPano:CaptureSoftware>Photo Sphere</GPano:CaptureSoftware>
    <GPano:StitchingSoftware>Photo Sphere</GPano:StitchingSoftware>
    <GPano:ProjectionType>equirectangular</GPano:ProjectionType>
    <GPano:PoseHeadingDegrees>350.0</GPano:PoseHeadingDegrees>
    <GPano:InitialViewHeadingDegrees>90.0</GPano:InitialViewHeadingDegrees>
    <GPano:InitialViewPitchDegrees>0.0</GPano:InitialViewPitchDegrees>
    <GPano:InitialViewRollDegrees>0.0</GPano:InitialViewRollDegrees>
    <GPano:InitialHorizontalFOVDegrees>75.0</GPano:InitialHorizontalFOVDegrees>
    <GPano:CroppedAreaLeftPixels>90</GPano:CroppedAreaLeftPixels>
    <GPano:CroppedAreaTopPixels>128</GPano:CroppedAreaTopPixels>
    <GPano:CroppedAreaImageWidthPixels>2300</GPano:CroppedAreaImageWidthPixels>
    <GPano:CroppedAreaImageHeightPixels>1042</GPano:CroppedAreaImageHeightPixels>
    <GPano:FullPanoWidthPixels>4000</GPano:FullPanoWidthPixels>
    <GPano:FullPanoHeightPixels>2000</GPano:FullPanoHeightPixels>
    <GPano:FirstPhotoDate>2012-11-07T21:03:13.465Z</GPano:FirstPhotoDate>
    <GPano:LastPhotoDate>2012-11-07T21:04:10.897Z</GPano:LastPhotoDate>
    <GPano:SourcePhotosCount>50</GPano:SourcePhotosCount>
    <GPano:ExposureLockUsed>False</GPano:ExposureLockUsed>
</rdf:Description>

Robustez para edição de imagem

Para serem robustos, programas que exibem photo spheres em um visualizador devem verificar se a photo sphere original foi dimensionada por um aplicativo sem atualizar os metadados. Isso pode ser feito com as etapas a seguir:

  1. garanta que a tag CroppedAreaImageWidthPixels seja equivalente à largura real da imagem
  2. garanta que a tag CroppedAreaImageHeightPixels seja equivalente à altura real da imagem
  3. se a etapa 1 ou 2 falhar, verifique se a proporção da imagem foi preservada
  4. se a etapa 3 falhar, não exiba a imagem como uma photo sphere, pois ela foi transformada de forma incompatível e ficará gravemente distorcida
  5. se a etapa 3 for bem-sucedida, a proporção da imagem é equivalente e os valores das seguintes tags associadas devem ser dimensionados de acordo com o novo tamanho da imagem:
    CroppedAreaImageWidthPixels, CroppedAreaImageHeightPixels, FullPanoWidthPixels, FullPanoHeightPixels, CroppedAreaLeftPixels, CroppedAreaRightPixels.

Visão geral dos ângulos de Euler

A orientação da photo sphere no quadro global é definida por ângulos de Euler. Ângulos de Euler podem ser definidos de muitas maneiras. Para estar correto, um programa deve seguir rigidamente as convenções dos ângulos de Euler descritas neste documento.

A posição acima da superfície da terra define um "quadro local" XYZ fixo, onde Z é superior e ortogonal em relação à superfície da terra, X é o leste verdadeiro e Y é o norte verdadeiro. A orientação é definida em relação a esse "quadro local" fixo e os ângulos de Euler são as rotações em torno desses ângulos XYZ fixos.  A orientação de posição, portanto, é indefinida nos polos. Isso significa que uma photo sphere com ângulos (0, 0, 0) será orientada de forma que o pixel central esteja voltado ao norte, com o equador da photo sphere paralelo à superfície da terra.

Os ângulos de Euler fornecem mapeamento dos pontos no "quadro da photo sphere" (girado) para os pontos no "quadro local" (fixo):
 
Uma matriz de rotação é criada a partir dos ângulos de Euler da seguinte maneira (é importante preservar esta ordem):

R = R_Z(-heading) * R_X(pitch) * R_Y(roll)

onde: R_*(t) é uma rotação à direita em torno do eixo nomeado:

    R_Z(angle) = [ cos(angle), -sin(angle),  0
                   sin(angle),  cos(angle),  0
                   0,       0,  1 ]
 
    R_X(angle) = [ 1,       0,      0,
                   0,  cos(angle), -sin(angle),
                   0,  sin(angle),  cos(angle) ]
 
    R_Y(angle) = [ cos(angle),  0,  sin(angle),
                   0,  1,       0,
                   -sin(angle),  0,  cos(angle) ]

and where: Z = Up, X = East, Y = North.

É importante preservar esta ordem:

R = R_Z(-heading) * R_X(pitch) * R_Y(roll)

pois as rotações não são comutativas.

Observe que o ângulo de direção equivale ao ângulo de bússola padrão.

Referências

Padrão Adobe XMP: http://www.adobe.com/devnet/xmp.html