Quem sou eu e o que este blog.

terça-feira, 26 de outubro de 2010

Método caseiro de medição de ruído de sensor.

Este é um método "simples", só com um pouco de complicação de software, para medição de ruído de sensores de câmeras digitais que gravem RAW. Se ela só grava JPEG, este método não se aplica.

Sei que ele é limitado, e só mede o ruído no escuro, mas a vantagem dele é que dá para fazer em casa.

Para entender os resultados é bom conhecer um pouco de estatística. Por isto que escrevi o artigo ABC da Estatística em 10 minutos.

Atenção, este artigo tem um nível alto de "nerdice", portanto leia por sua conta e risco.

No teste usei alguns programas que tenho instalados no meu computador de casa, o dcraw e o Netpbm. Estes programas estão disponíveis para Linux e FreeBSD, e estão disponíveis para Mac OS X via MacPorts. Executei os testes num FreeBSD. Não duvido que existam também versão para MS Windows, mas o Netpbm perde um pouco o sentido dele no MS Windows.

O teste, coleta de dados

Primeiro tem que se coletar as amostras. Decidi fazer um conjunto de fotos, uma com cada ISO (os principais, 100, 200, 400, 800...), para 3 tempos de exposição diferentes, 1 ms, 1 s e o tempo máximo de exposição da câmera (60 s para a Panasonic FZ28 e 30 s para a Nikon). Estas fotos tinham que ser sem luz. Eu fiz de noite, com a luz da casa apagada, quarto todo fechado, com a câmera tampada, diafragma mais fechado possível, e com a câmera debaixo de uma coberta escura dobrada. Acho que não devia ter quase nenhuma luz.

Este é uma coleta de dados, mesmo que um pouco trabalhosa, é muito simples e não tem os problemas de calibração de luz, e qualquer outra coisa que exija um laboratório. Por isto chamo de método caseiro.

Começa o processamento

Converti as imagens usando o DCRaw para um PGM de 16 bits, sem tratamento ou qualquer correção, usando as seguintes opções:

dcraw -D -4 -j -t 0 imagem_RAW

Assim cada ponto do arquivo de imagem era somente o valor lido pelo sensor para ele, sem equilíbrio de branco, sem interpolação de cores, sem curvas etc.

Para cada imagem apliquei o programa pgmhist, que faz parte do pacote de programas Netpbm. A saída dele apliquei uma filtragem, e depois a um programa para cálculo de estatísticas, médias, desvio padrão, moda etc. Para simplificar, fiz o seguinte shell script:

#!/bin/sh

echo    'Media          Desvio Padrao   Moda    % de Moda       Cont    Arquivo'
for i in $*
do
        pgmhist $i | sed '1,2d;s/\t*[0-9.e-]*%.*//' | analise_bin
        echo '  '$i
done

O fonte do programa analise_bin vai abaixo:

/* Licença GPL */

#include        <stdio.h>
#include        <math.h>

#define VALMAX  (65536)

static  valores[ VALMAX ]       ;

main()
{
        int             valor   ,
                        quant   ,
                        cont    = 0     ;
        register int    moda_v  = 0     ,
                        moda_q  = 0     ;
        register long   somat_q = 0     ,
                        somat_v = 0     ;
        double          media   ,
                        somat_var       ;

        while( scanf( "%d%d",&valor,&quant ) != EOF )
        {
                somat_q += ( valores[ valor ] = quant );
                somat_v += (long) valor*quant ;

                if( moda_q < quant )
                {
                        moda_q = quant ;
                        moda_v = valor ;
                }

                cont++;
        }

        media = (double) somat_v / somat_q ;

        for( valor = 0 ; valor < VALMAX ; valor++ )
        {
                double  tmp     = valor - media;


                somat_var += valores[ valor ]*tmp*tmp ;
        }

        printf( "%f\t%f\t%d\t%f%%\t%d",
                media,sqrt(somat_var/(somat_q - 1 ) ),moda_v,(double) moda_q/somat_q*100,cont
        );
}

Resultados

Abaixo vão os resultados do teste para a Panasonic FZ28:

Média Desvio Padrão Moda Percentual da Moda Quantidade de valores Tempo de exposição ISO
17.127514 2.240393 16 65.851653% 105 1 ms 100
19.158663 5.507378 16 57.046111% 287 1 ms 200
22.585527 10.981097 16 54.817104% 488 1 ms 400
29.025929 14.939595 24 11.167666% 857 1 ms 800
50.329426 37.806332 33 4.850237% 448 1 ms 1600
17.243251 3.406696 16 64.672413% 343 1 s 100
19.229540 7.449939 16 57.453083% 545 1 s 200
23.608795 15.292653 16 51.013070% 787 1 s 400
30.947057 25.260252 25 9.855715% 1277 1 s 800
52.130164 39.977223 33 4.647102% 516 1 s 1600
18.315030 3.927399 16 59.822909% 73 60 s 100
21.106672 8.208162 16 55.547695% 124 60 s 200
27.183994 17.556869 16 53.798916% 239 60 s 400
38.787731 31.084276 23 8.303942% 462 60 s 800
62.808779 61.699765 31 4.174972% 865 60 s 1600

Abaixo estão os resultados o teste para Nikon D90:

Média Desvio Padrão Moda Percentual da Moda Quantidade de valores Tempo de exposição ISO
0.404432 0.659306 0 66.759595% 14 1 ms 100
0.479797 0.745945 0 62.606261% 17 1 ms 200
0.665504 1.199968 0 62.514085% 27 1 ms 400
1.123875 2.172293 0 57.376257% 51 1 ms 800
2.432582 4.245830 0 35.089838% 96 1 ms 1600
4.379919 5.730250 1 25.578372% 136 1 ms 3200
8.484372 11.590041 3 15.234154% 207 1 ms 6400
0.381824 0.542346 0 64.538900% 12 1 s 100
0.244680 0.491916 0 78.167911% 14 1 s200
0.459909 0.768831 0 67.294969% 24 1 s 400
0.872025 1.342956 0 57.434488% 40 1 s 800
1.611404 2.427597 0 43.175871% 68 1 s 1600
3.272128 3.404522 1 32.389201% 116 1 s 3200
6.772315 7.244002 2 17.402339% 181 1 s 6400
0.062623 0.618663 0 94.473873% 34 30 s 100
0.220952 0.821496 0 81.416341% 38 30 s 200
0.973787 1.819879 0 50.633529% 57 30 s 400
1.224743 2.515000 0 53.656808% 81 30 s 800
2.382707 4.060317 0 34.314218% 121 30 s 1600
5.356754 6.507886 2 21.368675% 181 30 s 3200
10.301137 13.899308 3 11.295833% 255 30 s 6400

Abaixo estão os resultados o teste para Nikon D60 (Agradecimentos à Ale Perenyi):

Média Desvio Padrão Moda Percentual da Moda Quantidade de valores Tempo de exposição ISO
0.886701 1.295155 0 57.398255% 28 1 ms 100
3.571348 5.800137 0 57.394644% 74 1 ms 800
7.289803 11.753652 0 55.789592% 133 1 ms 1600
0.681258 1.065660 0 63.035405% 15 1 s 100
2.901643 4.305410 0 46.207925% 62 1 s 800
6.123491 8.916442 0 44.156702% 105 1 s 1600
0.592079 0.974208 0 65.869881% 51 30 s 100
2.565753 4.700695 0 62.010274% 181 30 s 800
5.047693 9.374539 0 61.554898% 244 30 s 1600

Os dados dele foram incompletos, mas acho que já dá para ter uma ideia.

Conclusões

Quem conhece um pouco de estatística já pode sacar algumas coisas. Na FZ28, mais da metade dos pixels não tem ruído até o ISO 400, por que o percentual da Moda está acima de 50%. Nem a Moda não é 0, e sim 16. Aparentemente o nível de preto dela é 16. A quantidade de valores é a quantidade de diferentes valores encontrados para os pixels da imagem. Quanto maior, pior. Quanto maior o desvio padrão, também maior é o nível de ruído. Note que a FZ28 se manteve usável até o ISO 400, em minha opinião. Depois disto ela deu um pulo na quantidade de ruído, e quase todos os píxels passaram a ser ruidosos, como se vê no percentual da moda baixo.

A D90, que tem um sensor muito maior que a FZ28, tem níveis de ruído muito mais baixos. A Moda é 0, que deve ser o nível de preto, e ela se mantém assim até o ISO 1600, mas até o ISO 800 a Moda, o valor 0, predomina em mais da metade dos pixels. O ruído registrado na D90, tem um Desvio Padrão muito mais baixo, isto implica em que são menos afastados, menores em valor absoluto, e ainda com menos valores diferentes, em relação à FZ28.

A Nikon D90 tem menos ruído em ISO 6400 que a FZ28 em ISO 800, e por vezes que no ISO 400.

Depois que fiz este teste, passei a evitar usar a FZ28 acima de ISO 400. Eu limito a minha D90 em no máximo 3200.

O ruído da  D60 pareceu bem curioso. Mesmo maioria dos pontos continuando em 0, mas os Desvios Padrões foram maiores que a D90. Isto deve implicar que, menos pixels ficam com ruído, mas os que ficam ruidosos, ficam mais evidentes.

Adoraria ver os resultados em uma Full Frame, como a Nikon D3s.

Já respondendo às polêmicas

Esta não é a primeira vez que apresento este teste. Ele gerou muita polêmica antes.

Sei que ele é incompleto, e não pretendia fazer um teste completo, pois não tenho luz controlada, laboratório etc. Eu queria um teste factível em casa. Sei que estou testando principalmente o ruído do circuito de chaveamento de pixels para o amplificador, do amplificador e da entrada do digitalizador, e pouco do ruído de erros de medida do sensor, que é mais complicado de testar, coisa que iria requerer condições muito controladas.

Qualquer um pode gerar dados para fazer este teste, e muita gente tem condições de fazer o teste em casa. Até agradeceria o envio de dados, ou os arquivos RAW para processar e coletar os dados.

Um comentário: