2015-11-17 9 views
9

Sto lavorando a un'app che esegue il riconoscimento facciale da un flusso di webcam. Ottengo base64 dati codificati URI della tela e voglio usarlo per fare qualcosa di simile:Leggere un'immagine 64 di base dalla memoria utilizzando la libreria python OpenCv

cv2.imshow('image',img) 

I dati URI simile a questa:

data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7 

Così, per chiarezza ho mostrato come appare l'immagine, quindi la stringa base64 non è rotta.

<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7">

Il official doc dice, che imread accetta un percorso di file come argomento. Da this risposta così, se faccio qualcosa di simile:

import base64 
imgdata = base64.b64decode(imgstring) #I use imgdata as this variable itself in references below 
filename = 'some_image.jpg' 
with open(filename, 'wb') as f: 
    f.write(imgdata) 

Le suddette opere frammento di codice e il file immagine viene generato correttamente. Tuttavia, non penso che siano possibili così tante operazioni di file I/O considerando che lo farei per ogni fotogramma del flusso. Voglio essere in grado di leggere l'immagine nella memoria creando direttamente l'oggetto img.

Ho provato due soluzioni che sembrano funzionare per alcune persone.

  1. Utilizzando PIL reference:

    pilImage = Image.open(StringIO(imgdata)) 
    npImage = np.array(pilImage) 
    matImage = cv.fromarray(npImage) 
    

    ottengo cv non definita come ho openCV3 installato che è disponibile per me come modulo cv2. Ho provato img = cv2.imdecode(npImage,0), questo non restituisce nulla.

  2. Ottenere il byte da stringa decodificata e la sua conversione in un array NumPy sorta di

    file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8) 
    img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing 
    

La documentazione in realtà non parlare di quello che le imdecode restituisce la funzione. Tuttavia, dagli errori che ho riscontrato, immagino che si aspetti un numpy array o un scalar come primo argomento. Come faccio a ottenere una maniglia su quella immagine in memoria in modo che io possa fare cv2.imshow('image',img) e tutti i tipi di cose interessanti da allora in poi.

Spero di essere stato in grado di spiegarmi.

+0

Controlla [this] (http://stackoverflow.com/a/33522724/5008845) – Miki

+0

Grazie per la tua risposta rapida @Miki, ma 'np.fromstring' non funziona altrettanto bene. –

+0

E 'imgstring' sarebbe l'URL dell'immagine, giusto? – Divakar

risposta

6

Si può semplicemente utilizzare sia CV2 e cuscino in questo modo:

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

def readb64(base64_string): 
    sbuf = StringIO() 
    sbuf.write(base64.b64decode(base64_string)) 
    pimg = Image.open(sbuf) 
    return cv2.cvtColor(np.array(pimg), cv2.COLOR_RGB2BGR) 

cvimg = readb64('R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7') 
cv2.imshow(cvimg) 
10

Questo ha funzionato per me, e non richiede PIL/cuscino o qualsiasi altre dipendenze (ad eccezione CV2):

import cv2 
import numpy as np 

def data_uri_to_cv2_img(uri): 
    encoded_data = uri.split(',')[1] 
    nparr = np.fromstring(encoded_data.decode('base64'), np.uint8) 
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) 
    return img 

data_uri = "data:image/jpeg;base64,/9j/4AAQ..." 
img = data_uri_to_cv2_img(data_uri) 
cv2.imshow(img) 
+1

Mi hai salvato la vita!Sono (obbligato a) usare Python 2 su AWS e la prima soluzione continuava a darmi un errore come questo: https://stackoverflow.com/questions/28226308/cv2-cvtcolor-error-215-scn-3-scn- 4-in-function-cvcvtcolor – Lewen

+0

Prego! :) – Lior

+1

Oh mio Dio, questa soluzione è pulita! Molte grazie! – hulkinBrain