我正在尝试制作一个数据生成器来批量加载 DICOM 图像,以便使用 Tensorflow 在 model.fit 中使用:
dataset = tf.data.Dataset.from_tensor_slices((file_names, annotations))
dataset = dataset.map(find_path, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.map(read_dicom, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.map(augment_images, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.map(resize_images, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.map(normalize_bbox, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.batch(64, num_parallel_calls=tf.data.AUTOTUNE)
dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)
第一个函数(
find_path
)将文件名转换为路径。
第二个函数(
read_dicom
)尝试加载dicom图像,它是这样的:
from pydicom import dcmread
...
def read_dicom(path, annotation):
raw_dicom = dcmread(path)
image = dcm.pixel_data_handlers.util.apply_voi_lut(raw_dicom.pixel_array, raw_dicom)
return image, annotation
我在
dcmread(path)
中收到错误,其中显示:
TypeError: dcmread: Expected a file path or a file-like, but got SymbolicTensor
我不完全理解这种情况,但据我所知,原因是当
model.fit
在图形模式下运行时,将每个函数转换为图形。这使得每个变量都进入函数SymbolicTensor
,因此路径是SymbolicTensor
并且不能与 Pydicom 或任何其他库一起使用。
我尝试了多种方法来解决这个问题,但它们不起作用或者不适合我正在做的项目:
使用
tf.py_function
防止tensorflow将read_dicom
转换为图
此方法有效,但对我来说不可用,因为我想使用 Tensorflow 线程同时加载多个图像。如果我使用
tf.py_function
它会运行具有 GIL 的 python 代码并防止线程同时运行。
使用
Tensorflow IO
库加载图像
import tensorflow as tf
import tensorflow_io as tfio
...
def read_dicom(path, annotation):
raw_image = tf.io.read_file(path)
image = tfio.image.decode_dicom_image(raw_image)
return image, annotation
此方法不起作用,因为
tfio.image.decode_dicom_image
库中的 Tensorflow IO
不起作用。你可以查看dicom教程中tensorflow提供的colab笔记本,它在那里也不起作用!
https://www.tensorflow.org/io/tutorials/dicom https://colab.research.google.com/github/tensorflow/io/blob/master/docs/tutorials/dicom.ipynb
我应该注意,我想使用tensorflow内置多线程。
你知道我该如何解决这个问题吗?
实际上
tfio.image.decode_dicom_image
有效。您只需确保 tensorflow-io
与您的 tensorflow
版本兼容。请参阅降价从这里。
试运行:
import tensorflow as tf
import matplotlib.pyplot as plt
file_name = np.array(['dicom_00000001_000.dcm'])
annotation = np.array([1])
dataset = tf.data.Dataset.from_tensor_slices((file_name, annotation))
def read_dicom(path, annotation):
raw_image = tf.io.read_file(path)
image = tfio.image.decode_dicom_image(raw_image)
return image, annotation
dataset = dataset.map(read_dicom)
for x, y in dataset:
plt.imshow(x.numpy().squeeze(), cmap='gray')