Расшифровка bytearray в Python3-x - PullRequest
0 голосов
/ 08 июля 2019

Я пытался отправить изображение через сокет, но у меня возникла большая проблема с кодировкой.Я использую сервер с python-2.7 и клиент на python-3.

Я думаю, что проблема в этой функции:

def decode_image(image):
    imageArray = str(bytearray(image))
    nparr = np.fromstring(imageArray, np.uint8)
    nparr.shape = (320, 240, 3)
    nparr = cv2.cvtColor(nparr, cv2.COLOR_BGR2RGB)
    print(nparr)
    return nparr

Если я запускаю код с python2.7 интерпретатор все работает нормально, однако, с интерпретатором Python3 это не так.Я получаю следующую ошибку:

nparr.shape = (320, 240, 3)
ValueError: cannot reshape array of size 597048 into shape (320,240,3)

Это означает, что вместо 320 * 240 * 3 (230400) декодированных элементов есть 597048. Что является эквивалентным способом декодирования байтового массива с python3 вполучить те же результаты, что и для python2.7?

image - это значение bytes.

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Вам не нужно декодировать данные, и при этом вам вообще не нужно использовать bytearray().Numpy может принять значение bytes напрямую, используя numpy.frombuffer().

Ошибка, которую вы видите, вызвана вызовом str():

str(bytearray(image))

, который возвращает Python-представление объекта bytearray():

>>> bytearray(5)
bytearray(b'\x00\x00\x00\x00\x00')
>>> str(bytearray(5))
"bytearray(b'\\x00\\x00\\x00\\x00\\x00')"

str() вернуло строку с теми же данными, что и для первого выражения.Вы передаете префикс bytearray(b', буквенные символы \x и цифры для numpy.Это 14 байтов дополнительных данных, окружающих ваши данные, и сами данные были значительно увеличены, поскольку любой непечатаемый символ был разбит на шестнадцатеричные цифры ASCII плюс обратный слеш и символ x.Вот почему ваши данные не могут быть изменены, ваши двоичные данные имели длину 230400 байт, но были «преобразованы» в строковое представление, которое использует 597048 символов, то есть примерно 2,6 буквы на входной байт.

Если image является значением bytes или объектом, реализующим буферный интерфейс Python, просто передайте это значение непосредственно numpy.frombuffer():

nparr = np.frombuffer(image, np.uint8)

Если image может быть целым числом или итерацией целых чисел в диапазоне (0-255), то просто создайте объект bytes() из этого значения.Поэтому следующая строка будет работать корректно для любого типа image:

nparr = np.frombuffer(bytes(image), np.uint8)

Существуют другие типы, которые bytearray() могли бы принять и по-прежнему работать, но они не будут работать в вашем конкретном кодепример.

1 голос
/ 08 июля 2019

Вы должны decode bytearray;

imageArray = bytearray(image).decode()

Вот пример (изменен с документы ):

>>> np.fromstring(b'1 2'.decode(), dtype=int, sep=' ')
array([1, 2])

С другойрука: str(b'1 2') == "b'1 2'".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...