Python | Numpy数组图像转换

Python | Numpy数组图像转换,python,numpy,rgb,yuv,Python,Numpy,Rgb,Yuv,我有一个Numpy图像数组,其形状(1000,50,100,3)(class'Numpy.ndarray'),其中包含1000个RGB图像(高度=50,宽度=100,通道=3)。我想首先将RGB值转换为YUV值,然后重新缩放它们以获得YUV值。下面给出了像素级转换器的典型实现 我的问题:有没有一种简单的方法可以实现这一转变 你调查过了吗 你可以做: images_yuv = np.apply_along_axis( yuv, -1, images_rgb) 编辑:混淆参数的顺序您可以对转换进行

我有一个Numpy图像数组,其形状
(1000,50,100,3)
class'Numpy.ndarray'
),其中包含1000个RGB图像(高度=50,宽度=100,通道=3)。我想首先将
RGB
值转换为
YUV
值,然后重新缩放它们以获得
YUV
值。下面给出了像素级转换器的典型实现

我的问题:有没有一种简单的方法可以实现这一转变

你调查过了吗

你可以做:

images_yuv = np.apply_along_axis( yuv, -1, images_rgb)

编辑:混淆参数的顺序

您可以对转换进行矢量化,以便所有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函数的简短嵌套循环实现:

def yuv(_pixel):
    R, G, B = _pixel[0], _pixel[1], _pixel[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
    return np.array([y, u, v])

def yuvloop(imgs):
    yuvimg = np.empty(imgs.shape)
    for n in range(imgs.shape[0]):
        for i in range(imgs.shape[1]):
            for j in range(imgs.shape[2]):
                yuvimg[n, i, j] = yuv(imgs[n, i, j])
    return yuvimg
一些速度比较:

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.沿_轴应用
似乎更慢。三种方法的结果相同。

我将测试样本的大小减少到100个图像,否则测试会太慢。

您的函数无法工作。
Y
的定义在哪里?是不是
y
@马库科修斯很好。问题是在每个像素上循环的过程效率极低。我的解决方案有效吗?如果是,你可以接受并投票表决。这也会给你一些提示。:)这是行不通的。即使使用
yuv
交换
images\u rgb
以正确传递参数,结果似乎也不正常。将参数的顺序更改为
images\u yuv=np。沿_轴(yuv,-1,imgs)应用_
并将样本大小减少到100个图像(奇怪的是,对于64GB内存的
沿_轴应用
,1000个图像似乎太多了),
np.apply_沿_轴
运行得很好,尽管速度非常慢。因此,如果性能不重要,这似乎也是一个很好的解决方案。@Scotty1-事实上,我混合了参数的顺序,可能需要批量剪切。如果函数可以就地应用,那就太好了,因为它是保形的,但它不需要看看有没有一个numpy内置的提供。一个nit:
np.random.randint(0,256,size=(100,50100,3))
数据生成的形状是否正确,为您节省了大型整形的成本。哦,很高兴知道!谢谢!我马上实现了它。
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)