Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import torch | |
| import numpy as np | |
| from PIL import Image | |
| from tqdm import tqdm | |
| from loguru import logger | |
| from typing import Dict, List, Tuple | |
| # ---- あなたの定義済み Dataset, transforms があるなら import ---- | |
| # from your_dataset import BlendShapeDataset, image_transform | |
| def unify_index(idx: int, group_size: int) -> int: | |
| """ | |
| BlendShape の選択 index が group_size と同じ場合、-1 (none) に変換して返す。 | |
| """ | |
| if idx == group_size: | |
| return -1 | |
| return idx | |
| def build_combination_to_filename( | |
| teacher_data_file: str, | |
| meta_file: str, | |
| ) -> Tuple[Dict[Tuple[int, ...], str], List[int]]: | |
| """ | |
| BlendShapeData.json を読み込み、 | |
| 例: | |
| { (g0_idx, g1_idx, g2_idx): "000001.png", ... } | |
| のような辞書を作成して返す。 | |
| さらに各グループのサイズ (blendShapeNames数 + 1) のリスト group_sizes も返す。 | |
| """ | |
| with open(meta_file, "r", encoding="utf-8") as f: | |
| meta = json.load(f) | |
| blend_shape_groups = meta["blendShapeGroupsMeta"] | |
| # group_sizes[i] = len(そのグループの blendShapeNames) + 1(none枠) | |
| group_sizes = [len(g["blendShapeNames"]) + 1 for g in blend_shape_groups] | |
| # teacher_data_file 読み込み | |
| with open(teacher_data_file, "r", encoding="utf-8") as f: | |
| teacher_data = json.load(f) | |
| data_list = teacher_data["dataList"] | |
| combination_to_filename = {} | |
| for data in data_list: | |
| photo_filename = data["photoFileName"] | |
| blendShapeSelections = data["blendShapeSelectionsPerGroup"] | |
| # グループ順に selectedBlendShapeIndex を取得しつつ、-1の場合は-1のまま、 | |
| # group_sizeと一致していたら-1へ変換(理想的には -1 しか登場しない想定だが一応対応) | |
| combo = [] | |
| for group_idx, selection in enumerate(blendShapeSelections): | |
| sel_idx = selection["selectedBlendShapeIndex"] | |
| # group_sizes[group_idx] と同じなら none として -1 | |
| sel_idx = unify_index(sel_idx, group_sizes[group_idx]) | |
| combo.append(sel_idx) | |
| combo = tuple(combo) # dictのキーにするのでtuple化 | |
| combination_to_filename[combo] = photo_filename | |
| return combination_to_filename, group_sizes | |
| def main_offline_precompute(): | |
| """ | |
| 1. Dataset(JSON)から (組み合わせ -> filename) を作る | |
| 2. CLIP モデルロード | |
| 3. filename -> embedding | |
| 4. ペアワイズ類似度 | |
| 5. 保存 | |
| """ | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--image_dir", type=str, default="lapwing/images") | |
| parser.add_argument("--meta_file", type=str, default="lapwing/texts/BlendShapeGroupsMeta.json") | |
| parser.add_argument("--teacher_data_file", type=str, default="lapwing/texts/BlendShapeData.json") | |
| parser.add_argument("--clip_model_name", type=str, default="ViT-L-14") | |
| parser.add_argument("--clip_pretrained", type=str, default="openai") | |
| parser.add_argument("--batch_size", type=int, default=8) | |
| parser.add_argument("--device", type=str, default="cuda") | |
| parser.add_argument("--out_comb2fn", type=str, default="combination_to_filename.json") | |
| parser.add_argument("--out_sims", type=str, default="pairwise_clip_sims.json") | |
| args = parser.parse_args() | |
| # 1. 組み合わせ->filename辞書の作成 | |
| combination_to_filename, group_sizes = build_combination_to_filename( | |
| teacher_data_file=args.teacher_data_file, | |
| meta_file=args.meta_file, | |
| ) | |
| # 5. 保存 (JSON形式) | |
| # 5.1 (combination -> filename) | |
| # group_sizes も保存しておくと後段のオンライン時に参照しやすい | |
| # tupleは文字列化する必要あり | |
| comb2fn_dict = { | |
| "group_sizes": group_sizes, | |
| "mapping": { | |
| ",".join(map(str, comb)): fn | |
| for comb, fn in combination_to_filename.items() | |
| } | |
| } | |
| with open(args.out_comb2fn, "w", encoding="utf-8") as f: | |
| json.dump(comb2fn_dict, f, ensure_ascii=False, indent=2) | |
| # データ出力 | |
| for combo, filename in combination_to_filename.items(): | |
| logger.info(f"Combination: {combo}, Filename: {filename}") | |
| if __name__ == "__main__": | |
| main_offline_precompute() | |