Código get_totals.m comentado Nombre de la función e inputs iniciales:

Anuncio
Código get_totals.m comentado
Nombre de la función e inputs iniciales:
function get_totals(files, thr, msk)
Revisa version de SPM:
if exist('spm_select','file') % should be true for spm5
spm5 = 1;
select = @(msg) spm_select(inf, 'image', msg);
elseif exist('spm_get','file') % should be true for spm2
spm5 = 0;
select = @(msg) spm_get(inf, 'img', msg);
else
error('Failed to locate spm_get or spm_select; please add SPM to
Matlab path')
end
Si no existe un archivo de imagen a analizar, pide seleccionarlo:
if ( ~exist('files', 'var') || isempty(files) )
files = select('choose images');
end
Si no existe un umbral declarado, el umbral solo quita NaNs (la nueva versión modificada de
get_totals permite introducir manualmente el umbral):
if ( ~exist('thr', 'var') || isempty(thr) )
thr = -inf; % default to include everything (except NaNs)
end
Si no existe una máscara, queda habilitado para analizar el volumen total de la imagen original:
if ~exist('msk', 'var')
msk = 1; % default to include everything
end
Si no existe una máscara declarada en get_totals([],[],[]), pide seleccionar un archivo de mascara:
if isempty(msk)
msk = select('Choose mask image');
end
Si la máscara está declarada, obtiene información del header de la máscara:
if ischar(msk)
msk = spm_vol(msk);
end
Si el header de la máscara brinda un array (“matriz de datos”), lee la intensidad de sus voxels:
if isstruct(msk)
msk = spm_read_vols(msk);
end
msk = msk ~= 0;
Lee el header de la imagen original a analizar:
vols = spm_vol(files);
Calcula la cantidad de imágenes a analizar cargadas:
N = length(vols);
Declara la variable en donde se guardaran los resultados (para quitarles después los puntos y
reemplazarlos por comas):
txt = '';
Bucle de análisis para todas las imágenes cargadas:
for n = 1:N
Retorna el valor absoluto del determinante de la matriz (el valor absoluto del determinante
de una matriz tridimensional sirve como unidad de medida de volúmenes. SPM trabaja con mm3):
vsz = abs(det(vols(n).mat));
Lee la intensidad de cada uno de los voxels de la imagen
img = spm_read_vols(vols(n));
Multiplica la intensidad de la matriz de voxels de la imagen por la intensidad de los voxels de
la máscara. Como la máscara solo tiene valores de 0 para voxels por fuera de la máscara y 1
para voxels por dentro de la máscara, la multiplicación anula los valores de la imagen
original que no están incluidos en la máscara y mantiene intactos los valores que están por
dentro de la misma: img = img .* msk;
El valor t se obtiene de la suma de los valores de las intensidades que superen el umbral,
multiplicado por el determinante. Se divide por mil para convertir el resultado obtenido de
milímetros cúbicos a mililitros.
t = sum(img(img > thr)) * vsz / 1000;
El resto de la función sirve para que los decimales se muestren con una coma:
t = num2str(t,'%5.3f');
t = strrep(t,'.',',');
txt = strcat(txt,'-',t);
end
txt = strrep(txt,'-',char(10));
ml = txt;
display(ml)
Código estimate&write comentado para la parte que calcula los
volúmenes de GM, WM, CRF:
En volfactor hace 2 cosas, primero calcula el valor absoluto del determinante de la matriz (la
matriz la obtiene previamente y corresponde a la imagen original, no procesada ni segmentada).
Luego divide por mil, que es el factor de conversión de milímetros cúbicos a mililitros.
volfactor = abs(det(M0(1:3,1:3)))/1000;
Estas dos líneas sirven para crear el archivo de texto, en el cual se grabarán los volúmenes después
calculados.
vol_txt = fullfile(pth,['p', nam1, '_seg8.txt']);
fid = fopen(vol_txt, 'w');
El bucle for es para analizar los 3 tipos de tejidos relevantes. fprintf escribe en el archivo txt
generado el resultado de cada operación realizada en el bucle:
for i=1:3
vol = volfactor*sum(cls{i}(:))/255;
fprintf(fid,'%5.3f\t',vol);
end;
fclose(fid);
El cálculo de los volúmenes en sí se realiza mediante esta fórmula:
vol = volfactor*sum(cls{i}(:))/255;
volfactor es el determinante dividido mil. La suma se efectúa de los valores de la matriz cls
correspondiente (hay 3 matrices cls, una para cada tejido, contienen la intensidad de cada voxel,
se obtienen a partir de la segmentación). 255 es un valor que no encontré su función, pero se usa
por defecto para otro cálculos a lo largo de todo del proceso Estimate&Write.
Comparación entre ambos métodos:
1. Ambos utilizan el determinante correspondiente a su matriz. Sin embargo, al ser matrices
distintas, los determinantes varían y no son intercambiables entre sí.
2. Ambos suman las intensidades de los voxels, pero toman valores distintos al proceder de
matrices diferentes. Además, VBM8 aplica un factor de corrección (255).
3. get_totals (g-t) permite definir un umbral y una máscara, VBM no.
4. Los valores de g-t globales se alejan de lo esperado, si consideramos que un cerebro
normal tiene en total 1200 ml aproximadamente, y g-t arroja en promedio 800ml para GM
y 700ml para WM.
5. Los valores anteriores se corrigen aplicando un umbral mayor a 0, pero queda por
determinar cuál podría ser el umbral óptimo. Un valor de 0.25 reduce los ml a los valores
“esperados”. Cuando se trabaja con máscaras la corrección por umbral es ínfima.
6. Ninguno de los métodos mide el volumen nativo, se basan en los valores de tejidos
normalizados y segmentados. Sin embargo, g-t puede analizar imágenes ya suavizadas, un
requerimiento para la publicación de papers de morfometría (“Calculate raw volumen…”
de VBM8 toma los valores sin suavizar).
Una prueba de la efectividad de g-t fue obtenida midiendo un volumen conocido. Generé una
máscara (recordar que los voxels activos tienen valor de uno y los voxels que se quieren descartar
cero, con lo cual el volumen de la máscara tiene una densidad uniforme). Calcule la cantidad de
voxels activos y lo multipliqué por el tamaño del voxel (1.5mm3), dándome un volumen total para
la máscara de 4995mm3 (=4,995ml). Cuando pedí a g-t que me calcule el volumen de la máscara
me dio 4,995ml.
Los resultados que g-t brinda (sin umbral) pueden deberse a que no calcula un volumen con
densidad uniforme, en un espacio vacío. La segmentación y el suavizado producen muchos voxels
con valores reducidos, incluso imperceptibles a la vista (utilizando el display de SPM), pero que
generan ruido e incrementan el resultado en la suma de las intensidades de los voxels. Estos
artefactos pueden eliminarse estableciendo un umbral (quedaría definir cuál es el umbral óptimo).
Descargar