覚え書きブログ

Pythonの覚え書き(よく使い方を忘れるよく使う関数のメモ)

  • ファイル一覧の取得
>>> import os
>>> files = os.listdir('label_2')
>>> for file in files:
>>>      print(file)
000000.txt
000001.txt
...
007478.txt
007480.txt
  • パスの結合
>>> import os
>>> filePath = os.path.join('label_2',files[0])
>>> print(filePath)
'label_2\\000000.txt'
  • csvファイルの読み込み(区切り文字がスペースで、ヘッダーが無い場合)
>>> df = pd.read_csv(filePath,header=None, sep=' ')
>>> df
>>> df
         0    1   2      3       4       5       6       7     8     9   \
0     Truck  0.0   0  -1.57  599.41  156.40  629.75  189.25  2.85  2.63
1       Car  0.0   0   1.85  387.63  181.54  423.81  203.12  1.67  1.87
2   Cyclist  0.0   3  -1.65  676.60  163.95  688.98  193.93  1.86  0.60
3  DontCare -1.0  -1 -10.00  503.89  169.71  590.61  190.13 -1.00 -1.00
4  DontCare -1.0  -1 -10.00  511.35  174.96  527.81  187.45 -1.00 -1.00
5  DontCare -1.0  -1 -10.00  532.37  176.35  542.68  185.27 -1.00 -1.00
6  DontCare -1.0  -1 -10.00  559.62  175.83  575.40  183.15 -1.00 -1.00

      10       11       12       13     14
0  12.34     0.47     1.49    69.44  -1.56
1   3.69   -16.53     2.39    58.49   1.57
2   2.02     4.59     1.32    45.84  -1.55
3  -1.00 -1000.00 -1000.00 -1000.00 -10.00
4  -1.00 -1000.00 -1000.00 -1000.00 -10.00
5  -1.00 -1000.00 -1000.00 -1000.00 -10.00
6  -1.00 -1000.00 -1000.00 -1000.00 -10.00
>>>
# -*- coding: utf-8 -*-

kitti関連の覚え書き

  • kittiのメインページ

http://www.cvlibs.net/datasets/kitti/

http://ww.cvlibs.net/publications/Geiger2013IJRR.pdf

github.com
https://github.com/NVIDIA/DIGITS/issues/866

以下フォーマットの説明を抜粋:

1 type Describes the type of object: 'Car', 'Van', 'Truck',
'Pedestrian', 'Person_sitting', 'Cyclist', 'Tram',
'Misc' or 'DontCare'
1 truncated Float from 0 (non-truncated) to 1 (truncated), where
truncated refers to the object leaving image boundaries
1 occluded Integer (0,1,2,3) indicating occlusion state:
0 = fully visible, 1 = partly occluded
2 = largely occluded, 3 = unknown
1 alpha Observation angle of object, ranging [-pi..pi]
4 bbox 2D bounding box of object in the image (0-based index):
contains left, top, right, bottom pixel coordinates
3 dimensions 3D object dimensions: height, width, length (in meters)
3 location 3D object location x,y,z in camera coordinates (in meters)
1 rotation_y Rotation ry around Y-axis in camera coordinates [-pi..pi]
1 score Only for results: Float, indicating confidence in
detection, needed for p/r curves, higher is better.

つまり、スペースで区切られていて、以下の順番に記載されている。
0:物体の種類(Car, Van, Truck, Pedestrian, Person_sitting, Cyclist)
1:物体の画像からはみ出している割合(0は完全に見えている、1は完全にはみ出している)
2:オクルージョン状態(0:完全に見える、1:部分的に隠れている、2:大部分が隠れている、3:不明)
3:カメラから見た物体の向きα[-pi, pi]
4:2D bounding boxのminx
5:2D bounding boxのminy
6:2D bounding boxのmaxx
7:2D bounding boxのmaxy
8:3D object dimensionsの高さ(height)
9:3D object dimensionsの幅(width)
10:3D object dimensionsの奥行き(length)
11:3D 物体のx座標
12:3D 物体のy座標
13:3D 物体のz座標
14:カメラ座標系での物体の向きrotation_y [-pi..pi]

3と14の違いは、以下のように記載されている。
「The difference between rotation_y and alpha is, that rotation_y is directly given in camera coordinates, while alpha also considers the vector from the camera center to the object center, to compute the relative orientation of
the object with respect to the camera. For example, a car which is facing along the X-axis of the camera coordinate system corresponds to rotation_y=0, no matter where it is located in the X/Z plane (bird's eye view), while alpha is zero only,
when this object is located along the Z-axis of the camera.」
つまり、「3のαは、カメラ中心と物体の中心の間に引いた線に対する角度」であり、「4のrotation_yは、カメラ座標系のy軸周りの角度」である。
したがって、例えば、車がx軸方向に向いている場合、4のrotation_yは常にゼロであるのに対し、3は車がz軸上にあるときのみゼロとなる。
f:id:hirotaka_hachiya:20180212233303p:plain

以下は、000015.txtの例:

Car 0.89 0 2.29 0.00 194.70 414.71 373.00 1.57 1.67 4.14 -2.75 1.70 4.10 1.72
Pedestrian 0.00 1 0.71 1021.76 133.28 1101.39 316.63 1.81 1.06 0.73 4.75 1.33 7.59 1.25
Pedestrian 0.00 0 -1.58 672.23 171.73 690.13 224.33 1.73 0.84 0.86 2.46 1.41 24.14 -1.48
Pedestrian 0.00 0 -1.59 692.68 169.14 712.48 224.03 1.81 0.90 0.95 3.30 1.40 24.22 -1.46
Pedestrian 0.00 0 -1.46 537.84 168.08 560.90 224.34 1.78 0.92 1.01 -1.79 1.36 23.30 -1.54
DontCare -1 -1 -10 916.14 175.59 973.32 253.55 -1 -1 -1 -1000 -1000 -1000 -10
DontCare -1 -1 -10 628.80 173.19 653.95 196.66 -1 -1 -1 -1000 -1000 -1000 -10
DontCare -1 -1 -10 610.47 175.76 625.72 205.87 -1 -1 -1 -1000 -1000 -1000 -10
DontCare -1 -1 -10 766.54 168.32 841.38 261.86 -1 -1 -1 -1000 -1000 -1000 -10
DontCare -1 -1 -10 464.22 177.67 508.93 230.69 -1 -1 -1 -1000 -1000 -1000 -10

f:id:hirotaka_hachiya:20180212233946p:plain

  • カメラパラメータ

カメラパラメータについては、以下の論文の3ページにて説明されている。
http://ww.cvlibs.net/publications/Geiger2013IJRR.pdf

具体的には、以下のような3次元のカメラ座標から、画像座標への変換を考えた場合、各カメラの射影行列P(P0, P1, P2, P3)は下記のようになる。
ただし、ここでの変換では、同次座標系を用いているのに注意する必要がある(つまり、最後の次元zで、xとyを割る形になっている)。
同次座標については、
http://www.wakayama-u.ac.jp/~tokoi/lecture/gg/ggbook03.pdfを参照するとよい。

f:id:hirotaka_hachiya:20180214191554p:plain

P0:
7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 0.000000000000e+00
0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 0.000000000000e+00
0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00
P1:
7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 -3.797842000000e+02
0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 0.000000000000e+00
0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00
P2:
7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 4.575831000000e+01
0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 -3.454157000000e-01
0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 4.981016000000e-03
P3:
7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 -3.341081000000e+02
0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 2.330660000000e+00
0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 3.201153000000e-03
R0_rect:
9.999128000000e-01 1.009263000000e-02 -8.511932000000e-03

  • 1.012729000000e-02 9.999406000000e-01 -4.037671000000e-03

8.470675000000e-03 4.123522000000e-03 9.999556000000e-01
Tr_velo_to_cam:
6.927964000000e-03 -9.999722000000e-01 -2.757829000000e-03 -2.457729000000e-02

  • 1.162982000000e-03 2.749836000000e-03 -9.999955000000e-01 -6.127237000000e-02

9.999753000000e-01 6.931141000000e-03 -1.143899000000e-03 -3.321029000000e-01
Tr_imu_to_velo:
9.999976000000e-01 7.553071000000e-04 -2.035826000000e-03 -8.086759000000e-01

  • 7.854027000000e-04 9.998898000000e-01 -1.482298000000e-02 3.195559000000e-01

2.024406000000e-03 1.482454000000e-02 9.998881000000e-01 -7.997231000000e-01

  • Arsalan Mousavian et al., 3D Bounding Box Estimation Using Deep Learning and Geometry, CVPR2017

https://arxiv.org/pdf/1612.00496.pdf
https://cs.gmu.edu/~amousavi/papers/3D-Deepbox-Supplementary.pdf
CNNの特徴量から物体の3次元dimensionと向き、2次元のBBを回帰する際に、それぞれの平均とGTとの差分を目的変数として設定している方法。
回帰した3DBB(8頂点)と、2次元BB(4頂点)の対応する頂点の組み合わせは、8の4乗=4096通りあるが、様々な仮定(以下のような)を入れることにより64通りまで減らして移動行列を求めることにより、物体の3次元位置を推定している。
「In many scenarios the objects can be assumed to be always upright. In this case, the 2D box top and bottom correspond only to the projection of vertices from the top and bottom of the 3D box, respectively, which reduces the number of correspondences to 1024」
「Furthermore, when the relative object roll is close to zero, the vertical 2D box side coordinates xmin and xmax can only correspond to projections of points from vertical 3D box sides. Similarly, ymin and ymax can only correspond to point projections from the horizontal 3D box sides. Consequently,
each vertical side of the 2D detection box can correspond to [±dx/2, ., ±dz/2] and each horizontal side of the 2D bounding corresponds to [., ±dy/2, ±dz/2], yielding 4^4 = 256 possible configurations」
「In the KITTI dataset,object pitch and roll angles are both zero, which further reduces of the number of configurations to 64」
さらに、ワールド座標の原点は、物体の中心に対応すると仮定している。
「Assuming that the origin of the object coordinate frame is at the center of the 3D bounding box and the object dimensions D are known」

vod-converterのxmlファイルの改行

以下のvod-converterを用いて、kittiからvodに変換し、出力されたxmlファイルには改行が無い。webで見ると改行を自動的に付加してくるようだが、viで開くと一行になっているので、とても読みにくい。
github.com

つまり、こんな感じ。

<annotation><filename>006911.png</filename><folder>VOC2012</folder><segmented>0</segmented><size><depth>3</depth><width>1242</width><height>375</height></siz
e><source><annotation>Dummy</annotation><database>Dummy</database><image>Dummy</image></source><object><name>car</name><difficult>0</difficult><occluded>0</o
ccluded><truncated>0</truncated><pose>Unspecified</pose><bndbox><xmin>201.54</xmin><xmax>337.91</xmax><ymin>189.12</ymin><ymax>235.67</ymax></bndbox><positio
n><x>-11.23</x><y>1.89</y><z>23.91</z></position><rotation><object_angle>-0.62</object_angle><camera_y>-1.05</camera_y></rotation><dimensions><height>1.35</h
eight><width>1.6</width><length>3.86</length></dimensions></object><object><name>Van</name><difficult>0</difficult><occluded>0</occluded><truncated>0</trunca
ted><pose>Unspecified</pose><bndbox><xmin>220.01</xmin><xmax>346.11</xmax>

そこで、以下を参考に、改行するようにvoc.pyを変更した。
https://stackoverflow.com/questions/3095434/inserting-newlines-in-xml-file-generated-via-xml-etree-elementtree-in-python/33956544

変更した箇所は2箇所。まず、「#mport xml.etree.ElementTree as ET」をコメントアウトし、その代わりに「from lxml import etree as ET」でetreeモジュールを読み込む。次に、179行目の「 ET.ElementTree(xml_root).write(f"{annotations_path}/{image_id}.xml")」に以下のように「pretty_print=True」を追加した。

             ET.ElementTree(xml_root).write(f"{annotations_path}/{image_id}.xml",pretty_print=True)