Быстрый способ конвертировать строку в numpy ndarray

В настоящее время я делаю программу python для преобразования изображения в шестнадцатеричную строку и наоборот. Мне нужны две функции: одна, которая берет изображение и возвращает шестнадцатеричную строку, соответствующую значениям RGB каждого пикселя, и другая функция, которая принимает шестнадцатеричную строку, два целых числа и создает видимое изображение этого размера, соответствующего этой шестнадцатеричной строке. .

В настоящее время я использую imageio, чтобы получить матрицу RGB из изображения, а затем преобразовать ее в шестнадцатеричный формат. Это быстро, около 2,5 секунд для изображения размером 442 КБ с разрешением 918 x 575 пикселей.

Чтобы получить изображение из строки, я конвертирую его в матрицу шестнадцатеричных значений, а затем конвертирую в 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)

Каков формат вашего шестнадцатеричного изображения? это необработанные значения пикселей, то есть то, что вы получите от своей функции ImageToBytes?

FirefoxMetzger 08.12.2022 12:28
Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
0
1
74
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Удалить неправильный отступ в этой строке:

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)

Простого исправления отступа было достаточно, чтобы значительно сократить время. Не знаю, о чем я думал, когда делал это. И эта модификация сокращает время до половины. Большое спасибо! Простите, что так много спрашиваю, но знаете ли вы, есть ли способ уменьшить время первой части (ImageToBytes) до менее 2,5 секунд?

Rararat 21.11.2022 02:10

Если ваша длина в байтах соответствует требованиям, следующий код должен быть самым быстрым методом, он в 500 000 раз быстрее, чем понимание списка на изображении 918 * 575 (игнорируйте время imwrite):

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

Простите, а что вы подразумеваете под "соответствующим"? Это работает только с байтовыми строками определенной длины?

Rararat 21.11.2022 07:02

@Rararat Длина байтов равна originalRows * originalColumns * 3.

Mechanic Pig 21.11.2022 07:04

Другие вопросы по теме

Как скрыть легенду хороплет python folium
Как создать таймер обратного отсчета, который продолжает отсчет после однократного нажатия кнопки, обновляя текст на холсте tkinter
BeautifulSoup - Соберите продукт и варианты продукта и экспортируйте его в csv
Почему выражения генератора имеют меньшую глубину рекурсии по сравнению с объектами карты в python 3, несмотря на то, что они считаются более питоническими?
Есть ли способ удалить первичный ключ из результатов запроса SQLAlchemy?
Прочитайте содержимое текстового файла в фрейм данных pandas из zip-папки
Создание простого взломщика паролей с использованием массивов numpy
Какой тип данных используется set в python внутри?
Извлечение узлов из json на основе пользовательского ввода с сохранением части объекта более высокого уровня.
Как удалить все элементы, которые находятся между двумя дубликатами в списке