如何将 .mat 二进制格式转换为 2D numpy 数组?
How to convert .mat binary format to 2D numpy array?
我正在将 hand_dataset 注释转换为可以在 YOLOv3 中使用的格式。注释采用 .mat 二进制格式,我想将其提取、转换和重组为 .csv。
我试过mat = scipy.io.loadmat(file)
,但提取数据的格式很奇怪。
mat = scipy.io.loadmat(file)
bboxes = np.transpose(mat['boxes'])
给出输出:
[[array([[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])]
其中形状是 (2,1)
和 numpy.array 类型。
我能够像这样提取遍历整个数据集注释的点:
points = np.array([point[0] for point in bboxes[0][0][0][0]])
层次结构是:
print(bboxes[0])
print(bboxes[0][0])
print(bboxes[0][0][0])
print(bboxes[0][0][0][0])
print(bboxes[0][0][0][0][0])
print(bboxes[0][0][0][0][0][0][1])
有没有"nicer"方法提取需要的点数?
给定打印的输出:
[[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]]
[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]
(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))
[[488.42954942 345.62261032]]
345.6226103157693
如有任何帮助,我们将不胜感激!谢谢!
这应该会给出更好的结果:
np.concatenate(bboxes[0][0].tolist()).squeeze()
我想我可以用
重新创建你的数组
In [38]: array=np.array
In [43]: data = np.zeros((1,1),object)
In [44]: data[0,0] = array([[(array([[488.42954942, 345.62261032]]), array([[461
...: .57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), arra
...: y([[492.42954942, 384.62261032]]))]],
...: dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
In [45]: data
Out[45]:
array([[array([[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])]],
dtype=object)
这是一个 (1,1) 对象数据类型数组,其中包含另一个数组。该数组也是 (1,1) 形状,但具有复合数据类型(structured
数组)。
In [51]: data.shape, data.dtype
Out[51]: ((1, 1), dtype('O'))
在 MATLAB 中,一切都是二维的。 loadmat
有一个 squeeze
参数可以告诉它删除不必要的尺寸。如果没有它,我们会得到很多 (1,1) 形状的数组。
像 cell
和 struct
这样的 MATLAB 对象被 return 编辑为某种类型的对象 dtype 数组。常规 MATLAB 矩阵是 returned 数字 numpy
数组。
我们可以使用二维索引从 data
中提取一个元素(比 data[0][0]
更惯用):
In [52]: data1 = data[0,0]
In [53]: data1.shape, data1.dtype
Out[53]: ((1, 1), dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')]))
item()
也可以从数组中删除一项:
In [54]: data.item().dtype
Out[54]: dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
在此级别,数组是一个结构化数组,具有 4 个(命名的)字段,每个对象 dtype。
字段(通常)按名称索引。但是作为对象数据类型,我们还有另一层:
In [74]: data1['a']
Out[74]: array([[array([[488.42954942, 345.62261032]])]], dtype=object)
In [75]: data1['a'].item()
Out[75]: array([[488.42954942, 345.62261032]])
In [76]: data1['a'].item().squeeze()
Out[76]: array([488.42954942, 345.62261032])
@aparpara 使用 tolist()
的想法可能是提取那些嵌套对象字段的最干净的方法:
In [85]: data1.tolist()
Out[85]:
[[(array([[488.42954942, 345.62261032]]),
array([[461.57045058, 348.37738968]]),
array([[465.57045058, 387.37738968]]),
array([[492.42954942, 384.62261032]]))]]
在结构化数组上 tolist()
创建一个元组列表(或嵌套列表),每个 'record' 个数组一个元组。
然后我们可以使用np.array
或concatenate
将数组合并为一个,并使用squeeze
删除多余的维度:
In [87]: np.array(data1.tolist()).squeeze()
Out[87]:
array([[488.42954942, 345.62261032],
[461.57045058, 348.37738968],
[465.57045058, 387.37738968],
[492.42954942, 384.62261032]])
MATLAB 源代码不是简单的二维数字矩阵。因此,翻译成另一种语言也不是一件容易的事。一些loadmat
参数可以简化return结构。除此之外,我们必须通过层层深入,使用 item
或 [0,0]
类型的索引。
我正在将 hand_dataset 注释转换为可以在 YOLOv3 中使用的格式。注释采用 .mat 二进制格式,我想将其提取、转换和重组为 .csv。
我试过mat = scipy.io.loadmat(file)
,但提取数据的格式很奇怪。
mat = scipy.io.loadmat(file)
bboxes = np.transpose(mat['boxes'])
给出输出:
[[array([[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])]
其中形状是 (2,1)
和 numpy.array 类型。
我能够像这样提取遍历整个数据集注释的点:
points = np.array([point[0] for point in bboxes[0][0][0][0]])
层次结构是:
print(bboxes[0])
print(bboxes[0][0])
print(bboxes[0][0][0])
print(bboxes[0][0][0][0])
print(bboxes[0][0][0][0][0])
print(bboxes[0][0][0][0][0][0][1])
有没有"nicer"方法提取需要的点数?
给定打印的输出:
[[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]]
[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]
(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))
[[488.42954942 345.62261032]]
345.6226103157693
如有任何帮助,我们将不胜感激!谢谢!
这应该会给出更好的结果:
np.concatenate(bboxes[0][0].tolist()).squeeze()
我想我可以用
重新创建你的数组In [38]: array=np.array
In [43]: data = np.zeros((1,1),object)
In [44]: data[0,0] = array([[(array([[488.42954942, 345.62261032]]), array([[461
...: .57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), arra
...: y([[492.42954942, 384.62261032]]))]],
...: dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
In [45]: data
Out[45]:
array([[array([[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])]],
dtype=object)
这是一个 (1,1) 对象数据类型数组,其中包含另一个数组。该数组也是 (1,1) 形状,但具有复合数据类型(structured
数组)。
In [51]: data.shape, data.dtype
Out[51]: ((1, 1), dtype('O'))
在 MATLAB 中,一切都是二维的。 loadmat
有一个 squeeze
参数可以告诉它删除不必要的尺寸。如果没有它,我们会得到很多 (1,1) 形状的数组。
像 cell
和 struct
这样的 MATLAB 对象被 return 编辑为某种类型的对象 dtype 数组。常规 MATLAB 矩阵是 returned 数字 numpy
数组。
我们可以使用二维索引从 data
中提取一个元素(比 data[0][0]
更惯用):
In [52]: data1 = data[0,0]
In [53]: data1.shape, data1.dtype
Out[53]: ((1, 1), dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')]))
item()
也可以从数组中删除一项:
In [54]: data.item().dtype
Out[54]: dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
在此级别,数组是一个结构化数组,具有 4 个(命名的)字段,每个对象 dtype。
字段(通常)按名称索引。但是作为对象数据类型,我们还有另一层:
In [74]: data1['a']
Out[74]: array([[array([[488.42954942, 345.62261032]])]], dtype=object)
In [75]: data1['a'].item()
Out[75]: array([[488.42954942, 345.62261032]])
In [76]: data1['a'].item().squeeze()
Out[76]: array([488.42954942, 345.62261032])
@aparpara 使用 tolist()
的想法可能是提取那些嵌套对象字段的最干净的方法:
In [85]: data1.tolist()
Out[85]:
[[(array([[488.42954942, 345.62261032]]),
array([[461.57045058, 348.37738968]]),
array([[465.57045058, 387.37738968]]),
array([[492.42954942, 384.62261032]]))]]
在结构化数组上 tolist()
创建一个元组列表(或嵌套列表),每个 'record' 个数组一个元组。
然后我们可以使用np.array
或concatenate
将数组合并为一个,并使用squeeze
删除多余的维度:
In [87]: np.array(data1.tolist()).squeeze()
Out[87]:
array([[488.42954942, 345.62261032],
[461.57045058, 348.37738968],
[465.57045058, 387.37738968],
[492.42954942, 384.62261032]])
MATLAB 源代码不是简单的二维数字矩阵。因此,翻译成另一种语言也不是一件容易的事。一些loadmat
参数可以简化return结构。除此之外,我们必须通过层层深入,使用 item
或 [0,0]
类型的索引。