Pyradiomics: ¿Por qué se produciría un desajuste de geometría cuando la máscara y la imagen se derivan de la misma serie DICOM?

Creado en 23 abr. 2019  ·  13Comentarios  ·  Fuente: AIM-Harvard/pyradiomics

Hola,

Para el contexto, he podido ejecutar PyRadiomics con éxito desde la línea de comandos, tanto para pares de máscara de imagen única, como para ejecutar la extracción por lotes para decenas de pares de máscara de imagen simultáneamente con varias configuraciones de YAML. Sin embargo, me he encontrado con un problema que sé cómo solucionarlo, pero todavía tengo curiosidad por saber por qué ocurre.

La configuración: tengo una serie DICOM para un solo paciente con 158 cortes, cada uno de una dimensión de 512x512 píxeles. Cargué la serie en Slicer y contorneé un ROI (nódulo) y luego exporté el mapa de etiquetas binarias como un archivo .nrrd. Luego, utilicé la herramienta de línea de comandos dcm2niix para convertir la misma serie DICOM en un volumen .nii.

Cuando ejecuto pyradiomics desde la terminal usando la imagen .nii y la máscara .nrrd, obtengo una discrepancia de geometría como se describe a continuación. ¿Por qué ocurriría esto si la máscara y el volumen de la imagen se derivaran de la misma serie DICOM? ¿Es esta una ocurrencia esperada?

Como se mencionó, dos soluciones son: (1) guardar la imagen como un volumen .nii o .nrrd directamente desde Slicer, y esto parece funcionar bien; (2) Ajuste el valor de tolerancia (aunque esta solución me hace sentir incómodo). Eventualmente, quiero realizar la conversión por lotes de cientos de series DICOM 'a volúmenes .nii o .nrrd, y ya tengo máscaras para estos cientos de series. Así que esperaba usar una herramienta de línea de comandos para la conversión por lotes de dcm >> nii o nrrd en lugar de Slicer.

Gracias por tu ayuda.

[2019-04-23 16:38:19] E: radiomics.script: Feature extraction failed!
Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/pyradiomics-0+unknown-py3.6-macosx-10.7-x86_64.egg/radiomics/imageoperations.py", line 192, in checkMask
    lsif.Execute(imageNode, maskNode)
  File "/anaconda3/lib/python3.6/site-packages/SimpleITK/SimpleITK.py", line 43958, in Execute
    return _SimpleITK.LabelStatisticsImageFilter_Execute(self, *args)
RuntimeError: Exception thrown in SimpleITK LabelStatisticsImageFilter_Execute: /scratch/dashboard/SimpleITK-OSX10.6-x86_64-pkg/SimpleITK-build/ITK-prefix/include/ITK-4.13/itkImageToImageFilter.hxx:241:
itk::ERROR: LabelStatisticsImageFilter(0x7fcd1e601050): Inputs do not occupy the same physical space! 
InputImage Origin: [-1.8200000e+02, 1.6933569e+02, -3.0314999e+02], InputImage_1 Origin: [-1.8200000e+02, -1.7000000e+02, -3.0314999e+02]
    Tolerance: 6.6406202e-07
InputImage Direction: 1.0000000e+00 0.0000000e+00 0.0000000e+00
0.0000000e+00 -1.0000000e+00 0.0000000e+00
0.0000000e+00 0.0000000e+00 1.0000000e+00
, InputImage_1 Direction: 1.0000000e+00 0.0000000e+00 0.0000000e+00
0.0000000e+00 1.0000000e+00 0.0000000e+00
0.0000000e+00 0.0000000e+00 1.0000000e+00

    Tolerance: 1.0000000e-06


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/anaconda3/lib/python3.6/site-packages/pyradiomics-0+unknown-py3.6-macosx-10.7-x86_64.egg/radiomics/scripts/segment.py", line 40, in extractSegment
    feature_vector.update(extractor.execute(imageFilepath, maskFilepath, label))
  File "/anaconda3/lib/python3.6/site-packages/pyradiomics-0+unknown-py3.6-macosx-10.7-x86_64.egg/radiomics/featureextractor.py", line 397, in execute
    boundingBox, correctedMask = imageoperations.checkMask(image, mask, **self.settings)
  File "/anaconda3/lib/python3.6/site-packages/pyradiomics-0+unknown-py3.6-macosx-10.7-x86_64.egg/radiomics/imageoperations.py", line 207, in checkMask
    raise ValueError('Image/Mask geometry mismatch. Potential fix: increase tolerance using geometryTolerance, '
ValueError: Image/Mask geometry mismatch. Potential fix: increase tolerance using geometryTolerance, see Documentation:Usage:Customizing the Extraction:Settings:geometryTolerance for more information
question

Todos 13 comentarios

Esto se debe a que la tolerancia predeterminada es demasiado estricta. Lo más fácil sería habilitar el remuestreo.

@warkentinmatt También es posible solucionarlo habilitando correctMask . Esto permite volver a muestrear la máscara (vecino más cercano), sin volver a muestrear la imagen. El único requisito es que el espacio físico de la máscara esté contenido dentro de la imagen.

Lo que sospecho que sucedió es que su máscara tiene el mismo espaciado / dirección que la imagen, pero el tamaño y el origen son diferentes, ya que Slicer ahora almacena la máscara recortando el área y ajustando el origen en consecuencia. Esto ahorra memoria, pero requiere que le digas a PyRadiomics que está bien volver a muestrear máscaras (que, en este último caso, equivale a rellenar hasta que coincida con el tamaño de la imagen).

PyRadiomics no corrige la máscara de forma predeterminada, ya que esto sirve como una advertencia para el paso adicional que PyRadiomics está realizando.

Gracias a ambos por sus respuestas.

@JoostJM Entonces, solo para asegurarme de que entiendo sus comentarios, cuando Slicer exporta / guarda un mapa de etiquetas NRRD, ¿recorta el tamaño en la medida del ROI? ¿No mantiene la dimensionalidad original del volumen de entrada? Cuando borro la escena en Slicer, vuelvo a importar la serie DICOM y luego la cargo en la máscara NRRD, la máscara se superpone a la tomografía computarizada en la ubicación anatómica adecuada. Para mí, asumí que esto significaba que las dimensiones originales de la TC se mantuvieron en la máscara. ¿Slicer es lo suficientemente inteligente (es decir, utiliza los metadatos correctos) para alinear correctamente la máscara en el CT?

Además, para tener claro lo que se logra con el remuestreo de la máscara binaria: tengo entendido que si el ROI está ubicado en el centro de la imagen (por lo tanto, el centro de la matriz contiene algunos cientos / miles de "1"), ese remuestreo el vecino más cercano de la máscara en el borde del volumen está esencialmente rellenando la máscara con ceros? ¿Es esta una interpretación correcta?

Gracias por tu ayuda.

Entonces, solo para asegurarme de entender sus comentarios, cuando Slicer exporta / guarda un mapa de etiquetas NRRD, ¿recorta el tamaño en la medida del ROI?

Sí, esto es posible, porque los archivos Nrrd también contienen el origen, es decir, la ubicación física del primer vóxel.
Nrrd también contiene información sobre la dirección y el espaciado, lo que le permite superponer incluso las segmentaciones realizadas en imágenes con diferentes tamaños de píxeles o incluso las que se giran.
Esta es también la razón por la que las matrices numpy no se aceptan como entrada para PyRadiomics, ya que no contienen esta información geométrica.

Además, para tener claro lo que se logra con el remuestreo de la máscara binaria: tengo entendido que si el ROI está ubicado en el centro de la imagen (por lo tanto, el centro de la matriz contiene algunos cientos / miles de "1"), ese remuestreo el vecino más cercano de la máscara en el borde del volumen está esencialmente rellenando la máscara con ceros? ¿Es esta una interpretación correcta?

Correcto

Cuando borro la escena en Slicer, vuelvo a importar la serie DICOM y luego la cargo en la máscara NRRD, la máscara se superpone a la tomografía computarizada en la ubicación anatómica adecuada. Para mí, asumí que esto significaba que las dimensiones originales de la TC se mantuvieron en la máscara. ¿Slicer es lo suficientemente inteligente (es decir, utiliza los metadatos correctos) para alinear correctamente la máscara en el CT?

La máscara puede corresponder a una subregión de la imagen del tamaño del cuadro delimitador de la máscara. No es necesario que tenga las mismas dimensiones que la imagen. Si las dimensiones coinciden o no, dependerá de cómo cree la segmentación en Slicer y de cómo la exporte. Si desea obtener más detalles sobre cómo garantizar que las dimensiones coincidan, háganoslo saber.

Mirando de nuevo el error (la primera vez que miré el teléfono), aquí están las diferencias:

InputImage Origin: [-1.8200000e+02, 1.6933569e+02, -3.0314999e+02], 
InputImage_1 Origin: [-1.8200000e+02, -1.7000000e+02, -3.0314999e+02]
    Tolerance: 6.6406202e-07

InputImage Direction: 1.0000000e+00 0.0000000e+00 0.0000000e+00
0.0000000e+00 -1.0000000e+00 0.0000000e+00
0.0000000e+00 0.0000000e+00 1.0000000e+00
, 

InputImage_1 Direction: 1.0000000e+00 0.0000000e+00 0.0000000e+00
0.0000000e+00 1.0000000e+00 0.0000000e+00
0.0000000e+00 0.0000000e+00 1.0000000e+00

Entonces, tiene la situación en la que el valor absoluto de origen está ligeramente desviado (y la diferencia es mayor que la tolerancia predeterminada), pero también que la orientación de una imagen se invierte en Y en comparación con la otra. Esto significa que no puede solucionar el problema reduciendo la tolerancia y deberá volver a muestrear la máscara o la imagen. Sin embargo, este remuestreo no debería alterar los valores de los píxeles, será efectivamente una operación de reorientación.

@JoostJM Gracias por su respuesta nuevamente, muy apreciada.

@fedorov ¿Cómo resolvería el remuestreo de la máscara o la imagen el problema de que Y se invierte en uno en relación con el otro? Esto no me queda claro. Tenía entendido que se utilizó el remuestreo para garantizar el mismo tamaño / dimensiones.

Si desea obtener más detalles sobre cómo garantizar que las dimensiones coincidan, háganoslo saber.

Sí, me encantaría obtener más información sobre cómo garantizar que las dimensiones coincidan. Por favor y gracias.

De hecho, me encantaría cualquier información o recurso que pudiera fortalecer mi comprensión de algunos de estos conceptos que hemos discutido (es decir, espaciado, dirección, origen). Ingenuamente, podría pensar que el origen de una imagen son las coordenadas [x, y, z] de [0,0,0], en otras palabras, una de las "esquinas" (¿anterior superior derecho?) De una matriz de imágenes. . ¿Los valores de origen que se muestran en el registro tienen una interpretación tangible (por ejemplo, milímetros o algo así)? ¿Qué representan estos números? Perdone mi ignorancia, soy autodidacta en todo lo relacionado con imágenes / radiomics, pero quiero comprender estos conceptos en lugar de simplemente implementar soluciones para que las cosas funcionen.

@warkentinmatt no se preocupe por todas las preguntas, ¡es una curva empinada para un principiante!

¿Cómo resolvería el remuestreo de la máscara o la imagen el problema de que Y se invierte en uno en relación con el otro?

Las direcciones de la imagen son esencialmente una transformación que rota el sistema de coordenadas de la matriz de imágenes (IJK) al espacio anatómico (XYZ).

En un ejemplo simple de 1D a continuación, "índice de matriz" es el sistema de coordenadas de su matriz 1d, e Izquierda-Derecha es el sistema de coordenadas en el espacio físico de un mundo 1d. En Image2, el orden de los valores en la matriz es opuesto a la dirección del eje del sistema de coordenadas físico, es decir, la matriz de vóxeles está orientada de manera diferente. El remuestreo toma la geometría de una imagen definida por el tamaño de la matriz, la dirección y el origen, y toma muestras de los valores de otra imagen en los vóxeles de la geometría de referencia.

image

¿Esto tiene sentido?

Si desea obtener más detalles sobre cómo garantizar que las dimensiones coincidan al exportar la etiqueta desde 3D Slicer, háganoslo saber.
Sí, me encantaría obtener más información sobre cómo garantizar que las dimensiones coincidan. Por favor y gracias.

Vea la captura de pantalla a continuación sobre cómo exportar un segmento de 3D Slicer a un mapa de etiquetas (que efectivamente es una imagen binaria). Tenga en cuenta que incluso si sigue este procedimiento, no es imposible que siga teniendo un desajuste de geometría, ya que los valores de tolerancia predeterminados son demasiado estrictos. Pero la orientación de la matriz de imágenes debería ser la misma.

image

De hecho, me encantaría cualquier información o recurso que pudiera fortalecer mi comprensión de algunos de estos conceptos que hemos discutido (es decir, espaciado, dirección, origen). Ingenuamente, podría pensar que el origen de una imagen son las coordenadas [x, y, z] de [0,0,0], en otras palabras, una de las "esquinas" (¿anterior superior derecho?) De una matriz de imágenes. . ¿Los valores de origen que se muestran en el registro tienen una interpretación tangible (por ejemplo, milímetros o algo así)? ¿Qué representan estos números? Perdone mi ignorancia, soy autodidacta en todo lo relacionado con imágenes / radiomics, pero quiero comprender estos conceptos en lugar de simplemente implementar soluciones para que las cosas funcionen.

A continuación, se muestran algunos recursos que pueden resultar útiles:

¡Espero que esto ayude!

@fedorov Muchas gracias por tomarse el tiempo para explicar estos conceptos, eso fue muy útil. Tiene mucho más sentido y agradezco su paciencia.

Entonces me parece que el remuestreo tiene dos funciones importantes pero distintas para garantizar la alineación geométrica entre dos volúmenes:

1) Primero, si es necesario, rellene el volumen más pequeño hasta que coincida con el mismo tamaño / dimensionalidad del volumen de referencia, utilizando algo como los vecinos más cercanos.

2) Luego, una vez que el tamaño esté de acuerdo, use la información de origen, dirección y espaciado para muestrear los vóxeles de manera que se asegure que dos volúmenes que están en alineación anatómica / física también se indexen de la misma manera (es decir, alineación de índice de matriz ).

¿Sería este un resumen justo de la función del remuestreo?

Además, gracias por compartir estos recursos, espero trabajar con ellos para fortalecer mi comprensión.

@warkentinmatt , casi. Los pasos 1 y 2 ocurren simultáneamente. Lo que ocurre es que define una cuadrícula de puntos en el espacio físico y luego muestra su imagen en esos puntos. Si los nuevos puntos de cuadrícula no coinciden exactamente con los puntos de cuadrícula existentes, los nuevos valores se calculan utilizando el algoritmo de interpolación, basado en los puntos (píxeles) circundantes (originales) de la imagen.

También puede encontrar una explicación extensa en los documentos de IBSI, sección sobre interpolación . También contiene una imagen que ilustra la cuadrícula de remuestreo.

@fedorov @JoostJM Sé que este problema está cerrado y estoy profundamente agradecido por toda la ayuda que ambos han brindado. Solo quería regresar para aclarar mi comprensión. Después de leer un montón a través de los recursos que cada uno proporcionó y ver algunos videos útiles, me siento mucho más cómodo con estos conceptos.

Entonces, en el ejemplo que generó este problema, dado que la máscara se derivó de la misma imagen que se estaba utilizando para la extracción de características, el espaciado fue el mismo. En otras palabras, un cambio de una unidad en la ubicación del vóxel en cualquiera de las direcciones x, y, z para la máscara o la imagen conlleva la misma interpretación de cambio físico. En los casos en que el espaciado es el mismo entre una máscara y una imagen, la interpolación no sería necesaria para "llenar los espacios", ¿correcto? Por lo tanto, volver a muestrear la máscara simplemente garantizaría una coincidencia geométrica con la imagen con respecto a la dimensionalidad del volumen, además de garantizar que ambos volúmenes que están en alineación física también estén indexados por matriz de la misma manera (con respecto a la dirección y el origen ). ¿He entendido esto correctamente finalmente?

Si el espaciado no fuera el mismo entre dos volúmenes, necesitaría interpolar vóxeles para obtener dos volúmenes en alineación geométrica. Por ejemplo, si el espaciado de la imagen era [1 mm, 1 mm, 1 mm] y la máscara era [2 mm, 2 mm, 2 mm], necesitaría interpolar vóxeles en la máscara para "llenar los huecos" en el espaciado físico.

Gracias, de nuevo, por toda su ayuda. Ha hecho toda la diferencia.

@warkentinmatt sí, esto tiene sentido, ¡creo que lo hiciste bien!

Otro recurso útil relacionado con el remuestreo es esta página: https://www.slicer.org/wiki/Registration : Remuestreo

@fedorov Genial. Gracias, de nuevo, por toda su ayuda.

Puede que este no sea el momento ni el lugar, pero tengo entendido que reside en Boston. Actualmente, soy candidato a doctorado en Toronto, pero me voy a mudar a Boston por dos semanas para una beca de investigación en el Departamento de Bioestadística de HSPH. Me encantaría conectarme en persona y tal vez continuar con algunas de estas conversaciones, si estuviera interesado y tuviera tiempo. De cualquier manera, su ayuda ha sido muy apreciada.

¡Seguro, feliz de conectarme y aprender más sobre cómo usa la piradiómica! Solo envíame un correo electrónico (es público en mi perfil de github) y podemos encontrarnos para tomar un café.

¿Fue útil esta página
0 / 5 - 0 calificaciones