【问题标题】:reading middlebury 'flow' files with python (bytes array & numpy)用python(字节数组和numpy)读取middlebury'flow'文件
【发布时间】:2015-03-16 18:48:48
【问题描述】:

我正在尝试将 .flo 文件读取为 numpy 2Channels 图像。

格式描述如下:

".flo" file format used for optical flow evaluation

Stores 2-band float image for horizontal (u) and vertical (v) flow components.
Floats are stored in little-endian order.
A flow value is considered "unknown" if either |u| or |v| is greater than 1e9.

bytes  contents

0-3     tag: "PIEH" in ASCII, which in little endian happens to be the float 202021.25
        (just a sanity check that floats are represented correctly)
4-7     width as an integer
8-11    height as an integer
12-end  data (width*height*2*4 bytes total)
        the float values for u and v, interleaved, in row order, i.e.,
        u[row0,col0], v[row0,col0], u[row0,col1], v[row0,col1], ...

(摘自此readme

这是我的代码,但我有点卡住了,我不知道如何将文件读取为 2 Channels numpy 2D 数组。

import numpy as np
import os

# test.flo, 512*512 optical flow file

f = open('test.flo', 'rb')
f.seek(11, os.SEEK_SET)  # skip header bytes


data_array = np.fromfile(f, np.float16)
data_2D = np.resize(data_array, (512, 512))

也许有人知道怎么做?

【问题讨论】:

  • 好吧,格式在您链接的 README 中进行了描述,用于读取 .flo 文件的示例 C++ 代码是 here - 有关详细信息,请参阅 ReadFlowFile() 函数(第 46 行)。对于有一点 C/C++ 知识的人来说翻译应该不会太难(不幸的是我不是……)
  • 另外,如果你下载flow-code-matlab.zip,你可以在Matlab中找到readFlowFile.m,如果你更熟练的话。
  • 嗨,感谢 cmets,我对 C++ 或数学实验室不是很流利,但我会尝试。实际上我正在尝试找到一个 numpy 解决方案来避免 C++ 风格的循环,这在 python 中会很慢。
  • 跳出来的两件事:1)您正在指定 np.float16。从自述文件和 C 源代码中,有两个 4 字节(32 位)浮点数。尝试 np.float32。 2)您正在寻找偏移量 11 .. 数据开始时不应该是偏移量 12 吗?

标签: python c++ image numpy file-format


【解决方案1】:

试试这个。到目前为止,我已经在一个 .flo 文件上对其进行了测试。

import numpy as np
import sys

if __name__ == '__main__':
    if len(sys.argv) <= 1:
        print('Specify a .flo file on the command line.')
    else:
        with open(sys.argv[1], 'rb') as f:
            magic, = np.fromfile(f, np.float32, count=1)
            if 202021.25 != magic:
                print('Magic number incorrect. Invalid .flo file')
            else:
                w, h = np.fromfile(f, np.int32, count=2)
                print(f'Reading {w} x {h} flo file')
                data = np.fromfile(f, np.float32, count=2*w*h)
                # Reshape data into 3D array (columns, rows, bands)
                data2D = np.resize(data, (w, h, 2))
                print(data2D)

【讨论】:

  • 谢谢!它运行良好。我以一个可行的解决方案结束,但它很脏;指定 w & h,读取整个文件并删除标题......你的方式真的很聪明。再次感谢:)
  • 如果你想用 Matplotlib 之类的东西查看它,请将 wh 翻转到 (w, h, 2)->(h, w 2)
  • 能否请您为此提供 C++ 代码。我想比较两个 fol 文件(光流 Sintel 数据集)并获得算法评估。我想获得“EPE 所有 EPE 匹配 EPE 不匹配 d0-10 d10-60 d60-140 s0-10 s10-40 s40+”结果来自“sintel.is.tue.mpg.de/results”数据集的光流。我使用了 OpenCV 3、VC++ 2013、Win 7 64 位。我需要得到这个结果的示例代码。
  • 如何发布一个新问题,并链接回这个问题。发布您到目前为止的代码。
  • 如果这里有什么问题,我会有点困惑,因为您正在阅读相同的宽度和高度数字w = np.fromfile(f, np.int32, count=1) ; h = np.fromfile(f, np.int32, count=1)
【解决方案2】:

bsa 的答案不适用于 python 3.5 及以后的版本。如下所示的小修改,例如np.fromfile(f, np.int32, count=1)[0], 将。

import numpy as np
import os
import sys

# WARNING: this will work on little-endian architectures (eg Intel x86) only!
if '__main__' == __name__:
    if len(sys.argv) > 1:
        with open(sys.argv[1], 'rb') as f:
            magic = np.fromfile(f, np.float32, count=1)
            if 202021.25 != magic:
                print('Magic number incorrect. Invalid .flo file')
            else:
                w = np.fromfile(f, np.int32, count=1)[0]
                h = np.fromfile(f, np.int32, count=1)[0]
                print('Reading %d x %d flo file' % (w, h))
                data = np.fromfile(f, np.float32, count=2*w*h)
                # Reshape data into 3D array (columns, rows, bands)
                data2D = np.resize(data, (h, w, 2))
    else:
        print('Specify a .flo file on the command line.')

【讨论】:

  • 我不认为您的代码将在 Python 3.5 中运行,因为您仍在使用 Python 2 样式 print 'blah' 而不是 print('blah')..
  • 我已经更新了我的代码,使其适用于 Python 3.6 或更高版本。
猜你喜欢
  • 1970-01-01
  • 2017-09-23
  • 2022-11-12
  • 2013-01-13
  • 2013-07-31
  • 2017-06-16
  • 2023-03-08
  • 2018-12-25
  • 1970-01-01
相关资源
最近更新 更多