2016-02-27 3 views
6

Ich arbeite an einem Programm, das farbige Bodenkontrollpunkte von einem ziemlich großen Bild erkennen soll. Das TIFF-Bild ist etwa 3 - 4 GB groß (ca. 35.000 x 33.000 Pixel). Ich benutze Python 2 und OpenCV, um die Bildverarbeitung zu machen.OpenCV wird kein großes Bild laden (~ 4GB)

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

Dieser Teil erzeugt (immer) keine Fehlermeldung. Während das Bild zeigt tut:

cv2.imshow('image', I) 

Ich habe versucht, auch mit matplotlib das Bild zeigt:

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

Gibt es eine Beschränkung auf OpenCV oder Python in Bezug auf große Bilder? Was würden Sie vorschlagen, um dieses iamge geladen zu bekommen?

PS: Der Computer, an dem ich arbeite, ist ein Windows 10 "Workstation" (es hat genug Pferdestärken, um mit dem Bild umzugehen).

Vorab Danke für Ihre Hilfe :)

+0

Was sagt die Fehlermeldung? – Hexaholic

+0

Für matplotlib plt.imshow (self.image [:,:, :: - 1]) Typeerror: 'NoneType' Objekt hat kein Attribut '\ _ \ _ GetItem \ _ \ _' OpenCV sais: OpenCV Fehler: Assertion fehlgeschlagen (size.width> 0 && size.height> 0) in cv :: imshow, Datei .. \ .. \ .. \ modules \ highgui \ src \ window.cpp, Zeile 261 cv2.imshow ('image', self.image) cv2.error: .. \ .. \ .. \ Module \ highgui \ src \ window.cpp: 261: Fehler: (-215) size.width> 0 && size.height > 0 in der Funktion cv :: imshow Im Wesentlichen ist es so, dass das Bild die Größe 0 x 0 Pixel hat. – cLupus

+0

... und Sie sind sicher, dass dieses Zeug (und wenn ich das sage, ich meine OpenCV und Python) für 64 Bit kompiliert wurde? – carlosdc

Antwort

3

Die Umsetzung imread():

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

Dies ordnet die Matrix ein Bild als eine zusammenhängende Anordnung laden, entspricht. Dies hängt (zumindest teilweise) von der Leistung Ihrer Hardware ab: Ihr Computer muss 4 GB zusammenhängendes RAM-Array zuweisen können (wenn Sie sich auf einer Debian-Distribution befinden, können Sie Ihre RAM-Größe überprüfen, indem Sie beispielsweise vmstat -s -SM ausführen).

Durch Neugier habe ich versucht, einen zusammenhängenden Speicherarray (ein großen, aber weniger als die Ihr 4 GB Bild erfordert) zu erhalten mit ascontiguousarray, aber vorher, stolperte ich bereits auf einer Speicherzuordnungsproblem:

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

in der Praxis, auch wenn Sie genug RAM haben, ist es keine gute Idee, die Pixel eines 4 GB RAM Bild zu manipulieren, und Sie müssen es trotzdem in Bezug auf regions of interests, kleinere Bereiche aufzuteilen und kann channels auch sein, abhängig von der na der Operationen, die Sie für die Pixel ausführen möchten.

EDIT 1:

Wie gesagt ich in meinem Kommentar unten Ihre Antwort, wenn Sie 16 GB RAM haben, und Sie sind in der Lage, das Bild mit scikit dann zu lesen, gibt es keinen Grund ist, dass Sie das nicht tun können, Gleiches gilt für OpenCV.

Bitte geben diesem einen Versuch:

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

Sie haben vergessen Numpy in Ihrem ursprünglichen Code zu importieren, und deshalb OpenCV offensichtlich das Bild konnte nicht geladen werden. Alle OpenCV-Array-Strukturen werden in Numpy-Arrays konvertiert, und das von Ihnen gelesene Bild wird von OpenCV als Arrays im Speicher dargestellt.

EDIT 2:

OpenCV mit imaes der Größe bis zu 10 GB umgehen kann.Aber das ist wahr, wenn es cv2.imwrite() Funktion kommt. Für cv2.imread() ist die Größe des zu lesenden Bildes jedoch viel kleiner: Das ist ein Fehler, der im September 2013 angekündigt wurde (Issue3258 #1438), der immer noch, AFAIK, nicht behoben ist.

+0

Danke für die Tipps. Eines der Ziele dieses Programms ist es, die Regionen von Interesse automatisch zu finden. So muss das gesamte Bild im Gedächtnis sein, aber nicht gleichzeitig. Ich habe von ['h5py'] (http://www.h5py.org/) gehört, das etwas Ähnliches wie Ihr Vorschlag machen soll. Ich habe jedoch keine Erfahrung mit dieser Bibliothek. – cLupus

+0

Wie viel RAM hat Ihre Maschine? @cLupus –

+0

Der Computer verfügt über 16 GB RAM (DDR3). – cLupus

2

Es stellt sich heraus, dass scikit-image zur Rettung kam, die ich aus here herausfand.

Die folgende lassen Sie mich das Bild in eine Python-Sitzung laden:

import numpy as np 
from skimage.io import imread 

img = imread(path_to_file) 

Es dauerte etwa eine halbe Minute oder so, zu laden.

+0

Es läuft ohne Fehler, aber die Variable img ist leer (np.size (img) gibt Ausgabe 1), während scikit's liest, gibt ein Bild mit Daten (etwa 4 Milliarden Bits). – cLupus

+1

Ich schätze, du hast die richtige Entscheidung getroffen, dich nicht auf OpenCV für dieses spezielle Bild zu verlassen: Ich habe mir Zeit genommen, mich umzusehen, weil dein Problem mich intrigiert. Endlich fand ich, dass das ein ** Bug ** ist. Sie können die Bearbeitung meiner Antwort überprüfen und ... akzeptieren, denn das ist die Erklärung für das Problem, dem Sie gegenüberstanden. Es ist schließlich ein Problem der Bibliothek selbst, nicht die Hardware oder etwas anderes. –