File size: 3,166 Bytes
c8716b4 | 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 | # -*- coding: utf-8 -*-
"""
data.py
์ด๋ฏธ ํฌ๋กญ๋ ์ฌ๋ผ์ด์ค(cropped/ + labels.jsonl)์์ ๋ฐฐํฐ๋ฆฌ๋ฅผ ์ฝ์ด์จ๋ค.
์ด ํ์ ๋ฐ์ดํฐ๋ ์๋ณธ์ด ์๋๋ผ '๋ด ์ ์ฒ๋ฆฌ ์ถ๋ ฅ'์ด๋ค:
data/cropped/<battery_key>/<slice>.jpg (๋ฐฐํฐ๋ฆฌ outline+์ฌ์ ๋ก ํฌ๋กญ๋ ํ์ ์ฌ๋ผ์ด์ค)
data/labels.jsonl (์ฌ๋ผ์ด์ค๋ณ: set/path/battery_key/type(cell|module)/swelling_flag/boxes(ํฌ๋กญ์ขํ GT))
โ ์ด๋ฏธ ํฌ๋กญ๋ผ ์์ผ๋ฏ๋ก ์ถ๋ก ์ outline ํฌ๋กญ ์์ด 'ํฌ๋กญ ์ด๋ฏธ์ง ๊ทธ๋๋ก' ํ์ผ๋ง/letterbox ํ๋ค.
๋ฃจํธ ์ง์ (์ฐ์ ์์): GLUE_DATA_ROOT > /workspace/battery-ct-security/data > d:/CT DATA
"""
import json
import os
from collections import defaultdict
from pathlib import Path
from PIL import Image
# ๋ฐฐํฐ๋ฆฌ๋น ์ฌ๋ผ์ด์ค ์ํ(๋ฐ๋ชจ ์๋; ์ถ๋น ๊ท ๋ฑ ์ํ). 0 ์ด๋ฉด ์ ๋. env GLUE_MAX_SLICES.
MAX_SLICES = int(os.environ.get("GLUE_MAX_SLICES", "0"))
_ROOT = None
_INDEX = None # {battery_key: {"type": str, "slices": [(name, rel_path)]}}
def _candidates():
env = os.environ.get("GLUE_DATA_ROOT")
if env:
yield Path(env)
yield Path("/workspace/battery-ct-security/data")
yield Path("d:/CT DATA")
def data_root():
global _ROOT
if _ROOT is not None:
return _ROOT
for c in _candidates():
if c and (c / "labels.jsonl").exists():
_ROOT = c
return _ROOT
raise FileNotFoundError(
"labels.jsonl ์ ๋ชป ์ฐพ์. GLUE_DATA_ROOT ๋ก data ํด๋๋ฅผ ์ง์ ํ์ธ์.")
def _build_index():
global _INDEX
if _INDEX is not None:
return _INDEX
root = data_root()
idx = defaultdict(lambda: {"type": None, "slices": []})
with open(root / "labels.jsonl", encoding="utf-8") as f:
for line in f:
r = json.loads(line)
bk = r["battery_key"]
idx[bk]["type"] = r.get("type")
idx[bk]["slices"].append((Path(r["path"]).stem, r["path"]))
for bk in idx:
idx[bk]["slices"].sort(key=lambda s: s[0])
_INDEX = idx
return idx
def list_batteries():
return sorted(_build_index().keys())
def cell_type_of(bid):
t = _build_index().get(bid, {}).get("type")
return t if t in ("cell", "module") else ("cell" if "cell" in bid else "module")
def _subsample(records, k):
if k <= 0 or len(records) <= k:
return records
return [records[round(t * (len(records) - 1) / (k - 1))] for t in range(k)]
def load_battery(bid):
"""๋ฐฐํฐ๋ฆฌ ํ๋ โ (slices, cell_type).
slices = [{"idx", "name", "img_path"(ํฌ๋กญ ์ด๋ฏธ์ง ์ ๋๊ฒฝ๋ก)}] (์ด๋ฏธ ํฌ๋กญ๋จ โ outline ๋ถํ์)."""
idx = _build_index()
if bid not in idx:
raise KeyError(f"๋ฐฐํฐ๋ฆฌ ์์: {bid}")
root = data_root()
recs = _subsample(idx[bid]["slices"], MAX_SLICES)
slices = [{"idx": i, "name": name, "img_path": str(root / "cropped" / rel)}
for i, (name, rel) in enumerate(recs)]
return slices, cell_type_of(bid)
def open_slice(sl):
"""ํฌ๋กญ ์ฌ๋ผ์ด์ค โ ํ์ ์ด๋ฏธ์ง(PIL 'L'). (์ด๋ฏธ ํฌ๋กญ๋ ์ด๋ฏธ์ง ๊ทธ๋๋ก)."""
return Image.open(sl["img_path"]).convert("L")
|