簡體   English   中英

Tensorflow - 有沒有辦法實現張量方式的圖像剪切/旋轉/平移?

[英]Tensorflow - Is there a way to implement tensor-wise image shear/rotation/translation?

我正在嘗試進行不同類型的(圖像)數據增強來訓練我的神經網絡。

我知道tf.image提供了一些增強功能,但它們太簡單了 - 例如,我只能將圖像旋轉90度,而不是任何程度。

我也知道tf.keras.preprocessing.image提供隨機旋轉,隨機剪切,隨機移位和隨機縮放。 但是這些方法只能應用於numpy數組,而不是張量。

我知道我可以先讀取圖像,使用tf.keras.preprocessing.image中的函數進行擴充,然后將這些擴充的numpy數組轉換為張量。

但是,我只是想知道是否有一種方法可以實現張量增強,所以我不需要打擾“圖像文件 - >張量 - > numpy數組 - >張量”程序。


想要了解如何應用轉換的用戶的更新:

有關詳細的源代碼,您可能需要檢查tf.contrib.image.transformtf.contrib.image.matrices_to_flat_transforms

這是我的代碼:

def transformImg(imgIn,forward_transform):
    t = tf.contrib.image.matrices_to_flat_transforms(tf.linalg.inv(forward_transform))
    # please notice that forward_transform must be a float matrix,
    # e.g. [[2.0,0,0],[0,1.0,0],[0,0,1]] will work
    # but [[2,0,0],[0,1,0],[0,0,1]] will not
    imgOut = tf.contrib.image.transform(imgIn, t, interpolation="BILINEAR",name=None)
    return imgOut

基本上,上面的代碼正在做

在此輸入圖像描述 對於imgIn每個點(x,y)。

例如,平行於x軸的剪切變換

在此輸入圖像描述

因此,我們可以像這樣實現剪切變換(使用上面定義的transformImg() ):

def shear_transform_example(filename,shear_lambda):
    image_string = tf.read_file(filename)
    image_decoded = tf.image.decode_jpeg(image_string, channels=3)
    img = transformImg(image_decoded, [[1.0,shear_lambda,0],[0,1.0,0],[0,0,1.0]])
    return img
img = shear_transform_example("white_square.jpg",0.1)

原始圖片: 在此輸入圖像描述

改造后: 在此輸入圖像描述

(請注意, img是張量,不包括將張量轉換為圖像文件的代碼。)

PS

以上代碼適用於tensorflow 1.10.1,可能不適用於將來的版本。

說實話,我真的不知道他們為什么設計tf.contrib.image.transform,我們必須使用另一個函數(tf.linalg.inv)來獲得我們想要的東西。 我真的希望他們能夠以更直觀的方式改變tf.contrib.image.transform。

看看tf.contrib.image.transform 它可以將一般投影變換應用於圖像。

您還需要查看tf.contrib.image.matrices_to_flat_transforms ,將您的仿射矩陣轉換為tf.contrib.image.transform接受的投影格式。

我通常使用tf.data.Dataset s的Dataset.maptf.py_func Dataset.prefetch意味着通常沒有時間成本(只要CPU上的預處理比在GPU上運行網絡所花費的時間少)。 如果您在多個GPU上運行,您可能需要重新考慮,但以下適用於單GPU系統的情況。

為簡單起見,我假設您將所有圖像都放在磁盤上的單獨文件中,雖然它可以很容易地適用於zip存檔或其他格式,如hdf5(不適用於.tar文件 - 不知道為什么,但我懷疑它會無論如何,這是一個好主意。)

import tensorflow as tf
from PIL import Image


def map_tf(path_tensor, label_tensor):
    # path_tensor and label_tensor correspond to a single example

    def map_np(path_str):
        # path_str is just a normal string here
        image = np.array(Image.load(path_str), dtype=np.uint8)
        image = any_cv2_or_numpy_augmentations(image)
        return image,

    image, = tf.py_func(
        map_np, (path_tensor,), Tout=(tf.uint8,), stateful=False)
    # any tensorflow operations here.
    image = tf.cast(image, tf.float32) / 255

    image.set_shape((224, 224, 3))
    return image, label


paths, labels = load_image_paths_and_labels()
dataset = tf.data.Dataset.from_tensor_slices((paths, labels))
if is_training:
    shuffle_buffer = len(paths)  # full shuffling - can be shorter
    dataset = dataset.shuffle(shuffle_buffer).repeat()
dataset = dataset.map(map_tf_fn, num_parallel_calls=8)
dataset = dataset.batch(batch_size)

dataset = dataset.prefetch(1)
# play with the following if you want - not finalized API, and only in
# more recent version of tensorflow
# dataset = dataset.apply(tf.contrib.data.prefetch_to_device('/gpu:0'))

image_batch, label_batch = dataset.make_one_shot_iterator().get_next()

你也可以在tensorflow中進行解碼並直接在py_func使用any_cv2_or_numpy_augmentations (盡管你沒有避免在你的問題中提到的張量 - > numpy - > tensor dance)。 我懷疑你會注意到性能差異。

查看此答案以獲取更多選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM