Python | numpy数组图像转换

时间:2019-01-25 11:35:12

标签: python numpy rgb yuv

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

  

我的问题:有没有一种简单的方法可以执行此转换?

def yuv(_pixel):
    R, G, B = _pixel[0], _pixel[1], _pixel[2]
    Y = 0.299 *  R + 0.587 * G + 0.114 * B
    y = Y / 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])

2 个答案:

答案 0 :(得分:2)

您看过numpy.apply_along_axis吗?

您可以这样做:

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

编辑:混淆参数的顺序

答案 1 :(得分:1)

您可以向量化转换,以便使用以下方法同时转换所有R,G和B像素:

import java.net.*;

import java.io.*;

public class bpart
{
    public static void main(String[] args) throws Exception {

        URL oracle = new URL("http://www.google.com/");
        BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));

        OutputStream os = new FileOutputStream("my file location");


        String inputLine;
        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}

为提高性能,我将演示问题中显示的yuv函数的简短嵌套循环实现:

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

一些速度比较:

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

因此,这比循环遍历像素快 256倍。使用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) 似乎更慢。这三个的结果都相同。
我将测试样本的大小减少到100张图像,否则测试太慢了。