Python 在tensorflow中的网格中平铺图像(即使用环绕)

Python 在tensorflow中的网格中平铺图像(即使用环绕),python,tensorflow,conv-neural-network,convolution,Python,Tensorflow,Conv Neural Network,Convolution,我想做的简短版本是将一堆图像(h、w、num_图像)以网格的形式平铺,以生成一个可以轻松绘制的图像,但我希望将它们放在网格中,即使用环绕(我想在tensorflow中这样做,即图形输出一个网格图像以准备绘制) 输入: a、 )列数(即单行上的最大图像数) 或 b、 )最大宽度(例如屏幕宽度)。它会自动计算出上面的值 我有numpy代码,但速度很慢,我认为在GPU上作为图形的一部分更合理 我的tensorflow图代码如下(t是卷积层的输出,因此最后一个轴包含图像堆栈): 这给了我(num_fil

我想做的简短版本是将一堆图像(h、w、num_图像)以网格的形式平铺,以生成一个可以轻松绘制的图像,但我希望将它们放在网格中,即使用环绕(我想在tensorflow中这样做,即图形输出一个网格图像以准备绘制)

输入:

a、 )列数(即单行上的最大图像数)

b、 )最大宽度(例如屏幕宽度)。它会自动计算出上面的值

我有numpy代码,但速度很慢,我认为在GPU上作为图形的一部分更合理

我的tensorflow图代码如下(t是卷积层的输出,因此最后一个轴包含图像堆栈):

这给了我(num_filters,h,w),我将其输入到我编写的更通用的numpy代码中,将其放入一个网格中(我的numpy代码相当长,因为它更通用,可以处理可变大小的图像,所以我不在下面介绍它)

这可以直接在tensorflow中实现吗


(注意,如果我要执行tf.concat而不是tf.stack,我可以将它们并排平铺,但它们没有环绕功能)

我的numpy代码只需不到20行就可以完成,而且速度非常快。当我将图像平铺到10000x1000x3时,速度非常快。如果图像不足,它会用零填充最后几个分幅

def重塑_行(arr):
返回减少(λx,y:np.串联((x,y),轴=1),arr)
def重塑颜色(arr):
返回减少(λx,y:np.串联((x,y),轴=0),arr)
定义任意行数(arr、num行数、num列数、gray=False):
num_图像,高度、宽度、深度,=arr.shape
行=[]
对于范围内的i(num_行):
行图像=arr[i*num\u cols:i*num\u cols+num\u cols]
r_n,r_h,r_w,r_d=行图像.shape
如果行_image.shape[0]!=数量:
对于范围内的(num_cols-row_image.shape[0]):
行图像=np.连接((行图像,np.展开图像,np.零点((高度、宽度、深度)),轴=0)),轴=0)
行图像=重塑行(行图像)
行。追加(行\图像)
马赛克=重塑颜色(行)
返回马赛克

您可以将此代码转换为TensorFlow代码,这样可能会更快。查看性能比较会很有趣。

事实上,我刚刚找到了一种非常简单的方法,即输入行数(这并不理想,但现在已经足够好了)


对于具有形状[批次、宽度、高度、通道]的图像,可以在tensorflow中使用

def image_grid(x, size=6):
    t = tf.unstack(x[:size * size], num=size*size, axis=0)
    rows = [tf.concat(t[i*size:(i+1)*size], axis=0) 
            for i in range(size)]
    image = tf.concat(rows, axis=1)
    return image[None]

TensorFlow中添加了一个函数,该函数正好执行以下操作:。它接受形状的输入张量
[批次、宽度、高度、通道]
,以及图像网格的形状、每个图像的尺寸和图像通道的数量作为参数。它很好用。

我有一个函数,如果你不指定你想要多少列,我可以将一个正方形网格变大,否则一个带有n列的网格

def tf_batch_to_canvas(X, cols: int = None):
"""
reshape a batch of images into a grid canvas to form a single image.

Parameters
----------
X: Tensor
    Batch of images to format. [N, H, W, C]-shaped
cols: int
    how many columns the grid should have. If None, a square grid will be created.
Returns
-------
image_grid: Tensor
    Tensor representing the image grid. [1, HH, WW, C]-shaped

Raises
------
    ValueError: The input tensor must be 4 dimensional

Examples
--------

x = np.ones((9, 100, 100, 3))
x = tf.convert_to_tensor(x)
canvas = batches.tf_batch_to_canvas(x)
assert canvas.shape == (1, 300, 300, 3)

canvas = batches.tf_batch_to_canvas(x, cols=5)
assert canvas.shape == (1, 200, 500, 3)
"""
if len(X.shape.as_list()) > 4:
    raise ValueError("input tensor has more than 4 dimensions.")
N, H, W, C = X.shape.as_list()
rc = math.sqrt(N)
if cols is None:
    rows = cols = math.ceil(rc)
else:
    cols = max(1, cols)
    rows = math.ceil(N / cols)
n_gray_tiles = cols * rows - N
if n_gray_tiles > 0:
    gray_tiles = tf.zeros((n_gray_tiles, H, W, C), X.dtype)
    X = tf.concat([X, gray_tiles], 0)
image_shape = (H, W)
n_channels = C
return image_grid(X, (rows, cols), image_shape, n_channels)

基本上,您现在可以使用
tf.contrib.gan.eval.image\u grid
,具体取决于您的tensorflow版本。


很高兴我能帮上忙!我自己也在找类似的东西,却偶然发现了。这绝对是一件有益的事情。
def image_grid(x, size=6):
    t = tf.unstack(x[:size * size], num=size*size, axis=0)
    rows = [tf.concat(t[i*size:(i+1)*size], axis=0) 
            for i in range(size)]
    image = tf.concat(rows, axis=1)
    return image[None]
def tf_batch_to_canvas(X, cols: int = None):
"""
reshape a batch of images into a grid canvas to form a single image.

Parameters
----------
X: Tensor
    Batch of images to format. [N, H, W, C]-shaped
cols: int
    how many columns the grid should have. If None, a square grid will be created.
Returns
-------
image_grid: Tensor
    Tensor representing the image grid. [1, HH, WW, C]-shaped

Raises
------
    ValueError: The input tensor must be 4 dimensional

Examples
--------

x = np.ones((9, 100, 100, 3))
x = tf.convert_to_tensor(x)
canvas = batches.tf_batch_to_canvas(x)
assert canvas.shape == (1, 300, 300, 3)

canvas = batches.tf_batch_to_canvas(x, cols=5)
assert canvas.shape == (1, 200, 500, 3)
"""
if len(X.shape.as_list()) > 4:
    raise ValueError("input tensor has more than 4 dimensions.")
N, H, W, C = X.shape.as_list()
rc = math.sqrt(N)
if cols is None:
    rows = cols = math.ceil(rc)
else:
    cols = max(1, cols)
    rows = math.ceil(N / cols)
n_gray_tiles = cols * rows - N
if n_gray_tiles > 0:
    gray_tiles = tf.zeros((n_gray_tiles, H, W, C), X.dtype)
    X = tf.concat([X, gray_tiles], 0)
image_shape = (H, W)
n_channels = C
return image_grid(X, (rows, cols), image_shape, n_channels)