2016-02-27 15 views
6

Sto lavorando a un programma che rileva i punti di controllo del colore colorato da un'immagine piuttosto grande. L'immagine TIFF è di circa 3 - 4 GB (massimo 35 000 x 33 000 pixel). Sto usando Python 2 e OpenCV per l'elaborazione delle immagini.OpenCV non carica un'immagine grande (~ 4 GB)

import cv2 
img = 'ortho.tif' 
I = cv2.imread(img, cv2.IMREAD_COLOR) 

Questa parte non genera (sempre) un messaggio di errore. Pur mostrando l'immagine fa:

cv2.imshow('image', I) 

Ho anche provato che mostra l'immagine utilizzando matplotlib:

plt.imshow(I[:, :, ::-1]) # Hack to change BGR to RGB 

Ci sono limitazioni sul OpenCV o Python per quanto riguarda immagini di grandi dimensioni? Cosa suggeriresti per far caricare questo iamge?

PS: Il computer su cui faccio questo lavoro è una "workstation" Windows 10 (ha abbastanza potenza per gestire l'immagine).

in anticipo, grazie per il vostro aiuto :)

+0

Che cosa dice il messaggio di errore? – Hexaholic

+0

Per matplotlib plt.imshow (self.image [:,:, :: - 1]) TypeError: oggetto 'NoneType' non ha alcun attributo '\ _ \ _ getitem \ _ \ _' OpenCV sais: Errore OpenCV: asserzione non riuscita (size.width> 0 && size.height> 0) in cv :: imshow, file .. \ .. \ .. \ modules \ highgui \ src \ window.cpp, riga 261 cv2.imshow ('image', self.image) cv2.error: .. \ .. \ .. \ modules \ highgui \ src \ window.cpp: 261: errore: (-215) size.width> 0 && size.height > 0 in function cv :: imshow Essenzialmente, l'immagine ha dimensione 0 x 0 pixel. – cLupus

+0

... e sei sicuro che questa roba (e quando dico questa roba intendo OpenCV e Python) sia stata compilata per 64 bit? – carlosdc

risposta

3

L'attuazione del imread():

Mat imread(const string& filename, int flags) 
{ 
    Mat img; 
    imread_(filename, flags, LOAD_MAT, &img); 
    return img; 
} 

Questo alloca la matrice corrispondente per caricare un'immagine come array contiguo. Quindi questo dipende (almeno in parte) dalle prestazioni dell'hardware: la macchina deve essere in grado di allocare un array di RAM contiguo da 4 GB (se si utilizza una distribuzione Debian, è possibile controllare la dimensione della RAM eseguendo, ad esempio, vmstat -s -SM).

dalla curiosità, ho cercato di ottenere un array contiguo di memoria (uno grande, ma meno di quello dell'immagine 4 GB richiede) utilizzando ascontiguousarray, ma prima di questo, ho già imbattuti in un problema di allocazione di memoria:

>>> img = numpy.zeros(shape=(35000,35000)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
MemoryError 
>>> 

in pratica, anche se avete abbastanza RAM, non è una buona idea di manipolare i pixel di immagine RAM a 4 GB e sarà necessario dividerlo in ogni caso in termini di regions of interests, aree più piccole e può essere channels troppo, a seconda del na delle operazioni che si desidera eseguire sui pixel.

EDIT 1:

Come ho detto nel mio commento qui sotto la tua risposta, se si dispone di 16 GB di RAM e siete in grado di leggere l'immagine con scikit allora non c'è ragione per cui non si può fare la lo stesso con OpenCV.

Si prega di dare una prova:

import numpy as np # Do not forget to import numpy 
import cv2  
img = cv2.imread('ortho.tif') 

Hai dimenticato di importare Numpy nel codice originale e questo è il motivo per cui non è riuscito OpenCV, ovviamente, per caricare l'immagine. Tutte le strutture dell'array OpenCV sono convertite in e dagli array Numpy e l'immagine che leggi sono rappresentate da OpenCV come array nella memoria.

EDIT 2:

OpenCV può trattare imaes quale formato è fino a 10 GB.Ma questo è vero quando arriva la funzione cv2.imwrite(). Per cv2.imread(), tuttavia, la dimensione dell'immagine da leggere è molto più piccola: si tratta di un bug annunciato a settembre 2013 (Issue3258 #1438) che è ancora, AFAIK, non risolto.

+0

Grazie per i suggerimenti. Uno degli obiettivi di questo programma è trovare automaticamente le regioni di interesse. Quindi l'intera immagine deve essere nella memoria, anche se non necessariamente allo stesso tempo. Ho sentito di ['h5py'] (http://www.h5py.org/) che dovrebbe fare qualcosa di simile al tuo suggerimento. Non ho alcuna esperienza con questa libreria però. – cLupus

+0

Quanta RAM ha la tua macchina? @ cLupus –

+0

Il computer ha 16 GB di RAM (DDR3). – cLupus

2

Si scopre che scikit-image è venuto in soccorso, che ho scoperto da here.

Il seguente mi permetta di caricare l'immagine in una sessione di pitone:

import numpy as np 
from skimage.io import imread 

img = imread(path_to_file) 

ci sono voluti circa mezzo minuto, o giù di lì, per caricare.

+0

Viene eseguito senza errori, ma la variabile img è vuota (np.size (img) restituisce l'output 1), mentre imick di scikit fornisce un'immagine con dati (circa 4 miliardi di bit). – cLupus

+1

Immagino che tu abbia fatto la scelta giusta di non affidarti a OpenCV per questa immagine specifica: ho avuto il tempo di guardarmi intorno perché il tuo problema mi intriga. Alla fine ho scoperto che è un ** bug **. Puoi controllare la modifica della mia risposta e ... accettarla perché questa è la spiegazione del problema che hai affrontato. È, infine, un problema della libreria stessa, non dell'hardware o qualcos'altro. –