5

I have a hexadecimal string "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49" to be specific this will contain the data of an image.

I want to convert it to a Numpy array or possibly reconstruct an OpenCV image from the said data.

The width and height will also be supplied so the dimensions of the Numpy array is known.

How can I construct a Numpy array from the above string?

3
  • np.array([int(x, 16) for x in "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49".split("-")]) Commented Apr 1, 2020 at 11:27
  • what are the dimensions for above string? Commented Apr 1, 2020 at 11:31
  • @PatrickArtner it's a function so the dimensions will be supplied during run time. It will construct a 2D array with rows and columns as height and width. Commented Apr 1, 2020 at 11:39

6 Answers 6

3

We could use np.fromiter, and cast the individual strings to hexadecimal, using the base argument in int, and then to integer type using the dtype argument in np.fromiter:

s = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49"

np.fromiter((int(x, 16) for x in s.split('-')), dtype=np.int32)
# array([137,  80,  78,  71,  13,  10,  26,  10,   0,   0,   0,  13,  73])
Sign up to request clarification or add additional context in comments.

Comments

1

You can use list comprehension and the built-in int module to convert from hexadecimal to decimal the splitted string:

import numpy as np

hex_string = '89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49'
np.array([int(x, base=16) for x in hex_string.split('-')])

Comments

0
import numpy as np
arr = np.array([int(x, 16) for x in "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49".split("-")])
print(arr)

Comments

0

You can split the string by dash and convert individual base-16 numbers into int.

>>> import numpy as np
>>> hext_str = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49"
>>> np.array([int(x, 16) for x in hex_str.split("-")])
array([137,  80,  78,  71,  13,  10,  26,  10,   0,   0,   0,  13,  73])

Provided that (n, m) are dimensions of your image you can use on the result the .reshape((n, m)) method of np.array.

Comments

0

If memory efficiency is of concern two digits in a hexadecimal number corresponds to an unsigned 8-bit integer (ie, numbers between 0 and 255).

To return to the original string you can use format(number, '02x') (zero padded 2-length hexadecimal number string)

hex_str = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49"
arr = np.fromiter((int(x, 16) for x in hex_str.split('-')), dtype=np.uint8)
# array([137,  80,  78,  71,  13,  10,  26,  10,   0,   0,   0,  13,  73],
      dtype=uint8)

The array would only take up 13 bytes of space, as opposed to the default array type for integers (np.int64) which would take up 104 bytes.

Once could return it to its original string form in the following way:

hex_str = '-'.join((format(x, '02x') for x in arr)).upper()

Comments

0

It is possible to use bytes.fromhex along with np.frombuffer

import numpy as np

hex_string = "ff01"
arr = np.frombuffer(bytes.fromhex(hex_string), dtype=np.uint8)
# array([255,   1], dtype=uint8)

in your case

import numpy as np

hex_string = "89-50-4E-47-0D-0A-1A-0A-00-00-00-0D-49"
arr = np.frombuffer(bytes.fromhex(hex_string.replace("-", "")), dtype=np.uint8)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.