2013-08-28 21 views
15

Bất cứ ai có thể giải thích lý do tại sao nhập cv và numpy sẽ thay đổi hành vi của struct.unpack python? Đây là những gì tôi quan sát:OpenCV và Numpy tương tác kém

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 

này là đúng

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

Tuy ok, sau khi nhập cv

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

Và OK sau khi nhập cv và sau đó NumPy

Bây giờ tôi khởi động lại 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 

Cho đến nay rất tốt, nhưng bây giờ tôi nhập cv SAU nhập khẩu NumPy:

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

tôi đã lặp đi lặp lại này một số lần, trong đó có trên nhiều máy chủ, và nó luôn luôn đi theo cùng một cách. Tôi cũng đã thử nó với struct.unpack và struct.pack, mà cũng làm cho không có sự khác biệt.

Tôi không thể hiểu cách nhập numpy và cv có thể có bất kỳ tác động nào ở đầu ra của struct.unpack (gói vẫn giữ nguyên, btw).

Các "libdc1394" Vấn đề là, tôi tin rằng, một đỏ cá trích: ctypes error: libdc1394 error: Failed to initialize libdc1394

Bất kỳ ý tưởng?

tl; dr: nhập numpy và sau đó opencv thay đổi hành vi của struct.unpack.

CẬP NHẬT: Câu trả lời của Paulo dưới đây cho thấy rằng điều này có thể lặp lại. Nhận xét của Seborg gợi ý rằng nó liên quan đến cách python xử lý các subnormals, điều này nghe có vẻ hợp lý. Tôi nhìn vào Contexts nhưng điều đó dường như không phải là vấn đề, vì bối cảnh là như nhau sau khi nhập khẩu như trước đó.

+2

Điều này sẽ không giúp ích gì cho bạn, nhưng chỉ vì mục đích dễ đọc và đơn giản hóa vấn đề, 'giải nén ("f", gói ("I", 31)) 'có tạo ra cùng một kết quả không? –

+0

@PauloAlmeida: Tốt. Chỉ cần thử nó - có, cùng một kết quả ... Tôi sẽ chỉnh sửa các câu hỏi để làm cho nó dễ dàng hơn để đọc ... – Ben

Trả lời

5

Đây không phải là câu trả lời nhưng quá lớn đối với nhận xét. Tôi đã chơi với các giá trị một chút để tìm các giới hạn.

Nếu không tải numpycv:

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

Sau khi tải numpycv, dòng đầu tiên là như nhau, nhưng thứ hai:

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

Bạn sẽ nhận thấy rằng kết quả đầu tiên là số lower limit for 32 bit floats. Sau đó tôi đã thử như vậy với d.

Nếu không tải các thư viện:

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

Và sau khi tải các thư viện:

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

Bây giờ kết quả đầu tiên là giới hạn dưới cho độ chính xác phao 64 bit.Có vẻ như vì một lý do nào đó, tải các thư viện numpycv, theo thứ tự đó, hãy hạn chế unpack để sử dụng chính xác 32 và 64 bit và trả về 0 cho các giá trị thấp hơn.

+0

Cảm ơn Paulo - thật tốt khi thấy rằng nó không chỉ là tôi! :-) – Ben

+0

@Ben Không vấn đề gì :) Hãy thử nghiệm Python 3 nếu bạn chưa có, bởi vì có vẻ như CV kiểm tra cho nó và định nghĩa mọi thứ khác nhau. Ngoài ra, nếu bạn nhận xét mọi dòng trong thư mục \ _ \ _ init \ _ \ _ py của numpy sẽ bị loại bỏ (ít nhất là trên hệ thống của tôi trong một thử nghiệm nhanh), nhưng tôi không điều tra thêm. –

+0

Tôi nghĩ điều này liên quan đến việc xử lý số phụ. Kết quả struct dường như đã làm tròn cái bình thường lên cái float/double hợp pháp nhỏ nhất (điều đó thực sự phải xảy ra?). Không chắc chắn làm thế nào làm tròn cờ để CPU làm việc, nhưng tôi đoán CV sẽ thay đổi một số cờ trong cách mọi thứ được làm tròn. – seberg