[Python] Elementweise Matrixoperationen definieren


Jennesta

Erfahrenes Mitglied
#1
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
 

Jennesta

Erfahrenes Mitglied
#2
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:

Neue Beiträge