Существует ли быстрый способ перетасовки изображения с фрагментами в сегментах? - PullRequest
1 голос
/ 24 сентября 2019

Я хочу написать функцию, которая может снимать небольшие изображения и возвращать их перестановку, по блокам.

В основном я хочу включить это:

enter image description here

В это:

enter image description here

Был отличный ответ в Есть ли в Python функция, которая перемешиваетданные по блокам данных? , которые помогли мне написать решение.Однако для ~ 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 ]

2 голосов
/ 24 сентября 2019

Вот один подход, основанный на 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]]])
0 голосов
/ 24 сентября 2019

Я уже нашел решение, которое работает намного быстрее.Я чувствую себя глупо, потому что мне действительно не нужен двойной цикл for, только два отдельных индекса тасования.Оставьте это решение здесь на тот случай, если кто-то захочет перетасовать изображение блочным образом в ноль.

Если кто-нибудь придумает другое хорошее решение, дайте мне знать.


# 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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...