web-dev-qa-db-fra.com

Python Image OpenCV en chaîne d'octets pour le transfert json

J'utilise python3 avec numpy, scipy et opencv .

J'essaie de convertir une image lue via OpenCV et l'interface de la caméra connectée en une chaîne binaire, pour l'envoyer dans un objet json via une connexion réseau.

J'ai essayé d'enconder le tableau en jpg et de décoder la chaîne UTF-16, mais je n'obtiens aucun résultat utilisable. par exemple, avec

img = get_image()
converted = cv2.imencode('.jpg', img)[1].tostring()
print(converted)

J'obtiens une chaîne d'octets comme résultat:

b '\ xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01 ....

Mais ces données ne peuvent pas être utilisées comme contenu d'un objet json, car elles contiennent des caractères non valides. Existe-t-il un moyen d'afficher les vrais octets derrière cette chaîne? Je crois que\xff représente la valeur d'octet FF, j'ai donc besoin d'une chaîne comme FFD8FFE0 ... et ainsi de suite, au lieu de\xff\xd8\xff\xe0. Qu'est-ce que je fais mal?

J'ai essayé de l'encoder en UTF-8 et UTF16 après le code ci-dessus, mais je reçois plusieurs erreurs à ce sujet:

utf_string = converted.decode('utf-16-le')

UnicodeDecodeError: le codec 'utf-16-le' ne peut pas décoder les octets en position 0-1: substitut UTF-16 illégal

text = strrrrrr.decode('utf-8')

UnicodeDecodeError: le codec 'utf-8' ne peut pas décoder l'octet 0xff en position 0: octet de début invalide

Je ne peux pas trouver un moyen de faire les choses correctement.

J'ai également essayé de le convertir en une chaîne encodée en base64, comme expliqué dans http://www.programcreek.com/2013/09/convert-image-to-string-in-python/ Mais cela ne fonctionne pas non plus. (Cette solution n'est pas préférée, car elle nécessite que l'image soit écrite temporairement sur le disque, ce qui n'est pas exactement ce dont j'ai besoin. De préférence, l'image ne doit être conservée qu'en mémoire, jamais sur le disque.)

La solution doit contenir un moyen de coder l'image en tant que chaîne conforme à json et également un moyen de la décoder de nouveau en numpy-array, afin qu'elle puisse être réutilisée avec cv2.imshow ().

Merci pour toute aide.

16
Jack O'neill

Vous n'avez pas besoin d'enregistrer le tampon dans un fichier. Le script suivant capture une image à partir d'une webcam, la code en tant qu'image JPG, puis convertit ces données en un codage imprimable en base64:

import cv2
import base64

cap = cv2.VideoCapture(0)
retval, image = cap.read()
retval, buffer = cv2.imencode('.jpg', image)
jpg_as_text = base64.b64encode(buffer)
print(jpg_as_text)
cap.release()

Vous donnant quelque chose commençant comme:

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCg

Cela pourrait être étendu pour montrer comment le reconvertir en binaire, puis écrire les données dans un fichier de test pour montrer que la conversion a réussi:

import cv2
import base64

cap = cv2.VideoCapture(0)
retval, image = cap.read()
cap.release()

# Convert captured image to JPG
retval, buffer = cv2.imencode('.jpg', image)

# Convert to base64 encoding and show start of data
jpg_as_text = base64.b64encode(buffer)
print(jpg_as_text[:80])

# Convert back to binary
jpg_original = base64.b64decode(jpg_as_text)

# Write to a file to show conversion worked
with open('test.jpg', 'wb') as f_output:
    f_output.write(jpg_original)
32
Martin Evans