【问题标题】:Saving a numpy homographic ndarray to file将 numpy 单应性 ndarray 保存到文件
【发布时间】:2020-06-11 04:54:07
【问题描述】:

我正在尝试将一个 numpy ndarray 单应表保存到文件中(如果需要,以后可以使用):

h.tofile("h.h", sep=",", format="%s")

但是当我稍后加载它并尝试在我的计算中使用它时,使用:

h = np.fromfile('h.h')

我收到以下错误:

OpenCV Error: Assertion failed (scn + 1 == m.cols) in perspectiveTransform, file /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/matmul.cpp, line 2268
Traceback (most recent call last):
  File "...camera_to_point.py", line 166, in draw_circle2
    pointOut = cv2.perspectiveTransform(a, h)
cv2.error: /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/core/src/matmul.cpp:2268: error: (-215) scn + 1 == m.cols in function perspectiveTransform

有趣的是,当我在保存到文件之前和从文件中检索它之后检查单应矩阵时,我得到:

保存前:

h
array([[ 1.86326937e-02, -1.16700086e-02,  2.66963340e+00],
       [-7.51402803e-03, -3.88364336e-02,  1.69502899e+01],
       [-1.05249671e-03,  1.47791921e-02,  1.00000000e+00]])
[0:3] : [array([ 0.01863269, ...6696334 ]), array([-7.51402803e-...2899e+01]), array([-0.0010525 , ...        ])]
dtype: dtype('float64')
max: 16.950289865517334
min: -0.038836433627212195
shape: (3, 3)
size: 9
__internals__: {'T': array([[ 1.86326937e...000e+00]]), 'base': None, 'ctypes': <numpy.core._interna...ff8179b90>, 'data': <read-write buffer f...ff81797f0>, 'dtype': dtype('float64'), 'flags':   C_CONTIGUOUS : Tru...PY : False, 'flat': <numpy.flatiter obje...0x2f69850>, 'imag': array([[0., 0., 0.],... 0., 0.]]), 'itemsize': 8, 'nbytes': 72, 'ndim': 2, 'real': array([[ 1.86326937e...000e+00]]), 'shape': (3, 3), 'size': 9, ...}

检索后:

h
array([7.12605079e-67, 1.18069470e-95, 9.95130728e-43, 9.95309333e-43,
       5.40222957e-62, 4.32553942e-91, 2.74137239e-57, 3.06246782e-57,
       7.11172728e-38, 8.16641713e-43, 1.83288526e-76, 9.92883300e-96,
       1.69053846e-52, 9.34287548e-67, 9.05446937e-43, 7.11877246e-67])
[0:16] : [7.126050789796848e-67, 1.1806946993563433e-95, 9.951307279141174e-43, 9.95309332763986e-43, 5.402229572720159e-62, 4.325539416797926e-91, 2.741372385066056e-57, 3.0624678193742925e-57, 7.111727282221548e-38, 8.16641712557458e-43, 1.8328852622133153e-76, 9.928833002794128e-96, 1.690538456980108e-52, 9.342875479816443e-67, ...]
dtype: dtype('float64')
max: 7.111727282221548e-38
min: 9.928833002794128e-96
shape: (16,)
size: 16
__internals__: {'T': array([7.12605079e-6...7246e-67]), 'base': None, 'ctypes': <numpy.core._interna...ff8179790>, 'data': <read-write buffer f...ff8179470>, 'dtype': dtype('float64'), 'flags':   C_CONTIGUOUS : Tru...PY : False, 'flat': <numpy.flatiter obje...0x2f68e00>, 'imag': array([0., 0., 0., 0..., 0., 0.]), 'itemsize': 8, 'nbytes': 128, 'ndim': 1, 'real': array([7.12605079e-6...7246e-67]), 'shape': (16,), 'size': 16, ...}

这显示了两个不同的矩阵。

那么,如何将 numpy ndmatrix 保存到文件并成功检索?

我在 python2.7 中使用 opencv2

【问题讨论】:

  • 您是否尝试过传递相同的参数 h = np.fromfile('h.h', sep=",", dtype="str") ?
  • 是的,结果(当试图计算指向目标平面的点时)是上面列出的错误。显然由于某种原因,h 矩阵在保存到文件时会失真。至少这是我在检查 h 之后,在保存到文件之前和之后可以验证的。

标签: python numpy opencv multidimensional-array save


【解决方案1】:

h.tofile("h.h", sep=",", format="%s") 会存储一个包含所有数字的文本文件,用逗号分隔,但会丢失数组维度的信息。
h = np.fromfile('h.h') 会生成您的输出文件。如果您改用
h = np.fromfile('h.h', sep=","),然后像
h.resize((3, 3)) 一样调整 h 的大小 你会得到想要的结果。

如果使用二进制文件格式,可以检索到数组信息。

np.arrays 可以使用 pickle 库以二进制文件格式存储:
脚本在 python 2.7 和 3.8 中运行

from pickle import dump, load
from numpy import array

def save_h():

    h = array([[1.86326937e-02, -1.16700086e-02,  2.66963340e+00],
           [-7.51402803e-03, -3.88364336e-02,  1.69502899e+01],
           [-1.05249671e-03,  1.47791921e-02,  1.00000000e+00]])

    with open("save.h", "wb") as f:
        dump(h, f)
    with open("save.h", "rb") as f:
        h1 = load(f)
    return h, h1

if __name__ == "__main__":
    stored, loaded = save_h()
    print(stored)
    print(loaded)

输出:

[[ 1.86326937e-02 -1.16700086e-02  2.66963340e+00]
 [-7.51402803e-03 -3.88364336e-02  1.69502899e+01]
 [-1.05249671e-03  1.47791921e-02  1.00000000e+00]]
[[ 1.86326937e-02 -1.16700086e-02  2.66963340e+00]
 [-7.51402803e-03 -3.88364336e-02  1.69502899e+01]
 [-1.05249671e-03  1.47791921e-02  1.00000000e+00]]

【讨论】:

  • 非常感谢您的回复。我想到的一个问题是,为什么 python 允许使用一个函数来保存数组(正如在 docs.scipy.org/doc/numpy/reference/generated/… 中明确指出的那样,这不起作用?
  • 在链接的注释中有一个提示:“这是一个快速存储数组数据的便利功能。有关字节序和精度的信息丢失了......”。使用 h.tofile("hh", sep=",", format="%s") 会存储一个包含所有数字的文本文件,以逗号分隔,但会丢失数组维度的信息。跨度>
  • 但即使是数字也完全错误。不仅是维度。无论如何,再次感谢。
  • 数字错误,因为您的 np.fromfile 命令中的sep="," 丢失。该命令可能会以“C”顺序分隔数字(如您发布的链接中所述)并根据这些分隔规则创建“新”数字。第一个数字可能是括号的二进制翻译。如果您包含sep=",",那么您将获得一个具有正确值的一维数组,可以使用h.resize((3, 3)) 将其传输到原始数组中(请参阅我编辑的答案的顶部)。
猜你喜欢
  • 2017-07-13
  • 2018-07-15
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
相关资源
最近更新 更多