Hexstring to img conversion

165 Views Asked by At

I'm using an arduino board to take a picture and it returns a HEX string. I've tried numpy, openCV, binascii and others but i'm not able to convert and save this image in RGB like a picture.

I get an "corrupted image" I can't open on my device but if a throw it in RAW Pixels I can see the image how it should be.

The original size of the picture (seted on arduino board is QVGA 320x240).

The HEX string is HERE. | EDIT: alternative HEX HERE.

And the result (by rawpixels) is this, revealing the data to represent a 320x240 image encoded using RGB565.

This is my actual code that saves a "corrupted file" but opens in rawpixels.net

with open('img.txt') as file:
    data = file.read()

data = bytes.fromhex(data[2:])

with open('image.png', 'wb') as file:
    file.write(data)
2

There are 2 best solutions below

0
Seon On BEST ANSWER

You can decode the image in only a few lines of code using opencv:

import numpy as np
import cv2

with open("hex.txt") as file:
    data = file.read()
    buff = bytes.fromhex(data)

# Convert to 3 channel uint8 numpy array representing the BGR image
img = cv2.cvtColor(
    np.frombuffer(buff, dtype=np.uint8).reshape(240, 320, 2), cv2.COLOR_BGR5652BGR
)
# Save the image to a png file
cv2.imwrite("image.png", img)
6
OM222O On

You can't just save a byte array as a png image, there are header information which are missing from the file. To be honest I'm not too familiar with the PNG format details, but I know you can easily convert the hex values to RGB by doing something like:

import numpy as np

with open("hex.txt",'r') as f:
    hex_str = f.read().strip()
    rgb = np.array([int(hex_str[i:i+2],16) for i in range(0,len(hex_str),2)]) 

however running this code on the hex file you provided results in an array of length 153600 which is not the expected 320*240*3(230400) elements, so for the rest of the answer I define my own HEX string:

0000FF00FF000000FF00FF0000FF00FF000000FF00FF00000000FF00FF000000FF00FF0000FF00FF000000FF00FF0000

This should create a 4x4 Bayer filter. Complete code:

import numpy as np
import matplotlib.pyplot as plt

h=4
w=4

with open("hex.txt",'r') as f:
    hex_str = f.read().strip()
    rgb = np.array([int(hex_str[i:i+2],16) for i in range(0,len(hex_str),2)]).reshape(h,w,3)

plt.figure()
plt.imshow(rgb)
plt.show()

if you want to save the result, you can use plt.imsave() to generate properly formatted PNGs. Edit: Here is the image output generated by the code above: Bayer filter