有没有一种快速的方法来随机播放段中的numpy图片?

时间:2019-09-24 07:02:09

标签: python image numpy

我想编写一个可以拍摄小图像并以块为单位返回它们的排列的函数。

基本上我想把这个转过来:

enter image description here

对此:

enter image description here

Is there a function in Python that shuffle data by data blocks?中有一个很好的答案,它帮助我编写了一个解决方案。但是,对于约50,000张28x28图像,这需要很长时间才能运行。

# blocks of 7x7 shuffling
range1 = np.arange(4) 
range2 = np.arange(4)
block_size = int(28 / 4)
print([[x[i*block_size:(i+1)*block_size].shape] for i in range1])
for x in x1:
  np.random.shuffle(range1)
  x[:] = np.block([[x[i*block_size:(i+1)*block_size]] for i in range1])
  for a in x:
    np.random.shuffle(range2)
    a[:] = np.block([a[i*block_size:(i+1)*block_size] for i in range2])

print("x1", time.time() - begin)
begin = time.time()

2 个答案:

答案 0 :(得分:2)

这是一种基于this post的方法-

def randomize_tiles_3D(x1, H, W):
    # W,H are width and height of blocks
    m,n,p = x1.shape
    l1,l2 = n//H,p//W
    combs  = np.random.rand(m,l1*l2).argsort(axis=1)
    r,c = np.unravel_index(combs,(l1,l2))
    x1cr = x1.reshape(-1,l1,H,l2,W)
    out = x1cr[np.arange(m)[:,None],r,:,c]
    return out.reshape(-1,l1,l2,H,W).swapaxes(2,3).reshape(-1,n,p)

样品运行-

In [46]: x1
Out[46]: 
array([[[ 0,  1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10, 11],
        [12, 13, 14, 15, 16, 17],
        [18, 19, 20, 21, 22, 23],
        [24, 25, 26, 27, 28, 29],
        [30, 31, 32, 33, 34, 35]],

       [[36, 37, 38, 39, 40, 41],
        [42, 43, 44, 45, 46, 47],
        [48, 49, 50, 51, 52, 53],
        [54, 55, 56, 57, 58, 59],
        [60, 61, 62, 63, 64, 65],
        [66, 67, 68, 69, 70, 71]]])

In [47]: np.random.seed(0)

In [48]: randomize_tiles_3D(x1, H=3, W=3)
Out[48]: 
array([[[21, 22, 23,  0,  1,  2],
        [27, 28, 29,  6,  7,  8],
        [33, 34, 35, 12, 13, 14],
        [18, 19, 20,  3,  4,  5],
        [24, 25, 26,  9, 10, 11],
        [30, 31, 32, 15, 16, 17]],

       [[36, 37, 38, 54, 55, 56],
        [42, 43, 44, 60, 61, 62],
        [48, 49, 50, 66, 67, 68],
        [39, 40, 41, 57, 58, 59],
        [45, 46, 47, 63, 64, 65],
        [51, 52, 53, 69, 70, 71]]])

答案 1 :(得分:0)

我已经找到了运行速度更快的解决方案。我觉得很傻,因为我真的不需要double for循环,只需要两个单独的shuffle索引。万一有人想以numpy的方式按块随机播放图像,请将此解决方案留在这里。

如果有人想出另一个好的解决方案,请告诉我。


# blocks of 7x7 shuffling
range1 = np.arange(4) 
range2 = np.arange(4)
block_size = int(28 / 4)
for x in x1:
  np.random.shuffle(range1)
  np.random.shuffle(range2)
  x[:] = np.block([[x[i*block_size:(i+1)*block_size]] for i in range1])
  x[:] = np.block([x[:,i*block_size:(i+1)*block_size] for i in range2])