我想以随机方式从图像中打乱像素。通过以下功能,一切都按照我想要的方式工作,但速度很慢。
def randomize_image(img):
# convert image from (m,n,3) to (N,3)
rndImg = np.reshape(img, (img.shape[0]*img.shape[1], img.shape[2]))
start_time = time.perf_counter()
np.random.shuffle(rndImg)
end_time = time.perf_counter()
print('Time random shuffle: ', end_time - start_time)
rndImg = np.reshape(rndImg, img.shape)
return rndImg
这就是为什么我将其更改为下一个功能。它也正在工作,dtype 是
谢谢
def rand_shuffle_faster(img):
# convert image from (m,n,3) to (N,3)
rndImg = np.reshape(img, (img.shape[0]*img.shape[1], img.shape[2]))
length = rndImg.shape[1]
yield rndImg[:, np.random.permutation(length)]
rndImg = np.reshape(rndImg, img.shape)
return rndImg
听起来您最终想要的是第一个函数的更快版本;我认为将函数转换为带有
yield
的 Python 生成器是没有必要的,您这样做只是为了寻找更快的替代方案。 (请注意,它看起来更快只是因为它没有完成所有工作。)
你是对的,生成索引的排列数组并使用它们来洗牌图像往往比使用
shuffle
更快。
import numpy as np
def randomize_image(img):
# convert image from (m,n,3) to (N,3)
rndImg = np.reshape(img, (-1, img.shape[2]))
np.random.shuffle(rndImg)
rndImg = np.reshape(rndImg, img.shape)
return rndImg
def randomize_image2(img):
# convert image from (m,n,3) to (N,3)
rndImg = np.reshape(img, (-1, img.shape[2]))
i = np.random.permutation(len(rndImg))
rndImg = rndImg[i, :]
rndImg = np.reshape(rndImg, img.shape)
return rndImg
m, n = 1000, 1000
img = np.arange(m*n*3).reshape(m, n, 3)
img1 = randomize_image(img)
%timeit randomize_image1(img)
# 1.69 s ± 505 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
img2 = randomize_image2(img)
%timeit randomize_image2(img)
# 152 ms ± 31.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
根据图像的大小,使用 NumPy Generator 执行排列(而不是
np.random.permutation
)可能会更快。
# include this outside of the function
rng = np.random.default_rng()
...
# inside the function, replace
# i = np.random.permutation(len(rndImg)
# with:
i = rng.permutation(len(rndImg))