#!/usr/bin/env python3 """依頼140:並べた図2枚。引き6枚(行=範囲・列=真上・60°・75°)と寄り8枚(行=右30°・左30°・列=角度。絵の下に4つの数) python3 sheet140.py <出力フォルダ> (stills/ のパネル付きの絵と sheets/near_metrics140.csv を読む) """ import csv, os, sys from PIL import Image, ImageDraw, ImageFont O = "/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261110_look140" FB = os.path.expanduser("~/Library/Fonts/NotoSansJP-Bold.otf") FR = os.path.expanduser("~/Library/Fonts/NotoSansJP-Regular.otf") INK, GRAY = (29, 29, 27), (90, 90, 88) HEAD = "病院 h0・廊下だけ・0.6m/秒・種0・9時57分42秒・色A" def f(b, s): return ImageFont.truetype(FB if b else FR, s) def wide(out): cw, ch, top, left, gap = 1280, 720, 150, 300, 14 rows = [("full", "全長", "x-0.5〜120.5・z12.5〜31.5"), ("west", "西半分", "x-0.5〜72・z12.5〜31.5")] cols = [("top", "真上(90°)"), ("l30_60", "60°見下ろし・左30°"), ("l30_75", "75°見下ろし・左30°")] sheet = Image.new("RGB", (left + (cw + gap) * 3 + 10, top + (ch + 70) * 2 + 10), (255, 255, 255)) d = ImageDraw.Draw(sheet) d.text((20, 20), "依頼140 引きを廊下と待合に絞る(6枚) " + HEAD, font=f(True, 44), fill=INK) for j, (k, ja) in enumerate(cols): d.text((left + j * (cw + gap), top - 56), ja, font=f(True, 36), fill=INK) for i, (k, ja, rng) in enumerate(rows): y = top + i * (ch + 70) d.text((20, y + 20), ja, font=f(True, 40), fill=INK) d.text((20, y + 80), rng.split("・")[0], font=f(False, 28), fill=GRAY) d.text((20, y + 118), rng.split("・")[1], font=f(False, 28), fill=GRAY) for j, (c, _) in enumerate(cols): im = Image.open(os.path.join(O, "stills", "still_A_w_%s_%s.png" % (k, c))).resize((cw, ch), Image.LANCZOS) sheet.paste(im, (left + j * (cw + gap), y)) p = os.path.join(out, "wide6_140.png") sheet.save(p) print(p, sheet.size) def near(out): m = {r["cam"]: r for r in csv.DictReader(open(os.path.join(O, "sheets", "near_metrics140.csv"), encoding="utf-8"))} cw, ch, top, left, gap, note = 1120, 630, 150, 240, 14, 150 pitches = [("60", "60°"), ("675", "67.5°"), ("75", "75°"), ("825", "82.5°")] rows = [("r30", "右30°", "南東から"), ("l30", "左30°", "南西から")] sheet = Image.new("RGB", (left + (cw + gap) * 4 + 10, top + (ch + note + 20) * 2 + 60), (255, 255, 255)) d = ImageDraw.Draw(sheet) d.text((20, 20), "依頼140 寄りの角度(8枚・x9〜31・z26〜32) " + HEAD, font=f(True, 44), fill=INK) for j, (k, ja) in enumerate(pitches): d.text((left + j * (cw + gap), top - 56), "見下ろす " + ja, font=f(True, 36), fill=INK) fs = f(False, 26) for i, (k, ja, sub) in enumerate(rows): y = top + i * (ch + note + 20) d.text((20, y + 20), ja, font=f(True, 40), fill=INK) d.text((20, y + 80), sub, font=f(False, 28), fill=GRAY) for j, (p, _) in enumerate(pitches): n = "n_%s_%s" % (k, p) x = left + j * (cw + gap) im = Image.open(os.path.join(O, "stills", "still_A_%s.png" % n)).resize((cw, ch), Image.LANCZOS) sheet.paste(im, (x, y)) r = m[n] lines = ["見える廊下 %s%% 見える輪 %s/%s" % (r["hall_visible_pct"], r["rings_visible"], r["rings_total"]), "ロボットの上の面が見える %s%%(画面の中 %s/%s コマ・うち隠れ %s)" % ( r["robot_top_center_visible_pct"], r["robot_inframe_frames"], r["robot_frames"], r["robot_hidden_inframe_frames"]), "人(カプセル)の高さ %s 画素(足元〜頭の線 %s 画素)" % (r["person_px"], r["person_axis_px"])] for k2, s in enumerate(lines): d.text((x + 6, y + ch + 10 + k2 * 40), s, font=fs, fill=INK) y = top + (ch + note + 20) * 2 d.text((20, y), "数の決め方:見える=カメラから見て部屋の箱・壁に隠れず画面の中にある。廊下=x9〜31・z27〜31 の床。輪=8852〜8862 秒に出た輪の中心。" "ロボット=8845〜8945 秒・0.2 秒ごと 501 コマで白い円柱の上の面の中心。人の高さ=(20, 29) に立つカプセル(1.59 m)の画面の縦の幅(左 1360×1080 の絵で)", font=f(False, 24), fill=GRAY) pth = os.path.join(out, "near8_140.png") sheet.save(pth) print(pth, sheet.size) if __name__ == "__main__": out = sys.argv[1] if len(sys.argv) > 1 else os.path.join(O, "sheets") wide(out) near(out)