您可以将转换矢量化,以便所有R、G和B像素同时变换:def yuv_vec(images):
R, G, B = images[:, :, :, 0], images[:, :, :, 1], images[:, :, :, 2]
y = (0.299 * R + 0.587 * G + 0.114 * B) / 127.5 - 1
u = (0.493 * (B - y)) / 127.5 - 1
v = (0.887 * (R - y)) / 127.5 - 1
yuv_img = np.empty(images.shape)
yuv_img[:, :, :, 0] = y
yuv_img[:, :, :, 1] = u
yuv_img[:, :, :, 2] = v
return yuv_img
为了计时性能,我将展示问题中所示的yuv函数的一个短嵌套循环实现:
^{pr2}$
一些速度比较:imgs = np.random.randint(0, 256, size=(100, 50, 100, 3))
%timeit yuvloop(imgs)
# Out: 8.79 s ± 265 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
% timeit np.apply_along_axis(yuv, -1, imgs)
# Out: 9.92 s ± 360 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit yuv_vec(imgs)
# Out: 34.4 ms ± 385 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
所以这比循环像素要快256倍。使用np.apply_along_axis似乎更慢。三者的结果都是一样的。
我将测试样本的大小缩小到100个图像,否则测试会太慢。在