4 votes

Convertir une chaîne base64 en une image compatible avec OpenCV

J'essaie de convertir une représentation base64 d'un JPEG en une image utilisable avec OpenCV. Le problème est que j'aimerais pouvoir le faire sans avoir à enregistrer physiquement la photo (je voudrais qu'elle reste en mémoire). Existe-t-il un moyen actualisé d'accomplir cette tâche ?

J'utilise python 3.6.2 et OpenCV 3.3.

Voici un exemple partiel du type d'entrée que j'essaie de convertir :

/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAgAAgAAgESAAMAAAA....

J'ai déjà essayé les solutions fournies par ces questions, mais je continue à obtenir la même erreur "bad argument type for built-in operation" :

5voto

andre Points 38

Voici un exemple pour python 3.6 qui utilise imageio au lieu de PIL. Il charge d'abord une image et la convertit en une chaîne b64_string. Cette chaîne peut ensuite être envoyée et l'image reconstruite comme suit :

import base64
import io
import cv2
from imageio import imread
import matplotlib.pyplot as plt

filename = "yourfile.jpg"
with open(filename, "rb") as fid:
    data = fid.read()

b64_bytes = base64.b64encode(data)
b64_string = b64_bytes.decode()

# reconstruct image as an numpy array
img = imread(io.BytesIO(base64.b64decode(b64_string)))

# show image
plt.figure()
plt.imshow(img, cmap="gray")

# finally convert RGB image to BGR for opencv
# and save result
cv2_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.imwrite("reconstructed.jpg", cv2_img)
plt.show()

2voto

Nathan Ortega Points 118

Je me débats avec ce problème depuis un certain temps maintenant et, bien sûr, dès que je poste une question, je trouve la solution.

Pour mon cas particulier, j'avais besoin de convertir la chaîne en une image PIL pour l'utiliser dans une autre fonction avant de la convertir en un tableau numpy pour l'utiliser dans OpenCV. Vous vous demandez peut-être "pourquoi convertir en RVB ?". Je l'ai ajouté parce que lors de la conversion de l'image PIL -> tableau Numpy, OpenCV utilise par défaut le BGR pour ses images.

Quoi qu'il en soit, voici mes deux fonctions d'aide qui ont résolu ma propre question :

import io
import cv2
import base64 
import numpy as np
from PIL import Image

# Take in base64 string and return PIL image
def stringToImage(base64_string):
    imgdata = base64.b64decode(base64_string)
    return Image.open(io.BytesIO(imgdata))

# convert PIL Image to an RGB image( technically a numpy array ) that's compatible with opencv
def toRGB(image):
    return cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB)

1voto

Anthony Anyanwu Points 79

Vous pouvez aussi essayer ceci :

import numpy as np
import cv2

def to_image_string(image_filepath):
    return open(image_filepath, 'rb').read().encode('base64')

def from_base64(base64_data):
    nparr = np.fromstring(base64_data.decode('base64'), np.uint8)
    return cv2.imdecode(nparr, cv2.IMREAD_ANYCOLOR)

Vous pouvez maintenant l'utiliser comme ceci :

filepath = 'myimage.png'
encoded_string = to_image_string(filepath)

le charger avec un cv ouvert comme ceci :

im = from_base64(encoded_string)
cv2.imwrite('myloadedfile.png', im)

0voto

gty3310 Points 31

Voici quelques commandes qui pourraient être utiles

import io
import cv2
import base64 
import numpy as np
from PIL import Image

#convert image to byte type
with open("tes-img/example27.png", "rb") as image_file:
    encoded_string1 = base64.b64encode(image_file.read())

#convert byte to string
encoded_string = encoded_string1.decode("utf-8")

#convert string to byte
base64_image = str.encode(encoded_string)

#save image locally
with open("tes-img/example27_2.png", "wb") as fh:
    fh.write(base64.decodebytes(base64_image))

#convert byte to numpy array for cv2 
img_color = cv2.cvtColor(np.array(Image.open(io.BytesIO(base64.b64decode(base64_image)))), cv2.COLOR_BGR2RGB)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X