Quem sou eu e o que este blog.

quinta-feira, 3 de novembro de 2016

Perda de data em câmeras

Sim, uma câmera pode perder a data, e isto pode gerar um bando de inconveniências, especialmente quanto à catalogação, tal como eu faço com grande rigor.

Isto aconteceu dias atrás comigo com a minha Nikon D90. Ela tem 6 anos e meio de uso, e com o Shutter Count de 93606. Pode-se dizer que foi muito usada. Talvez mais do que a maioria das D90 existentes no mundo.

Notas: Este artigo é bastante técnico, talvez tenham outros artigos futuros que completem ele. Ele tem, como costumo avisar, um alto nível de "nerdice", mas deve ajudar a entender o que aconteceu com a minha câmera, e talvez com a sua (ou que ainda poderá acontecer).

Este problema pode vir a não afetar muita gente, pois abandonam a câmera depois de um tempo, ou a trocam (vendendo ou deixando a antiga de lado). Também deve ter muita gente que não se importa mesmo com as datas armazenadas no EXIF ou as datas dos arquivos das fotos.

Introdução

Muitos equipamentos computadorizados tem um sistema de data, e preservam a data, a configuração básica, de diversas maneiras.

Antigamente computadores dependiam de uma pilha para armazenar algumas configurações, e manter o relógio funcionando. Com o advento das memórias flash estas pilhas só passaram a serem necessárias para manter o relógio funcionando.

Por uma época usaram pilhas AA comuns, as CR2032, pilhas de NiCd recarregáveis (Que falhavam e vazavam depois de alguns anos.), e de volta às confiáveis CR2032.

Sistemas Unix usavam a última data de sincronização do sistema de arquivos como referência. Se no boot recebiam do relógio do computador uma data muito diferente da encontrada no sistema de arquivos eles davam um aviso, pois a data do sistema poderia estar errada. Eu assisti um alerta destes ser dado quando um conjunto de estações gráficas foi religado depois de cerca de 10 dias desligado.

Quando não tinha um meio de determinar a data, eles usavam a data da última sincronização do sistema de arquivos como data do boot. Mesmo estando errada, esta data não causaria tantas confusões do que se usassem alguma outra data.

O meu pager tinha uma pequena bateria dentro, que acabou depois de cerca de 5 anos de uso, fazendo com que as mensagens se apagassem, e a data fosse reiniciada, quando a pilha fosse trocada. Para que isto não acontecesse as trocas de pilha tinham que demorar menos de um segundo.

Câmeras fotográficas também tem alguma bateria dentro para preservar a data funcionando. E li uma vez que se tratava de uma pilha recarregável, que era recarregada cada vez que colocava a bateria na câmera.

O site IFIXIT desmontou uma Nikon D600, e na imagem do passo 21 aparece a placa principal. Nela pode-se ver um componente pequeno, cilíndrico, e prateado, preso à placa por uma alça metálica. Parece ser uma bateria. No mesmo passo 21 tem outra imagem, do outro lado da placa, que é destacado em roxo o Circuito Integrado de memória flash.

Então a configuração deve ser armazenada na memória flash e o relógio deve ser sustentado pela pilha. Em caso da pilha falhar as configurações se mantém, mas a data se perde.

O incidente e seu agravante

Na noite do dia 26/10/2016 eu preparei a câmera para usar no dia seguinte, mas não conferi a data. basicamente esvazei dois cartões de memória e escolhi as lentes.

Na tarde do dia 27, depois de tirar algumas centenas de fotos, vi que a data estava incoerente. Estava 01/01/2000, e as horas estavam sendo contadas desde o momento que coloquei a bateria na câmera.

Eu corrigi a data, e as fotos seguintes estavam corretas. O problema eram as centenas de fotos com informação de data errada, tanto na data do arquivo no cartão, como no EXIF.

Ao contrário do Unix (os casos citados acima), a câmera não deu nenhum alerta visível, nem usou alguma data, seja de diretório ou arquivo, gravada no cartão como ponto de partida.

Então, na catalogação de fotos, um grupo de fotos estava no dia certo, e um grupo estava em 01/01/2000.

Procurando soluções

Pelo que sei, é possível modificar a data armazenada no EXIF da foto. O programa ExifTool (Wikipedia) diz que faz isto, porém não pretendo ser tão intrusivo assim no arquivo. Mas o mesmo programa é muito bom para ler o EXIF dos arquivos, e isto deve me ser muito útil.

No EXIF existem vários parâmetros que definem a data da foto, e um deles é o "Date/Time Original". Com ele eu posso reajustar as datas de modo proporcional em relação às outras fotos tiradas. O problema é que não tenho o tempo em relação ao horário real. Eu tenho um horário máximo, que é a data da primeira foto com a hora certa.

Eu cometi um erro. Eu deveria, quando percebi a data errada, ter fotografado um relógio com a data certa, como o relógio do celular, por exemplo. Assim teria um ajuste de tempo. (Dica muito importante.) Então, se isto lhe acontecer, fotografe um relógio antes de ajustar a data da câmera.

Uma solução aproximada é considerar que a última foto com data errada foi feita 5 minutos antes da primeira com a data certa. A data vai continuar errada, mas será muito menos errada.

Existe um conceito em sistemas operacionais chamado "uptime". É o tempo no qual o sistema está ligado. Nos sistemas Unix, Unix-Like, derivados etc, (Solaris, Mac OS X, FreeBSD, GNU/Linux, OpenBSD etc) tem um comando com este nome. Mas o mais parecido que achei com isto foi o atributo EXIF "Power Up Time", que guarda o momento que a câmera foi ligada antes de começar a fazer as fotos.

Na pausa que fiz, na qual descobri o erro da data na câmera, eu desliguei a câmera, portanto perdi o "Power Up Time". Talvez pudesse ser usada, comparando com "Date/Time Original", para acertar a data das fotos. Não tem como saber agora.

Fazendo a solução

A solução foi dividida em 3 partes. Um programa em C para o deslocamento da hora, um script para processar os arquivos, e um meio de listar os arquivos afetados.

Fazendo a solução, parte 1, o deslocador de horas

O programa é bem simples. Ele aceita 3 parâmetros, no formato HH:MM:SS, ou H:MM:SS, no formato de 24 horas, e faz a aritmética entre eles. Transforma os três horários em segundos, depois pega o primeiro, subtrai o segundo, e soma o terceiro, fazendo assim um deslocamento de hora.

Considere o programa sob licença GPL, pois não quero que vire um produto comercial de ninguém, e nem tem qualidade para mais do que foi concebido a fazer.

O programa está abaixo:

#include        <stdio.h>

long    PraSegundos( hora )
char    *hora;
{
        long    h ;

        h = *(hora++) - '0' ;

        if( *hora != ':' )
                h = h*10 + *(hora++) - '0' ;

        hora++;
        h = h*60 + ( *hora - '0' )*10 + hora[1] - '0' ;
        hora += 3;
        h = h*60 + ( *hora - '0' )*10 + hora[1] - '0' ;

        return( h );
}

int     main( argc,argv )
int     argc    ;
char    *argv[] ;
{
        long    h,h1,h2,h3;

        h1 = PraSegundos( argv[1] ) ;
        h2 = PraSegundos( argv[2] ) ;
        h3 = PraSegundos( argv[3] ) ;

        h = h1 - h2 + h3 ;

        printf( "%02ld%02ld.%02ld\n",h/3600,(h/60)%60,h%60 );

        return( 0 ) ;
}

Deixo bem claro que este programa é extremamente limitado. Ele não verifica se a quantidade de parâmetros está correta, se o formato dos parâmetros está correto etc.

Outra limitação é se o resultado cair no dia anterior, que dará um número negativo na conta interna, e uma saída muito errada, ou no dia seguinte, o que dará uma hora superior a 23:59:59. Esta limitação estaria resolvida se usasse a data completa e usasse as funções de data existentes na linguagem C. Mas como todas as fotos ainda estavam dentro de uma tarde, não foi necessário chegar neste nível.

Fazendo a solução, parte 2, o script


Fiz um script que recebe como parâmetro a lista de arquivos, extrai com o ExifTool o "Date/Time Original" de cada um deles, e passa para o programa de deslocamento de hora mostrado acima, junto com as horas de referência (que estão nas variáveis refi e refd).

De novo, é licença GPL.

#!/bin/sh

# Diretório onde está o programa de deslocamento de hora.
dir=/home/goffredo/trabalho/c/desloca_hora

# Referência inicial e referência final.
# Quem tiver a data igual à incial será convertida para a final.
refi="13:10:43"
refd="15:50:00"

dia=20161027

for i in $*
do
        set `exiftool "$i" | grep 'Date/Time Original' | head -1`
        data=$5

        conv="$dia"`"$dir"/desloca_hora $data "$refi" "$refd"`

        echo "$i"': '$conv
        touch -t $conv "$i"
done

As 4 variáveis que são inicializada antes do loop são para facilitar o entendimento, e gerar um ponto só de modificação.

Fazendo a solução, parte 3, a seleção dos arquivos

Eu conheço vários modos de escolher os arquivos (inclusive fazer a lista manualmente), mas o mais simples, ou um dos mais simples, é o abaixo:

find * -mtime +6000 -print | more

O find é uma poderosa ferramente de localização e seleção de arquivos. Pode fazer por data, nome, antiguidade, permissões etc. Neste caso estou selecionando arquivos com mais de 6 mil dias de idade, o que dá em algum dia, contando à partir da data de escrita deste artigo, do primeiro semestre do ano 2000. Para maiores informações leia o manual.

Execução

Foram feitos alguns testes intermediários, durante o desenvolvimento do programa. E quando dado como pronto o script foi executado com a seguinte linha de comando:

desloca_hora.sh `find * -mtime +6000 -print | more`

Em menos de 5 minutos de processamento as datas dos mais de 700 arquivos foram corrigidas.

Catalogação.

A catalogação não pode se fiar na informação EXIF da foto, já que ela não foi atualizada. Tem que se fiar na data do arquivo que armazena a foto. O que não aconteceu. O KPhotoAlbum, o programa de catalogação que uso, parece ter pego as informações de data do EXIF , e não da data dos arquivos. Em suma, não funcionou bem.

Como o arquivo de catalogação do KPhotoAlbum e um texto, um XML, eu posso criar as linhas, ou editá-las com algum editor texto. Então resolvi alterar a data lá mesmo.

Copiei as linhas referentes a estas fotos para um outro aquivo. Este isolamento das linhas permitiria um processamento mais rápido e seguro. Eu não precisaria lidar com um grande grupo de dificuldades poderiam aparecer, como coincidências de nomes dos arquivos das fotos.

Então tive que fazer uma versão do programa e uma do script para resolver este problema. No caso do programa foi só uma alteração na linha com o printf para mudar a formatação.

O script para resolver a catalogação ficou como mostrado abaixo:

#!/bin/sh

# Diretório onde está o programa de deslocamento de hora.
dir=/home/goffredo/trabalho/c/desloca_hora

# Referência inicial e referência final. Quem tiver a data igual à incial será convertida para a final.
refi="13:10:43"
refd="15:50:00"

dia='2016-10-27T'

> "$dir"/isolado.out

for i in $*
do
        echo $i

        set `exiftool "$i" | grep 'Date/Time Original' | head -1`
        data=$5

        conv="$dia"`"$dir"/desloca_hora2 $data "$refi" "$refd"`

        grep $i "$dir"/isolado | sed 's/startDate="[^"]*" /startDate="'$conv'" /;s/endDate="[^"]*" /endDate="'$conv'" /' >> "$dir"/isolado.out
done

Depois foi reinserir no local correto as descrições destas fotos no arquivo index.xml, o arquivo que guarda o catálogo das fotos, que estava resolvido

Efeitos colaterais

Como agora tem um conjunto de fotos cujas datas no EXIF não condizem com as datas do arquivos e as datas armazenadas na catalogação, e não posso mais pedir para reorganizar as fotos pelas datas encontradas no EXIF. Isto tiraria da ordem correta as fotos.

Os arquivos raw

Depois de começar a catalogação eu tinha que fazer o primeiro backup destas fotos. Resolvi acertar as datas dos arquivos raw também, antes mesmo de fazer o primeiro backup. Usei o primeiro script deste artigo para isto. Portanto, só modifiquei as datas dos arquivos.

Conclusões

Ainda tenho que verificar se a câmera vai passar a perder a data a cada retirada de bateria. Se ela não está preservando a data configurada. Se sim, preciso saber se tem solução, quem resolve este problema, e quanto custa. Talvez não seja barato fazer isto, pois esta pilha que mantém o relógio funcionando é de difícil acesso.

A cada vez que eu tirar e colocar bateria na câmera vou ter que verificar a data.

Seria bom que o firmware da câmera, no momento recebe energia da bateria, isto é, no momento que se coloca a bateria, testasse a validade da data, e se ela estiver errada, tocasse um alarme, piscasse uma mensagem no LCD etc, e mostrasse o menu de data, para que ela possa ser ajustada de imediato.

Este texto foi escrito enquanto eu resolvia os problemas, mas aprendi muito com ele. Se o problema se repetir vou resolver mais rápido, com uma precisão maior na hora, pois devo fazer a foto de um relógio, e será um script só para resolver tudo.

Post scriptum

Deixei a câmera sem bateria por cerca de 10 horas, e não perdeu a hora. O relógio estava funcionando normalmente. Então ele deve ser mantido por alguma pilha recarregável que descarregou por falta de uso.

Nenhum comentário:

Postar um comentário