【问题标题】:OpenCV and Numpy interacting badlyOpenCV 和 Numpy 交互不好
【发布时间】:2013-08-31 17:56:17
【问题描述】:

谁能解释为什么导入 cv 和 numpy 会改变 python 的 struct.unpack 的行为?这是我观察到的:

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 cv
libdc1394 error: Failed to initialize libdc1394
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44

还是可以的,导入cv后

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

导入cv然后numpy后就OK了

现在我重新启动 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

到目前为止一切顺利,但现在我在导入 numpy 之后导入 cv:

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

我已经重复了很多次,包括在多台服务器上,而且总是以同样的方式进行。我也用 struct.unpack 和 struct.pack 试过,也没什么区别。

我无法理解导入 numpy 和 cv 如何对 struct.unpack 的输出产生任何影响(顺便说一句,pack 保持不变)。

我相信“libdc1394”是一个红鲱鱼:ctypes error: libdc1394 error: Failed to initialize libdc1394

有什么想法吗?

tl;dr: 导入 numpy 然后 opencv 会改变 struct.unpack 的行为。

更新:保罗在下面的回答表明这是可重现的。 Seborg 的评论表明这与 python 处理次常态的方式有关,这听起来很合理。我查看了Contexts 但这似乎不是问题,因为导入之后的上下文与之前的上下文相同。

【问题讨论】:

  • 这对您没有帮助,只是为了便于阅读和简化问题,unpack("f",pack("I",31)) 会产生相同的结果吗?
  • @PauloAlmeida:好点。刚刚试了一下——是的,结果一样...我将编辑问题以使其更易于阅读...

标签: python opencv numpy


【解决方案1】:

这不是答案,但对于评论来说太大了。我对这些值进行了一些调整以找到限制。

不加载numpycv

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

加载numpycv后,第一行是一样的,但是第二行:

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

您会注意到第一个结果是lower limit for 32 bit floats。然后我用d尝试了同样的方法。

不加载库:

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

加载库后:

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

现在第一个结果是 64 位浮点精度的下限。

似乎由于某种原因,按此顺序加载 numpycv 库会限制 unpack 使用 32 位和 64 位精度并返回 0 以获得较低的值。

【讨论】:

  • @Ben 没问题 :) 如果您还没有测试 Python 3,请进行测试,因为看起来 CV 会检查它并以不同的方式定义事物。此外,如果您评论 numpy 的 __init__.py 中的每一行,行为就会消失(至少在我的系统上进行了快速测试),但我没有进一步调查。
  • 我认为这与非正常号码处理有关。结构结果似乎已经将次规范向上舍入到最小的合法浮点数/双精度数(这真的应该发生吗?)。不确定 CPU 的四舍五入标志是如何工作的,但我猜 CV 会改变一些标志如何四舍五入。
  • 推理当然是次正规非常慢,所以 CV 会想要避免它们,因为出于其目的它们可能不是必需的。不知道为什么会在整个过程中更改这些标志,但我猜这些标志并不是那么简单。
  • @seberg -- 谢谢 -- 这很有帮助。你能指出我关于非正规的任何有用资源吗?这不是我以前遇到过的……
  • @Ben,我被 'xi' 骗了……不过我猜它可能在某种程度上与非规范化有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
相关资源
最近更新 更多