Tensorflow 的 Tiff 解决方法
Tiff workaround for Tensorflow
我需要构建一个数据加载器来训练 CNN 使用 tensorflow 进行语义分割。图像是 3 通道 tiff 训练图像和 1 通道(灰度)tiff 掩码。
到目前为止,我关注了 this example。他们写了一个函数
def parse_image(img_path: str) -> dict:
image = tf.io.read_file(img_path)
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.convert_image_dtype(image, tf.uint8)
mask_path = tf.strings.regex_replace(img_path, "images", "annotations")
mask_path = tf.strings.regex_replace(mask_path, "jpg", "png")
mask = tf.io.read_file(mask_path)
mask = tf.image.decode_png(mask, channels=1)
mask = tf.where(mask == 255, np.dtype('uint8').type(0), mask)
return {'image': image, 'segmentation_mask': mask}
适用于 jpeg 和 png 图像。但是,对于 tiff,必须使用 tfio.experimental.image.decode_tiff(image)
,这是非常有限的,在我的情况下不起作用。它吐出很多错误,例如
TIFFReadDirectory: Warning, Unknown field with tag 42112 (0xa480) encountered.
如 中所述,我可以使用 cv2
或 PIL
等包。
我尝试实现如下:
import cv2
def parse_image(img_path: str) -> dict:
# read image
image = cv2.imread(img_path)
image = tf.convert_to_tensor(image, tf.uint8)
# read mask
mask_path = tf.strings.regex_replace(img_path, "X", "y")
mask_path = tf.strings.regex_replace(mask_path, "X.tif", "y.tif")
mask = cv2.imread(mask_path)
mask = tf.convert_to_tensor(mask, tf.uint8)
return {"image": image, "segmentation_mask": mask}
然而,这只会导致
TypeError: in user code:
<ipython-input-46-41b06b3732aa>:6 parse_image *
image = cv2.imread(img_path)
TypeError: Can't convert object of type 'Tensor' to 'str' for 'filename'
我想在这个函数中使用非tensorflow函数会出现更多问题
因为我看过一些关于 tensorflow 和 tiff 的类似问题的旧帖子,我想知道在此期间是否有解决方法?例如,一些与 tensorflow 的其余部分兼容并可以读取 tiff 数据的自定义函数?
如果您仍然愿意使用 opencv
,那么您可以将阅读功能包装在 tf.numpy_function
中。在包裹在 tf.numpy_function
中的函数范围内,您处理 numpy 数组,因此在调用 cv2.imread
.[=21= 之前需要将 numpy 字节串表示转换为常规 python 字符串]
import tensorflow as tf
import cv2
def parse_with_opencv(image_path):
return cv2.imread(image_path.decode('UTF-8'))
img_path = ["/path/to/image.tif"]
ds = tf.data.Dataset.from_tensor_slices(img_path).map(
lambda x: tf.numpy_function(parse_with_opencv, [x], Tout=tf.uint8)
)
处理 tf.numpy_function
有时会有点令人沮丧,因为错误消息可能有些晦涩难懂。
另一种选择是使用 decode_tiff
function from the tfio
module。它与 TensorFlow 操作兼容。当然它有局限性。
一个例子:
import tensorflow as tf
import tensorflow_io as tfio
def parse_image(image_path):
filecontent = tf.io.read_file(image_path)
img = tfio.experimental.image.decode_tiff(filecontent)
return img
img_path = ["/path/to/image.tif"]
ds = tf.data.Dataset.from_tensor_slices(img_path).map(parse_image)
我需要构建一个数据加载器来训练 CNN 使用 tensorflow 进行语义分割。图像是 3 通道 tiff 训练图像和 1 通道(灰度)tiff 掩码。
到目前为止,我关注了 this example。他们写了一个函数
def parse_image(img_path: str) -> dict:
image = tf.io.read_file(img_path)
image = tf.image.decode_jpeg(image, channels=3)
image = tf.image.convert_image_dtype(image, tf.uint8)
mask_path = tf.strings.regex_replace(img_path, "images", "annotations")
mask_path = tf.strings.regex_replace(mask_path, "jpg", "png")
mask = tf.io.read_file(mask_path)
mask = tf.image.decode_png(mask, channels=1)
mask = tf.where(mask == 255, np.dtype('uint8').type(0), mask)
return {'image': image, 'segmentation_mask': mask}
适用于 jpeg 和 png 图像。但是,对于 tiff,必须使用 tfio.experimental.image.decode_tiff(image)
,这是非常有限的,在我的情况下不起作用。它吐出很多错误,例如
TIFFReadDirectory: Warning, Unknown field with tag 42112 (0xa480) encountered.
如 cv2
或 PIL
等包。
我尝试实现如下:
import cv2
def parse_image(img_path: str) -> dict:
# read image
image = cv2.imread(img_path)
image = tf.convert_to_tensor(image, tf.uint8)
# read mask
mask_path = tf.strings.regex_replace(img_path, "X", "y")
mask_path = tf.strings.regex_replace(mask_path, "X.tif", "y.tif")
mask = cv2.imread(mask_path)
mask = tf.convert_to_tensor(mask, tf.uint8)
return {"image": image, "segmentation_mask": mask}
然而,这只会导致
TypeError: in user code:
<ipython-input-46-41b06b3732aa>:6 parse_image *
image = cv2.imread(img_path)
TypeError: Can't convert object of type 'Tensor' to 'str' for 'filename'
我想在这个函数中使用非tensorflow函数会出现更多问题
因为我看过一些关于 tensorflow 和 tiff 的类似问题的旧帖子,我想知道在此期间是否有解决方法?例如,一些与 tensorflow 的其余部分兼容并可以读取 tiff 数据的自定义函数?
如果您仍然愿意使用 opencv
,那么您可以将阅读功能包装在 tf.numpy_function
中。在包裹在 tf.numpy_function
中的函数范围内,您处理 numpy 数组,因此在调用 cv2.imread
.[=21= 之前需要将 numpy 字节串表示转换为常规 python 字符串]
import tensorflow as tf
import cv2
def parse_with_opencv(image_path):
return cv2.imread(image_path.decode('UTF-8'))
img_path = ["/path/to/image.tif"]
ds = tf.data.Dataset.from_tensor_slices(img_path).map(
lambda x: tf.numpy_function(parse_with_opencv, [x], Tout=tf.uint8)
)
处理 tf.numpy_function
有时会有点令人沮丧,因为错误消息可能有些晦涩难懂。
另一种选择是使用 decode_tiff
function from the tfio
module。它与 TensorFlow 操作兼容。当然它有局限性。
一个例子:
import tensorflow as tf
import tensorflow_io as tfio
def parse_image(image_path):
filecontent = tf.io.read_file(image_path)
img = tfio.experimental.image.decode_tiff(filecontent)
return img
img_path = ["/path/to/image.tif"]
ds = tf.data.Dataset.from_tensor_slices(img_path).map(parse_image)