File size: 4,683 Bytes
ceea884
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
"""์นด๋ฉ”๋ผ ๋ชจ๋“œ ์žฅ ('์นด๋ฉ”๋ผ ์„ผ์„œ ์ข…๋ฅ˜ โ€” RGB ยท ๊นŠ์ด ยท โ€ฆ') ๋ฐ”๋กœ ๋’ค์— ๋ผ์ด๋‹ค ยท ๋ ˆ์ด๋” ์„ผ์„œ ๋ฐ์ดํ„ฐ ์žฅ์„ ๋„ฃ๋Š”๋‹ค.

๊ฐ™์€ ํ‹€ ยท ๊ฐ™์€ ๋ฐฐ์น˜ (์™ผ์ชฝ 2ร—2 ๊ทธ๋ฆผ + ์˜ค๋ฅธ์ชฝ ์„ค๋ช… ์ƒ์ž 4๊ฐœ) โ€” ์ƒ์ž๋Š” ์นด๋ฉ”๋ผ ๋ชจ๋“œ ์žฅ์˜ ๊ฒƒ์„ ๋ณต์‚ฌํ•ด ๊ธ€๋งŒ ๋ฐ”๊พผ๋‹ค.
๊ทธ๋ฆผ: figures/out/sensors_data.jpg (figures/sensors/ ์˜ sdump ยท run.py ยท viz.py).
์‹คํ–‰: python docs/presentation/add_sensor_data_slide.py [์ž…๋ ฅ.pptx] [์ถœ๋ ฅ.pptx]   (๊ธฐ๋ณธ: vkgs_sim_merged.pptx ๋ฅผ ์ œ์ž๋ฆฌ์—์„œ)
"""

import copy
import sys
from pathlib import Path

from PIL import Image
from pptx import Presentation
from pptx.oxml.ns import qn

HERE = Path(__file__).resolve().parent
SRC = Path(sys.argv[1]) if len(sys.argv) > 1 else HERE / "vkgs_sim_merged.pptx"
OUT = Path(sys.argv[2]) if len(sys.argv) > 2 else SRC
FIG = HERE / "figures/out/sensors_data.jpg"
ANCHOR = "์นด๋ฉ”๋ผ ์„ผ์„œ ์ข…๋ฅ˜"
HEADING = "๋ผ์ด๋‹ค ยท ๋ ˆ์ด๋” ์„ผ์„œ ๋ฐ์ดํ„ฐ โ€” ๊ฐ™์€ ์ˆœ๊ฐ„์˜ 4๊ฐ€์ง€ ๋ณด๊ธฐ"
BULLET = "scene-0402 ๊ธฐ๋ก ์ฃผํ–‰์˜ ํ•œ ์ˆœ๊ฐ„ (11.9 m/s) โ€” ๋ผ์ด๋‹ค ํ•œ ๋ฐ”ํ€ด 3.4๋งŒ ์  ยท ๋ ˆ์ด๋” 5๋Œ€ ๊ฒ€์ถœ 605๊ฐœ, ๋‹ค๋ฅธ ์ฐจ๋Ÿ‰์€ nuScenes ๋ฐ•์Šค"
BOXES = [("๋ผ์ด๋‹ค โ†’ ์นด๋ฉ”๋ผ ํˆฌ์˜", "๊ฐ™์€ ์ˆœ๊ฐ„์˜ ์‹ค์ œ nuScenes ์ •๋ฉด ์‚ฌ์ง„์— ์‹œ๋ฎฌ ๋ผ์ด๋‹ค ์ ์„ ํˆฌ์˜ โ€” ๋…ธ๋ฉด ๋ง ยท ๊ธธ๊ฐ€ ๋‚˜๋ฌด ยท ์•ž ์ฐจ๋Ÿ‰ ์ž๋ฆฌ๊ฐ€ ์‚ฌ์ง„๊ณผ ๊ฒน์นจ"),
         ("๊ฑฐ๋ฆฌ ์˜์ƒ ยท BEV", "HDL-32E ๊ทผ์‚ฌ: 32๋น” (+10.7ยฐ ~ โˆ’30.7ยฐ) ร— 0.33ยฐ ๋ฐฉ์œ„, 70 m, 20 Hz โ€” ๋ณต์…€ ์›”๋“œ (0.2 m) ์— ๊ด‘์„ ์„ ์จ"),
         ("๋ ˆ์ด๋” 5๋Œ€", "ARS 408 ๊ทผ์‚ฌ: ์‹œ์•ผ 120ยฐ ยท 120 m ยท 13 Hz ยท ๋Œ€๋‹น ์ตœ๋Œ€ 125์ , ๋…ธ๋ฉด ๋ฐ˜์‚ฌ ์ œ๊ฑฐ โ€” ์ •์ง€๋ฌผ ๋„ํ”Œ๋Ÿฌ vr = โˆ’vยทcosฮธ"),
         ("์ถœ๋ ฅ ํ˜•์‹", "O ํ‚ค ยท closed-loop (--serve) ๊ด€์ธก์— ํ•จ๊ป˜ ์ €์žฅ โ€” LIDAR_TOP.bin (nuScenes .pcd.bin) ยท RADAR_*.txt (vr ยท ๋ณด์ • ์†๋„ ยท RCS)")]
NOTE = ("๊ทธ๋ฆผ 1: ์‹ค์ œ ์‚ฌ์ง„ ์œ„ ํˆฌ์˜ โ€” ์‹œ๋ฎฌ ๋ผ์ด๋‹ค ๊ธฐํ•˜๊ฐ€ ์‹ค์ œ ์žฅ๋ฉด๊ณผ ๋งž๋Š”์ง€ ๋ณด๋Š” ๊ทธ๋ฆผ. ๊ทธ๋ฆผ 2: ๋ผ์ด๋‹ค ์›์‹œ ๋ฐ์ดํ„ฐ ํ˜•์‹ (๋น” ร— ๋ฐฉ์œ„ ๊ฑฐ๋ฆฌ ์˜์ƒ). "
        "๊ทธ๋ฆผ 3: ์œ„์—์„œ ๋ณธ ํ•œ ๋ฐ”ํ€ด, ์ƒ‰์€ ์ง€๋ฉด ์œ„ ๋†’์ด. ๊ทธ๋ฆผ 4: ๋ ˆ์ด๋” 5๋Œ€ ์‹œ์•ผ์™€ ๊ฒ€์ถœ, ์ƒ‰์€ ๋„ํ”Œ๋Ÿฌ โ€” ์ž์ฐจ๊ฐ€ ์›€์ง์ด๋ฏ€๋กœ ์ •์ง€๋ฌผ๋„ ์•ž์€ ๋‹ค๊ฐ€์˜ด, ๋’ค๋Š” ๋ฉ€์–ด์ง. "
        "๋‹ค๋ฅธ ์ฐจ๋Ÿ‰์€ nuScenes ์–ด๋…ธํ…Œ์ด์…˜ ๋ฐ•์Šค๋กœ ๋„ฃ์—ˆ๊ณ  ์ •์ง€๋กœ ๋ณธ๋‹ค (์†๋„ ยท ๋„ํ”Œ๋Ÿฌ๋Š” ๊ตํ†ต ์ฐธ๊ฐ€์ž ์ž‘์—… ๋’ค). ๋งŒ๋“œ๋Š” ๋ฒ•: figures/sensors/README.txt.")

def heading(s):
    """์†Œ์ œ๋ชฉ ๋ง‰๋Œ€ (๊ทธ๋ฃน ๋„ํ˜•) ์˜ ๊ธ€."""
    return "".join(c.text_frame.text for sh in s.shapes if sh.shape_type == 6 for c in sh.shapes if c.has_text_frame)


prs = Presentation(SRC)
slides = list(prs.slides)
if any(HEADING in heading(s) for s in slides):
    sys.exit(f"์ด๋ฏธ ๋“ค์–ด ์žˆ๋‹ค: {SRC}")
src = next(s for s in slides if ANCHOR in heading(s))

sl = prs.slides.add_slide(src.slide_layout)
tree = sl.shapes._spTree
for sh in list(sl.shapes):
    tree.remove(sh._element)
pic_box = None
for sh in src.shapes:
    if sh.shape_type == 13:  # ๊ทธ๋ฆผ ์ž๋ฆฌ๋งŒ ๊ธฐ์–ตํ•˜๊ณ  ๊ทธ๋ฆผ์€ ์ƒˆ๋กœ ๋„ฃ๋Š”๋‹ค
        pic_box = (sh.left, sh.top, sh.width, sh.height)
        continue
    el = copy.deepcopy(sh._element)
    for node in el.iter():
        for attr in (qn("r:embed"), qn("r:link"), qn("r:id")):
            rid = node.get(attr)
            if rid:
                node.set(attr, sl.part.relate_to(src.part.related_part(rid), src.part.rels[rid].reltype))
    tree.append(el)


def set_text(p, text):
    rs = p.runs
    rs[0].text = text
    for r in rs[1:]:
        r._r.getparent().remove(r._r)


boxes = [sh for sh in sl.shapes if sh.name.startswith("Rounded Rectangle")]
assert len(boxes) == len(BOXES), len(boxes)
for sh, (t, d) in zip(sorted(boxes, key=lambda s: s.top), BOXES):
    ps = sh.text_frame.paragraphs
    set_text(ps[0], t)
    set_text(ps[1], d)
for sh in sl.shapes:
    if sh.shape_type == 6:
        for c in sh.shapes:
            if c.has_text_frame and c.text_frame.text.strip():
                set_text(c.text_frame.paragraphs[0], HEADING)
    elif sh.name == "TextBox 9":
        tf = sh.text_frame
        for p in tf.paragraphs[1:]:
            p._p.getparent().remove(p._p)
        set_text(tf.paragraphs[0], BULLET)

x, y, w, h = pic_box
im = Image.open(FIG)
s_ = min(w / im.width, h / im.height)
sl.shapes.add_picture(str(FIG), x + int((w - im.width * s_) / 2), y, int(im.width * s_), int(im.height * s_))
sl.notes_slide.notes_text_frame.text = NOTE

lst = prs.slides._sldIdLst
new = list(lst)[-1]
lst.remove(new)
list(lst)[slides.index(src)].addnext(new)
prs.save(OUT)
print("saved", OUT, len(prs.slides), "slides โ€” ์ƒˆ ์žฅ", slides.index(src) + 2, "์ชฝ")