[Python] Elementweise Matrixoperationen definieren

Jennesta

Erfahrenes Mitglied
Hallo,

ich bin noch relativ neu in Python, muss aber einige Projekte damit schreiben. In dem Projekt muss ich viel mit Bildern arbeiten, daher habe ich recht große Matrizen. Da ich keine Funktion für Python gefunden habe, die Bilder von RGB in YCbCr umwandelt, wollte ich mir die Funktion selbst schreiben

Python:
def rgb2ycbcr(rgb):
    dim = np.shape(rgb)
    for m in range(dim[0]):
        for n in range(dim[1]):
            rgb[m, n , 0] = 16.0 + (65.738*rgb[m, n, 0] + 129.057*rgb[m, n, 1] + 25.064*rgb[m, n, 2]) / 256.0
            rgb[m, n , 1] = 128.0 + (-37.945*rgb[m, n, 0] - 74.494*rgb[m, n, 1] + 112.439*rgb[m, n, 2]) / 256.0
            rgb[m, n , 2] = 128.0 + (112.439*rgb[m, n, 0] - 94.154*rgb[m, n, 1] - 18.285*rgb[m, n, 2]) / 256.0
    
    return rgb

Da ich normalerweise in C programmiere ist die herangehensweise daran angelehnt. Nun braucht der Code für die Ausführung allerdings mehrere Minuten, was absolut inakzeptabel ist.

Daher die Frage, kann mir irgendwer zeigen, wie man mit numpy effiziente Punktoperationen implementieren kann, ohne die Funktion selbst in C zu schreiben und dann mit Python zu nutzen?

Grüße,
Jennesta
 
Ich habe nun einen Weg gefunden, wie das Problem akzeptabel gelöst werden kann. Durch Zufall bin ich auf die SciPy-Module gestoßen, wo Functionen wie rgb2xyz usw. definiert werden. Dort habe ich mir dann den folgenden Weg abgeschaut.

Python:
import numpy as np
import skimage.util.dtype as sud

def rgb2ycbcr(rgb):
    """
    Transform image from RGB to YCbCr

    :param rgb:
    :return ycbcr:
    """

    ycbcr_from_rgb = np.array([[0.256789, 0.504129, 0.097906],
                               [-0.148223, -0.290992, 0.439215],
                               [0.439215, -0.367789, -0.071426]])

    rgb = sud.img_as_float(rgb)
    rgb = np.swapaxes(rgb, 0, 2)
    oldshape = rgb.shape
    rgb = np.reshape(rgb, (3, -1))
    out = np.dot(ycbcr_from_rgb, rgb)
    out.shape = oldshape
    out = np.swapaxes(out, 2, 0)

    out[:, :, 0] = out[:, :, 0] + 16
    out[:, :, 1] = out[:, :, 1] + 128
    out[:, :, 2] = out[:, :, 2] + 128

    return np.ascontiguousarray(out)
 
Zuletzt bearbeitet:
Zurück