繁体   English   中英

将字符串转换为 numpy ndarray 的快速方法

[英]Fast way to convert string to numpy ndarray

我目前正在做一个 python 程序,将图像转换为十六进制字符串,反之亦然。 我需要两个函数,一个获取图像并返回对应于每个像素的 RGB 值的十六进制字符串,另一个 function 获取一个十六进制字符串,两个整数,并生成与该十六进制字符串对应的大小的可见图像.

我目前使用 imageio 从图像中获取 RGB 矩阵,然后将其转换为十六进制。 这个速度很快,对于 918 x 575 像素的 442KB 图像大约需要 2.5 秒。

为了从字符串中获取图像,我将其转换为十六进制值矩阵,然后将其转换为 RGB 以使用 imageio 创建图像。 这是出现问题的地方,因为对与相同 918 x 575 图像对应的字符串执行处理需要 36 秒。

我怎样才能让它更快?

这是代码:

def rgb2hex(rgb):

    """
    convert a list or tuple of RGB values
    to a string in hex
    """

    r,g,b = rgb
    return '{:02x}{:02x}{:02x}'.format(r, g, b)


def arrayToString(array):
    """
    convert an array to a string
    """

    string = ""
    for element in array:
        string += str(element)

    return string


def sliceStr(string,sliceLenght):
    """
    slice a string in chunks of sliceLenght lenght
    """

    string = str(string)
    array = np.array([string[i:i+sliceLenght] for i in range(0,len(string),sliceLenght)])
    return array



def hexToRGB(hexadecimal):
    """
    convert a hex string to an array of RGB values
    """
    h = hexadecimal.lstrip('#')
    if len(h)!=6:
        return
    return [int(h[i:i+2], 16) for i in (0, 2, 4)]

def ImageToBytes(image):
    """
    Image to convert from image to bytes
    """
    dataToEncrypt =imageio.imread(image)

    if dataToEncrypt.shape[2] ==4:
        dataToEncrypt = np.delete(dataToEncrypt,3,2)

    originalRows, originalColumns,_ = dataToEncrypt.shape


    #converting rgb to hex
    hexVal = np.apply_along_axis(rgb2hex, 2, dataToEncrypt)
    hexVal = np.apply_along_axis(arrayToString, 1, hexVal)
    hexVal = str(np.apply_along_axis(arrayToString, 0, hexVal))

    byteImage = bytes.fromhex(hexVal)

    return (byteImage, [originalRows,originalColumns])

def BytesToImage(byteToConvert,originalRows,originalColumns,name):

    """
    Convert from Bytes to Image
    """
    Data = byteToConvert.hex()


    stepOne = sliceStr(Data,originalColumns*6)

    stepTwo = []

    for i in stepOne:
        step = sliceStr(i,6)

        #Add lost pixels
        while len(step) != originalColumns:
            step = np.append(step,"ffffff")
        stepTwo.append(step)


    stepThree = []
    for i in stepTwo:
        d = []
        for j in i:
            d.append(hexToRGB(j))

        if len(stepThree) < originalRows:
            stepThree.append(d)

        Img = np.asarray(stepThree)


    imageio.imwrite(name,Img)

删除此行中不正确的缩进:

Img = np.asarray(stepThree)

它在 for 循环内,不应该

此外,代码正在进行从字节到字符串到 int 的必要转换,而不是直接将字节转换为 int,请考虑更改为以下更短更快的代码

def BytesToImage2(byteToConvert,originalRows,originalColumns,name):

    """
    Convert from Bytes to Image
    """
    ia=[]
    for i in range(0,len(byteToConvert),originalColumns*3):
        row=[[y for y in x] for x in [byteToConvert[j:j+3] for j in range(i,i+originalColumns*3,3)]]
        ia.append(row)
             
    Img = np.asarray(ia)
    imageio.imwrite(name,Img)

如果你的字节长度是合规的,下面的代码应该是最快的方法,它比 918 * 575 图像上的列表理解快 500k 倍(忽略imwrite的时间):

def BytesToImage(byteToConvert, originalRows, originalColumns, name):
    img = np.frombuffer(byteToConvert, np.uint8).reshape(originalRows, originalColumns, 3)
    imageio.imwrite(name, img)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM