2013-08-28 13 views
15

Czy ktoś może wyjaśnić, dlaczego importowanie cv i numpy zmieniłoby zachowanie Pythona w struct.unpack? Oto co obserwować:OpenCV i Numpy źle reagują

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 

ta jest poprawna

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

nadal OK, po zaimportowaniu cv

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

i OK po zaimportowaniu CV, a następnie numpy

Teraz restart 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 

Jak na razie dobrze, ale teraz mogę importować cv po zaimportowaniu numpy:

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

Mam powtórzył to kilka razy, w tym na wielu serwerach, a to zawsze idzie tą samą drogą. Próbowałem również z struct.unpack i struct.pack, co również nie ma znaczenia.

Nie mogę zrozumieć, jak importowanie numpy i cv może mieć jakikolwiek wpływ na wynik struct.unpack (pakiet pozostaje taki sam, btw).

W "libdc1394" Chodzi o to, wierzę, czerwony-śledź: ctypes error: libdc1394 error: Failed to initialize libdc1394

Jakieś pomysły?

tl; dr: importowanie numpy, a następnie opencv zmienia zachowanie struct.unpack.

AKTUALIZACJA: Odpowiedź Paula poniżej pokazuje, że jest to powtarzalne. Komentarz Seborga sugeruje, że ma to coś wspólnego ze sposobem, w jaki pyton radzi sobie z podnormałami, co brzmi wiarygodnie. Spojrzałem na Contexts, ale nie wydawało mi się to problemem, ponieważ kontekst był taki sam po imporcie, jak przed nim.

+2

To ci nie pomoże, ale tylko ze względu na czytelność i uproszczenie problemu, czy "rozpakuj (" f ", paczka (" I ", 31)) da taki sam rezultat? –

+0

@PauloAlmeida: Dobra uwaga. Po prostu wypróbowałem - tak, ten sam wynik ... Zmienię to pytanie, aby ułatwić czytanie ... – Ben

Odpowiedz

5

To nie jest odpowiedź, ale jest za duża na komentarz. Grałem trochę z wartościami, by znaleźć granice.

bez ładowania numpy i cv:

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

Po załadowaniu numpy i cv, pierwsza linia jest taka sama, ale druga:

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

Zauważysz, że pierwszy wynik jest lower limit for 32 bit floats. Następnie próbowałem to samo z d.

bez ładowania bibliotek:

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

I po załadowaniu biblioteki:

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

Teraz pierwszy wynik jest dolna granica dla 64 bitowej precyzji pływaka.Wydaje się, że z jakiegoś powodu ładowanie bibliotek numpy i cv w tej kolejności ogranicza unpack w celu użycia precyzji 32 i 64-bitowej i zwraca 0 w przypadku niższych wartości.

+0

Dzięki Paulo - dobrze widzieć, że to nie tylko ja! :-) – Ben

+0

@Ben Nie ma problemu :) Wykonaj test Pythona 3, jeśli jeszcze tego nie zrobiłeś, ponieważ wygląda na to, że CV go sprawdza i definiuje rzeczy inaczej. Ponadto, jeśli skomentujesz każdą linię w numpy \ _ \ _ init \ _ \ _. Py, zachowanie zniknie (przynajmniej w moim systemie w szybkim teście), ale nie badałem dalej. –

+0

Myślę, że ma to związek z nieprawidłową obsługą numerów. Wynik struktury wydaje się już okrążać subnormal do najmniejszego legalnego float/double (czy tak naprawdę powinno się stać?). Nie wiem, jak zaokrąglać flagi do CPU, ale domyślam się, że CV zmienia niektóre flagi w to, jak sprawy się zaokrąglają. – seberg