2013-08-28 16 views
15

Qualcuno può spiegare perché l'importazione di cv e numpy cambierebbe il comportamento di struct.unpack di python? Ecco quello che osservo:OpenCV e Numpy interagiscono male

Python 2.7.3 (default, Aug 1 2012, 05:14:39) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from struct import pack, unpack 
>>> unpack("f",pack("I",31))[0] 
4.344025239406933e-44 

Questo è corretto

>>> import cv 
libdc1394 error: Failed to initialize libdc1394 
>>> unpack("f",pack("I",31))[0] 
4.344025239406933e-44 

ancora ok, dopo aver importato cv

>>> import numpy 
>>> unpack("f",pack("I",31))[0] 
4.344025239406933e-44 

E OK dopo l'importazione cv e poi NumPy

Ora ricomincio python:

Python 2.7.3 (default, Aug 1 2012, 05:14:39) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from struct import pack, unpack 
>>> unpack("f",pack("I",31))[0] 
4.344025239406933e-44 
>>> import numpy 
>>> unpack("f",pack("I",31))[0] 
4.344025239406933e-44 

Fin qui tutto bene, ma ora importare cv dopo l'importazione NumPy:

>>> import cv 
libdc1394 error: Failed to initialize libdc1394 
>>> unpack("f",pack("I",31))[0] 
0.0 

Ho ripetuto questo un certo numero di volte, anche su più server, e va sempre allo stesso modo. Ho anche provato con struct.unpack e struct.pack, che non fa differenza.

Non riesco a capire come l'importazione di numpy e cv possa avere alcun impatto sull'output di struct.unpack (il pacchetto rimane lo stesso, btw).

La cosa "libdc1394" è, credo, un rosso-aringhe: ctypes error: libdc1394 error: Failed to initialize libdc1394

Tutte le idee?

tl; dr: importazione numpy e quindi opencv modifica il comportamento di struct.unpack.

AGGIORNAMENTO: la risposta di Paolo qui sotto mostra che questo è riproducibile. Il commento di Seborg suggerisce che è qualcosa a che fare con il modo in cui Python gestisce i subnormali, il che sembra plausibile. Ho esaminato Contexts ma questo non sembrava essere il problema, poiché il contesto era lo stesso dopo le importazioni come era stato prima di loro.

+2

Questo non ti aiuterà, ma solo per motivi di leggibilità e di semplificazione del problema, 'unpack (" f ", pack (" I ", 31))' produce lo stesso risultato? –

+0

@PauloAlmeida: buon punto. Ho appena provato - si, lo stesso risultato ... Modificherò la domanda per rendere più facile la lettura ... – Ben

risposta

5

Questa non è una risposta, ma è troppo grande per un commento. Ho giocato un po 'con i valori per trovare i limiti.

senza caricare numpy e cv:

>>> unpack("f", pack("i", 8388608)) 
(1.1754943508222875e-38,) 
>>> unpack("f", pack("i", 8388607)) 
(1.1754942106924411e-38,) 

Dopo aver caricato numpy e cv, la prima linea è la stessa, ma la seconda:

>>> unpack("f", pack("i", 8388607)) 
(0.0,) 

Si noterà che il primo risultato è il lower limit for 32 bit floats. Ho quindi provato lo stesso con d.

Senza caricare le librerie:

>>> unpack("d", pack("xi", 1048576)) 
(2.2250738585072014e-308,) 
>>> unpack("d", pack("xi", 1048575)) 
(2.2250717365114104e-308,) 

E dopo il caricamento delle librerie:

>>> unpack("d",pack("xi", 1048575)) 
(0.0,) 

Ora il primo risultato è il limite inferiore per la precisione float a 64 bit.

Sembra che per qualche ragione, il caricamento delle librerie numpy e cv, in questo ordine, costringe unpack usare 32 e 64 bit di precisione e restituire 0 per valori inferiori.

+0

Grazie Paulo - è bello vedere che non sono solo io! :-) – Ben

+0

@ Ben Nessun problema :) Prova Python 3 se non lo hai ancora fatto, perché sembra che CV lo controlli e definisca le cose in modo diverso. Inoltre, se si commenta ogni riga di numpy \ _ \ _ init \ _ \ _. Py, il comportamento scompare (almeno sul mio sistema in un test rapido che ho fatto), ma non ho indagato ulteriormente. –

+0

Penso che questo abbia a che fare con la gestione del numero subnormale. Il risultato di struct sembra già aggirare il subnormal fino al più piccolo float/double legale (è ciò che dovrebbe accadere realmente?). Non sono sicuro di come i flag di arrotondamento alla CPU funzionino, ma suppongo che CV cambi alcune bandiere nel modo in cui le cose si arrotondano. – seberg