Skip to content

calculaMediaVarianciaHSV

Mateus de Assis Silva edited this page Apr 21, 2020 · 25 revisions

Observações externas:

HSV

O espaço de cores HSV é utilizado pois a informação de cor fica contida em um escalar, ao invés de um vetor. Uma dica de como funciona pode ser visto abaixo:

HSV_cone

Descontinuidade no sistema HSV

Como visto logo acima, o sistema HSV separa as cores em tom (hue , ou seja, se é vermelho, roxo, laranja, etc.); saturação (saturation , se a cor é mais esbranquiçada ou mais forte) e valor (value, se a cor é mais escura ou não). Vamos focar no tom, pois é com ele que vamos trabalhar. Para a interpretação do MATLAB, ele varia de 0 a 1, percorrendo o círculo de cores. Tais extremidades (0 e 1) representam o vermelho, e chamamos esse ponto de descontinuidade. Ou seja, um local em que a mesma cor possui valores distintos.

Vamos supor que estamos iterando na região em que acredita-se que existe um peixe (isto é, num determinado blob), e que sua cor está próxima da cor vermelha. Por simplicidade, suponha que existam apenas 2 pixels. Ora, se o tom do primeiro for 0.1 e o tom do segundo for de 0.99 (note que ambos vermelhos, pela forma de representação do MATLAB), a sua média será de 0.545. Para o sistema isso é uma cor próxima do verde! Assim, é necessário uma forma de "driblar" esse problema. Para tanto, move-se a descontinuidade.

explicar como funciona o movimento da descontinuidade

Funções encontradas nesse arquivo:

  1. calculaMediaVarianciaHSV
  2. extraiIntervaloFrames
  3. geraVetor_frames_video
  4. transformada_HSV
  5. transformadaInv_HSV

Introdução

Até antes da existência do reconhecimento via proximidade de cor, o Zebtrack reconhecia os peixes ao localizar os blobs e associá-los com os indivíduos mais próximos. De forma a refinar essa associação, utilizava-se uma "previsão" da posição dos peixes no próximo momento. Isso é passível de falha, pois os animais podem se movimentar de forma a confundir o software.

Um desses movimentos é quando os peixes se deslocam em retas concorrentes. No ponto de encontro das retas eles não prosseguem, mas se desviam. Isso faz com que o software troque as labels relativas a cada animal.

Assim se torna necessário uma forma de diferenciar os indivíduos. Dentre algumas possibilidades, utilizaremos um critério de cor.

Critério de cor: médias e variâncias

Ora, apesar de ser interessante utilizarmos cor pra diferenciar indivíduos (principalmente quando os animais têm cores muito distintas, como azul e vermelho), muitos fatores podem influenciar a leitura da imagem efeituada pela câmera. Isso faz com que os valores de cores lidos pelo software variem.

 % as cores dos peixes não se repetem como abaixo
 % para todos os quadros nem em todos os vídeos.

> peixe1.cor[quadro1]
        r,g,b = [255, 0, 0]
> peixe1.cor[quadro2]
        r,g,b = [255, 0, 0]
> peixe1.cor[quadro3]
        r,g,b = [255, 0, 0]

> peixe2.cor[quadro1]
        r,g,b = [0, 0, 255]
> peixe2.cor[quadro2]
        r,g,b = [0, 0, 255]
> peixe2.cor[quadro3]
        r,g,b = [0, 0, 255]

A solução para lidar com valores que variam aleatoriamente é utilizar um método estatístico. Ao computarmos as médias e variâncias das cores, para cada peixe, capturamos o comportamento aleatório das leituras. Com as médias, temos como identificar quantitativamente cada um (estimando a cor dele: por exemplo, azul). A variância expressa como tal cor varia (o expectro de azul, por exemplo).

Como usar

O usuário define um intervalo de tempo (através das variáveis tempo_final e tempo_inicial), no qual, de preferência, os peixes estejam separados espacialmente. o código contido em calculaMediaVarianciaHSV.m processa os quadros e retorna os vetores de média e variância de cor (relativas a cada animal).

Note que a função realiza a calibração dos detectores dos peixes através das cores. Ela cria identificadores para cada peixe, os quais, depois, serão utilizados para os rastrear (a partir de suas cores). Esse identificadores são as médias e as variâncias para cada peixe com cor notável.

Como funciona

inicialização de algumas variáveis

No início do código temos a inicialização das variáveis que auxiliam o software a encontrar a posição do peixe (dicax e dicay) como -1. Também se inicializa vetores para guardarem a posição imediatamente anterior de cada peixe (ou seja, as posições dos peixes no frame anterior), os quais são os pxant e pyant (posição x/y anterior).

recuperação de frames

Logo após tal inicialização, utiliza-se os tempos inicial e final do intervalo, informados pelo usuário, para recuperar todos os frames do vídeo (os quais estão no intervalo definido). Além disso, registra-se quantas imagens existem (length_frames_video).

É importante notar que frame_inicial e frame_final se refere a um número de frame numa sequência. Por exemplo:

> frame_inicial
     654
> frame_final
     988

, enquanto que os tempos inseridos pelo usuário são instantes em unidades de minutos:segundos .

O último detalhe antes de explicarmos na próxima etapa é o alocamento de trê s variáveis:mediaTOTAL,mediaFrameIndividual e quantidade_pixeis. É importante realizar um alocamento prévio para não atrasarmos o processamento do MATLAB. Para entender-se a necessidade delas, deve-se considerar que, o objetivo do código em questão é extrair estimadores da distribuição aleatória de cores. Ora, as cores não variam apenas entre os frames, mas também ao longo do corpo do animal (devido a uma sombra, por exemplo). Assim sendo, utiliza-se mediaTOTAL e quantidade_pixeispara se estimar a cor que cada peixe, em média (espacial, ou seja, a cor média do seu corpo), apresenta em cada frame. A variável mediaFrameIndividual é auxiliar do processo.

Loop Principal : para todos os frames

O primeiro passo do loop principal é transformar os frames dos vídeos em matrizes double, cujo espaço de cor é baseado em tons de cinza.

Logo após isso, utiliza-se a função extractnblobs para se calcular alguns parâmetros necessários para as operações seguintes. Por exemplo, wframe_log, que é a imagem binária (pós-processada) que indica onde os peixes podem estar, no frame.

O próximo passo, a seguir, é aplicar o Filtro de Kalman. É necessário executar esse passo nesse momento para que o código como um todo funcione corretamente. É interessante entender porque certos trechos são necessários pra poder chamar funções depois. Isto é, existe a necessidade de se executar certos trechos de código antes de chamar determinadas funções. Por que isso? Não sabemos ainda.

Logo após a aplicação do Filtro de Kalman, utiliza-se a função associateeuclid, a qual associa cada peixe ao blob mais próximo (segundo uma distância euclidiana).

Após concluído, transforma-se o frame atual do espaço de cores rgb para hsv. O que é e porque se usa pode ser lido na seção "Observações Externas".

Percorrendo animal a animal

Agora pode-se dar início ao cálculo da média de cor em cada frame. Logo no início aloca-se as variáveis para serem usadas no tratamento da descontinuidade das cores no sistema HSV. São elas: flag_amostrando , conta_amostrando , quad14 , quad23 e quad_usado.

Percorrendo a bounding box (pixel a pixel)

No momento de percorrer a Bounding Box , iremos adequar a variável responsável por guardar essa informação (caixa). Ora, trata-se de posições e dimensões (das boxes) em uma perspectiva discreta (pixels na tela). Entretanto, o processo que as geram retornam valores em ponto flutuante. Assim, temos que arredondar. Logo depois é necessário passar por uma operação max, min . Isto faz com que o iterador m = round(caixa(animal_k,coordenada == 2)) comece em 1.

Dado a necessidade de se tratar a descontinuidado do Hue , é necessário se realizar uma amostragem para se verificar o quadrante em que as cores recaem. Após uma dada transformada (se for necessária), soma-se o valor à média. O cerne do cômputo dos labels se encontra nesse trecho. Em outras palavras: testar o quadrante (somando número arbitrário); aplicação da transformada; somar o valor à média, se não tratar-se de um valor NaN. Ainda não entendi o que ocorre entre as linhas 108 e 174

Logo após o mencionado cálculo, tira-se o valor médio da cor encontrada: mediaFrameIndividual = mediaFrameIndividual/sizeOfBlob; e atribui esse valor a mediaTOTAL(k,i) de forma que a mediaTOTAL do peixe k no frame i é o valor médio da cor calculada na área correspondente ao peixe: mediaTOTAL(k, i) = mediaFrameIndividual;.