Skip to content

calculaMediaVarianciaHSV

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

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.

O funcionamento a nível global deve ser notado com clareza. O objetivo da aplicação do Zebtrack, é associar peixes (sobre o que queremos saber) a blobs (o que, de fato, podemos saber). O critério de cor é útil pois iremos aplicar a distância de Mahalanobis. Assim, como queremos associar os peixes aos blobs corretamente, antes do rastreio começar, fazemos os cálculos de Média e Variância como descrito aqui.

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 página "Observações Gerais".

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, quad_usado e sizeOfBlob.

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;. Por fim, prepara-se a variável pra recomeçar o processo: mediaFrameIndividual = 0;.

Processo Final: Média de Médias

Após concluído esse processo, é retornado ao programador (log num relatório no console) a quantidade dos pixels encontrados para cada peixe em cada frame.

Ora, sabe-se que a hipótese central do funcionamento do programa é que a média das médias e das variâncias das cores achadas em cada frame, para cada peixe, é um label válido. Já foi tirado a média das cores em cada frame, agora aloca-se previamente as variáveis que conterão as médias das médias: media = zeros(1, nanimais); e variancia = zeros(1, nanimais); .

O processamento das médias das médias e das variâncias ocorre peixe-a-peixe.

Transformada Inversa

Devido à Transformada HSV, alguns valores podem se tornar negativos. Daí, dado que o valor numérico da tonalidade não pode ser negativo (lembre-se que o hue varia de 0 a 1), basta aplicar a transformada inversa: soma-se o valor atual (negativo) a 1.