forked from borgesnogueira/ZebTrack
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculaMediaVarianciaHSV.m
254 lines (195 loc) · 11.5 KB
/
calculaMediaVarianciaHSV.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
%A ideia é que o usuário defina um intervalo em (tempo_inicial - tempo_final)
%de qualquer extensão de forma que o mesmo possibilite gerar uma biblioteca
%de pontos resultante de múltiplos SURFS em múltiplos frames e uma média e
%variância correspondente a cada peixe
%OBS:
%tol = threshrold na track.m, que serve para a subtração de fundo;
%Imback = wbackg do track.m;
%criavideo = criavideodiff do track.m;
%avi = aviobj2 do track.m (o input e não o output nessa função!);
%wframe = working frame (double e em greyscale);
%frames_video(i) = frame do track.m;
%INTENSIDADE = intervalo que dita o valor do V de HSV, ou seja, dita o limite para que as cores sejam mais 'intensas';
%V = Vrm do track.m;
%media e variancia são dois vetores, já que posso ter mais de 1 peixe.
function [media, variancia] = calculaMediaVarianciaHSV(video, tempo_inicial, tempo_final ...
, Imback, V, nanimais, mascara, minpix, maxpix, tol, avi, criavideo, tipsubfundo ...
, caixa, l, c ...
, colorida, cor, tipfilt ...
, INTENSIDADE)
%ainda não se entrou em um consenso para um bom valor para a
%intensidade, por isso, os valores abaixo foram pré-setados.
%variáveis que preciso para o funcionamento do código mas que não faz
%sentido passar como parâmetros.
dicax = -1;
dicay = -1;
pxant = zeros(1,nanimais);
pyant = zeros(1,nanimais);
[frame_inicial, frame_final] = extraiIntervaloFrames(tempo_inicial, tempo_final, video); %aqui obtenho os índices final e inicial para a calibração.
frames_video = read(video, floor([frame_inicial, frame_final])); %cria um vetor com todos os frames entre frame_incial e frame_final.
%Lembrando que para acessar o i-ésimo frame, uso a notação frames_video(:,:,:,i);
length_frames_video = (floor(frame_final) - floor(frame_inicial)) + 1; %Necessário para a implementação do for (o +1 é pra incluir o primeiro termo!)
%VARIÁVEIS DE CONTROLE DO FOR: MÉDIA E VARIÂNCIA.
mediaTOTAL = zeros(nanimais, length_frames_video); %aloco somente um espaço do V (HSV) para cada animal e frames_video espaços (a progressão temporal de cada animal)
mediaFrameIndividual = 0; %(Em 1 peixe e muda em cada loop).
quantidade_pixeis = zeros(nanimais, length_frames_video);
%LOOP PRINCIPAL
for i=1:1:length_frames_video
%converte pra tons de cinza e double pra trabalhar
if colorida || (cor == 1)
wframe = double(frames_video(:,:,:,i));
else
wframe = double(rgb2gray(frames_video(:,:,:,i)));
end
%faz a diferenca so na area de interesse e extrai o centro de massas
%das regioes (blobs) maiores que minpix
[cx, cy, radius, boundingbox, ndetect, ~,~ ,wframe_log] = extractnblobs(wframe, Imback, V, nanimais, mascara, minpix, maxpix, tol, avi, criavideo, tipsubfundo);
%vetor que irá decorar cada animal que ja foi associado a um blob
detectado = zeros(1,nanimais);
if pxant(1) ~= 0 %global variable;
if tipfilt == 1
%previsao do filtro de kalman
for j=1:nanimais
pdecorada = [pxant(j); pyant(j)];
predita = A*[pdecorada;v(:,j)] + Bu;
%garantir que esta dentro da imagem
predita(1) = min(max(predita(1),1),c);
predita(2) = min(max(predita(2),1),l);
pxant(j) = predita(1);
pyant(j) = predita(2);
v(:,j) = predita(3:4);
end
end
end
%OLHAR POR PX E PY
[px, py, detectado, caixa] = associateeuclid(nanimais, ndetect, pxant, pyant, cx, cy, radius, boundingbox, detectado, dicax, dicay ...
, caixa, l, c, frames_video(:,:,:,i));
%aqui começa a parte que trata do cáculo das médias
frameHSV = rgb2hsv(frames_video(:,:,:,i)); %converte o i-ésimo frame(frame atual) para HSV;
%OBS: Somente conseguimos dizer que o k-ésimo elemento do loop é o k-ésimo peixe em todas as situações porque antes de
%rodar esse loop, as funções extractnblobs() e associateeuclid() fora executadas!
%percorrendo de k=1 até o numero de animais (podemos ter mais de um blob por frame)
for k=1:1:nanimais %blob individual do frame
%variáveis para o tratamento da descontinuidade das cores no sistema HSV.
flag_amostrando = true; %flag que garante uma pequena amostragem dos píxeis
conta_amostrando = 0;
quad14 = 0;
quad23 = 0;
quad_usado = 0;
sizeOfBlob = 0; %number of pixels/blob;
%debugging
% debug_imagem = frames_video(min(max(round(caixa(k, 2)),1),1):1:floor(caixa(k, 2) + caixa(k,4)), min(max(round(caixa(k, 1)),1),1):1:floor(caixa(k, 1) + caixa(k,3)), :, i);
% figure, imshow(debug_imagem)
%PERCORRENDO A BOUNDING BOX
m = round(caixa(k, 2)); %reiniciando a coordenada m (anteriormente era um floor() )
m = max(m, 1); %reiniciando a coordenada m
m = min(m, l);
quantos_pixeis = 0;
while m <= floor(caixa(k, 2) + caixa(k,4))
n = round(caixa(k, 1)); %reiniciando a coordenada n (anteriormente era um floor() )
n = max(n, 1); %reiniciando a coordenada n
n = min(n, c);
while n <= floor(caixa(k, 1) + caixa(k,3))
if(detectado(k))
%detectado(:) é a condição em 0's e 1's de ter um peixe ou não associado ao k-ésimo blob(?) (VEM DO ASSOCIATEEUCLID() )
if(wframe_log(m,n) == 1 && frameHSV(m,n,2) >= 0.5 && frameHSV(m,n,3) >= 0.15)
%Amostrar alguns pixels, utilizar uma flag para selecionar os pixels e contamos quantos pixels pertencem a cada quadrante
%Após isso definiremos o espaço onde vamos trabalhar e resetamos o rastreio com o quadrante predominante
%Transformação T[h] = h - 1
quantos_pixeis = quantos_pixeis + 1;
if flag_amostrando
conta_amostrando = conta_amostrando + 1;
if frameHSV(m,n,1) >= 0.25 && frameHSV(m,n,1) <= 0.75 %intervalo das cores
quad23 = quad23 + 1; %dois quadrantes do lado esquerdo (tons de verde e azul)
else
quad14 = quad14 + 1; %dois quadrantes do lado direito (tons de vermelho e amarelo(?)
end
%definindo com que quadrante trabalhar e resetando a flag
if conta_amostrando > 15 %NÃO PODE TER VALORES MUITO GRANDES KKKKKKKKKKKKKKKKKKKKKKKK
flag_amostrando = false;
if quad23 > quad14
quad_usado = 23;
else
quad_usado = 14;
end
%voltamos para a execução normal do código
m = floor(caixa(k, 2));
n = floor(caixa(k, 1));
end
else
pixel_hue = transformada_HSV( frameHSV(m,n,1), quad_usado);
%se meu pixel for um NaN, ao somar a mediaFrameIndividual ele transformara o valor contido em NaN, que não é o que queremos
if ~(isnan(pixel_hue))
mediaFrameIndividual = mediaFrameIndividual + pixel_hue;
end
sizeOfBlob = sizeOfBlob + 1;
end
end
end
n = n + 1; %incrementa a coordenada n
end
pxant = px;
pyant = py;
m = m + 1; %incrementa a coordenada m
end
quantidade_pixeis(k,i) = quantos_pixeis;
%a média deve ser calculada depois de percorrer toda aquela bounding box para o k-ésimo animal
mediaFrameIndividual = mediaFrameIndividual/sizeOfBlob;
mediaTOTAL(k, i) = mediaFrameIndividual; % (media do k-ésimo animal no i-ésimo frame)
%zerando as variáveis de controle
mediaFrameIndividual = 0;
end
end
for k=1:1:nanimais
for i=1:1:length_frames_video
disp(['PIXES = ', num2str(quantidade_pixeis(k,i)), '; ANIMAL = ', num2str(k), '; FRAME = ', num2str(i),';'])
end
end
%aloco previamente por questões de velocidade
media = zeros(1, nanimais);
variancia = zeros(1, nanimais);
%cálculo dos outputs da função.
for k=1:1:nanimais
media(k) = nanmean(mediaTOTAL(k, 1:end)); %MEDIA FINAL CALCULADA: do primeiro ao último frame para o k-ésimo animal.
variancia(k) = nanvar(mediaTOTAL(k, 1:end)); %VARIÂNCIA FINAL CALCULADA: do primeiro ao último frame para o k-ésimo animal.
end
disp('entrei aqui alguma vez (antes for-animals)')
%tratamento final
for k=1:1:nanimais
if media(k)<0
media(k) = media(k) + 1;
end
end
end
%Função para converter meu tempo inicial e final em termos dos frames correspondentes.
function [frame_inicial, frame_final] = extraiIntervaloFrames(tempo_inicial, tempo_final, video)
frameRate = video.NumberOfFrames/video.Duration;
frame_inicial = frameRate*tempo_inicial;
frame_final = frameRate*tempo_final;
end
function frames_video = geraVetor_frames_video(video, frame_inicial, frame_final)
% frames_video = read(video, floor([frame_inicial frame_final]));
for i=frame_inicial:frame_final
frames_video(i - frame_inicial + 1) = read(video, i);
end
end
function H_novo = transformada_HSV(H, quadrante_usado)
if quadrante_usado == 23
H_novo = H;
elseif quadrante_usado == 14
if H >= 0.75
H_novo = H - 1;
else
H_novo = H; %se quadrante_usado == 14, então, aqui, necessariamente 0 <= H <= 0.25 (low-red)
end
end
end
function H_re_novo = transformadaInv_HSV(H, quadrante_usado)
if quadrante_usado == 14 && H < 0
H_re_novo = H + 1;
else
H_re_novo = H;
end
end
%function [cc,cr,radius,boundingbox,ndetect,avi,foremm] = extractnblobs(Imwork,Imback,V,n,mascara,minpix,maxpix,tol,avi,criavideo,tipsubfundo)
%function [pxn,pyn,detectado,caixa] = associateeuclid(nanimais,ndetect,pxa,pya,cx,cy,radius,boundingbox,detectado,dicax,dicay,caixa,l,c,frame)