如何将.mat二进制格式转换为2D numpy数组?

时间:2019-10-06 11:42:18

标签: python numpy mat-file

我正在将hand_dataset注释转换为可以在YOLOv3中使用的格式。注释采用.mat二进制格式,我想将其提取,转换为.csv并重新组织。

我尝试过2019-10-04T00:00,但是提取数据的格式却很奇怪。

$date_to_show = date('Y-m-d\TH:i', strtotime('2019-10-04 00:00:00'));//2019-10-04T00:00

给出输出:

mat = scipy.io.loadmat(file)

其中形状为mat = scipy.io.loadmat(file) bboxes = np.transpose(mat['boxes']) ,类型为numpy.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')])]

层次结构是

(2,1)

是否有“更精细”的方法来提取所需的点?

给定打印输出:

points = np.array([point[0] for point in bboxes[0][0][0][0]])

任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:0)

这应该给出更好的结果:

np.concatenate(bboxes[0][0].tolist()).squeeze()

答案 1 :(得分:0)

我想我可以用以下方式重新创建您的数组

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)对象dtype数组,其中包含另一个数组。该数组也是(1,1)形状,但是具有复合dtype(structured数组)。

In [51]: data.shape, data.dtype                                                 
Out[51]: ((1, 1), dtype('O'))

在MATLAB中,一切都是2d。 loadmat有一个squeeze参数,可以告诉它删除不必要的尺寸。没有这些,我们将得到很多(1,1)形状的数组。

MATLAB对象(如cellstruct)作为某种对象dtype数组返回。常规的MATLAB矩阵返回一个数字numpy数组。

我们可以使用2d索引(比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。

(通常)按名称对字段进行索引。但是作为对象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()上创建一个元组列表(或嵌套列表),每个“记录”数组一个元组。

然后,我们可以使用np.arrayconcatenate将数组合并为一个,并使用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参数可以简化返回结构。除此之外,我们还必须使用item[0,0]这种索引来逐步遍历各个层次。