mishig HF Staff commited on
Commit
e8c3f0d
·
verified ·
1 Parent(s): eac4010

Upload folder using huggingface_hub

Browse files
Files changed (7) hide show
  1. gen_eiffel_base.py +33 -0
  2. gen_eiffel_hq.py +35 -0
  3. gen_eiffel_scene.py +36 -0
  4. gen_hq.py +38 -0
  5. gen_images.py +48 -0
  6. gen_splats.py +54 -0
  7. hf_call.py +65 -0
gen_eiffel_base.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Eiffel diorama candidates with a CLEAN solid base (circle / square) so the
3
+ splat doesn't reconstruct a ragged 'cut' edge."""
4
+ import pathlib
5
+ import hf_call
6
+
7
+ ROOT = "https://ideogram-ai-ideogram4.hf.space"
8
+ OUT = pathlib.Path(__file__).parent / "images"
9
+
10
+ BASE = ("An architectural scale-model diorama of the Eiffel Tower standing on the "
11
+ "Champ de Mars, with tree-lined garden promenades, rows of trees and green "
12
+ "lawns spreading around its base. The whole diorama sits on a solid thick "
13
+ "{shape} display pedestal with a clean smooth {edge} edge and visible side "
14
+ "thickness, the ENTIRE {shape} base fully visible and centered in the frame "
15
+ "with margin around it. Isolated on a pure solid black background, gentle "
16
+ "elevated three-quarter view, dramatic soft studio lighting, photorealistic, "
17
+ "crisp fine detail, sharp focus, no people, no text, no watermark.")
18
+
19
+ CANDIDATES = {
20
+ "eiffel-circle": BASE.format(shape="circular", edge="round"),
21
+ "eiffel-square": BASE.format(shape="square", edge="straight"),
22
+ }
23
+
24
+ for slug, prompt in CANDIDATES.items():
25
+ dest = OUT / f"{slug}.jpg"
26
+ print(f"[gen ] {slug} ...", flush=True)
27
+ data = hf_call.call(ROOT, "generate", [
28
+ prompt, "Quality · 48 steps", "Ideogram (remote)", 1024, 1024, 0, True,
29
+ ])
30
+ hf_call.download(data[0], dest, space_root=ROOT)
31
+ print(f"[ok ] {slug} -> {dest} ({dest.stat().st_size//1024} kB)", flush=True)
32
+
33
+ print("DONE")
gen_eiffel_hq.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Re-generate the Eiffel Tower splat at higher quality: more gaussians and
3
+ more refinement steps. Tries decreasing gaussian counts if the space rejects
4
+ a high value, and writes to splats/tour-eiffel.ply."""
5
+ import pathlib, time
6
+ import hf_call
7
+
8
+ ROOT = "https://vast-ai-triposplat.hf.space"
9
+ SRC = pathlib.Path(__file__).parent / "images" / "tour-eiffel.jpg"
10
+ DEST = pathlib.Path(__file__).parent / "splats" / "tour-eiffel.ply"
11
+
12
+ GAUSSIAN_CANDIDATES = [524288, 393216, 327680, 262144]
13
+ STEPS = 32
14
+
15
+ ok = False
16
+ for ng in GAUSSIAN_CANDIDATES:
17
+ for attempt in range(1, 4):
18
+ try:
19
+ print(f"[up ] uploading image (ng={ng}, try {attempt}) ...", flush=True)
20
+ fd = hf_call.upload(ROOT, SRC)
21
+ print(f"[gen ] generating HQ splat: {ng} gaussians, {STEPS} steps ...", flush=True)
22
+ data = hf_call.call(ROOT, "generate", [
23
+ fd, 42, STEPS, 3.0, ng, "ply",
24
+ ], timeout=2400)
25
+ hf_call.download(data[1], DEST, space_root=ROOT)
26
+ print(f"[ok ] tour-eiffel HQ -> {DEST} ({DEST.stat().st_size//1024} kB, {ng} gaussians)", flush=True)
27
+ ok = True
28
+ break
29
+ except Exception as e:
30
+ print(f"[err ] ng={ng} attempt {attempt}: {e}", flush=True)
31
+ time.sleep(12)
32
+ if ok:
33
+ break
34
+
35
+ print("DONE" if ok else "FAILED")
gen_eiffel_scene.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate richer Eiffel Tower 'scene diorama' candidate images (tower + its
3
+ setting) on black, for the user to pick from before splatting."""
4
+ import pathlib
5
+ import hf_call
6
+
7
+ ROOT = "https://ideogram-ai-ideogram4.hf.space"
8
+ OUT = pathlib.Path(__file__).parent / "images"
9
+ OUT.mkdir(exist_ok=True)
10
+
11
+ COMMON = ("scene presented as a floating circular diorama isolated on a pure solid "
12
+ "black background, dramatic soft three-quarter studio lighting, photorealistic, "
13
+ "crisp fine detail, sharp focus, no people, no text, no watermark, "
14
+ "elevated three-quarter aerial view")
15
+
16
+ CANDIDATES = {
17
+ "eiffel-gardens": (
18
+ "The Eiffel Tower rising from the Champ de Mars, with the long tree-lined "
19
+ "garden promenades, rows of trees and manicured green lawns spreading out "
20
+ "around its base, the complete iron tower fully visible, " + COMMON),
21
+ "eiffel-bridge": (
22
+ "The Eiffel Tower with the Pont d'Iéna stone bridge crossing the river Seine "
23
+ "directly in front of it, tree-lined riverbanks and quays, the complete iron "
24
+ "tower fully visible behind the bridge, " + COMMON),
25
+ }
26
+
27
+ for slug, prompt in CANDIDATES.items():
28
+ dest = OUT / f"{slug}.jpg"
29
+ print(f"[gen ] {slug} ...", flush=True)
30
+ data = hf_call.call(ROOT, "generate", [
31
+ prompt, "Quality · 48 steps", "Ideogram (remote)", 1024, 1024, 0, True,
32
+ ])
33
+ hf_call.download(data[0], dest, space_root=ROOT)
34
+ print(f"[ok ] {slug} -> {dest} ({dest.stat().st_size//1024} kB)", flush=True)
35
+
36
+ print("DONE")
gen_hq.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Reusable high-quality splat generator: 524K gaussians (with fallbacks) + 32 steps.
3
+ Usage: python3 gen_hq.py <slug> [<slug> ...] (reads images/<slug>.jpg -> splats/<slug>.ply)"""
4
+ import sys, pathlib, time
5
+ import hf_call
6
+
7
+ ROOT = "https://vast-ai-triposplat.hf.space"
8
+ IMG = pathlib.Path(__file__).parent / "images"
9
+ OUT = pathlib.Path(__file__).parent / "splats"
10
+ OUT.mkdir(exist_ok=True)
11
+
12
+ GAUSSIANS = [524288, 393216, 327680, 262144]
13
+ STEPS = 32
14
+
15
+ for slug in sys.argv[1:]:
16
+ src = IMG / f"{slug}.jpg"
17
+ dest = OUT / f"{slug}.ply"
18
+ if not src.exists():
19
+ print(f"[miss] {slug}: no image", flush=True); continue
20
+ ok = False
21
+ for ng in GAUSSIANS:
22
+ for attempt in range(1, 4):
23
+ try:
24
+ print(f"[up ] {slug} (ng={ng}, try {attempt}) ...", flush=True)
25
+ fd = hf_call.upload(ROOT, src)
26
+ print(f"[gen ] {slug}: {ng} gaussians, {STEPS} steps ...", flush=True)
27
+ data = hf_call.call(ROOT, "generate", [fd, 42, STEPS, 3.0, ng, "ply"], timeout=2400)
28
+ hf_call.download(data[1], dest, space_root=ROOT)
29
+ print(f"[ok ] {slug} -> {dest} ({dest.stat().st_size//1024} kB, {ng} gaussians)", flush=True)
30
+ ok = True; break
31
+ except Exception as e:
32
+ print(f"[err ] {slug} ng={ng} attempt {attempt}: {e}", flush=True)
33
+ time.sleep(12)
34
+ if ok: break
35
+ if not ok:
36
+ print(f"[FAIL] {slug}", flush=True)
37
+
38
+ print("DONE")
gen_images.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Generate dark-background, isolated-specimen images of Paris monuments
3
+ via the ideogram-ai/ideogram4 Gradio space, then save them locally."""
4
+ import pathlib
5
+ import hf_call
6
+
7
+ ROOT = "https://ideogram-ai-ideogram4.hf.space"
8
+ OUT = pathlib.Path(__file__).parent / "images"
9
+ OUT.mkdir(exist_ok=True)
10
+
11
+ MONUMENTS = {
12
+ "tour-eiffel": "the Eiffel Tower, the complete iron lattice tower",
13
+ "opera-garnier": "the Palais Garnier opera house of Paris, the complete ornate Beaux-Arts opera building with its green dome, columned facade and gilded rooftop sculptures",
14
+ "arc-de-triomphe": "the Arc de Triomphe, the complete triumphal arch",
15
+ "sacre-coeur": "the Sacré-Cœur Basilica of Montmartre, the complete white-domed basilica",
16
+ "moulin-rouge": "the Moulin Rouge cabaret of Paris, the complete building with its iconic bright red windmill on the roof, red facade and awnings",
17
+ "pantheon": "the Panthéon of Paris, the complete neoclassical monument with its large dome and tall columned portico",
18
+ }
19
+
20
+ def prompt_for(subject):
21
+ return (
22
+ f"A photorealistic architectural studio photograph of {subject}, "
23
+ "the entire structure fully visible and centered in the frame, "
24
+ "isolated on a pure solid black background, dramatic soft three-quarter "
25
+ "studio lighting, crisp fine detail, sharp focus, no people, no text, "
26
+ "no watermark, museum specimen presentation, full object 3/4 view"
27
+ )
28
+
29
+ for slug, subject in MONUMENTS.items():
30
+ dest = OUT / f"{slug}.jpg"
31
+ if dest.exists():
32
+ print(f"[skip] {slug}", flush=True)
33
+ continue
34
+ print(f"[gen ] {slug} ...", flush=True)
35
+ data = hf_call.call(ROOT, "generate", [
36
+ prompt_for(subject), # prompt
37
+ "Quality · 48 steps", # mode
38
+ "Ideogram (remote)", # upsampler
39
+ 1024, # width
40
+ 1024, # height
41
+ 0, # seed
42
+ True, # randomize_seed
43
+ ])
44
+ img = data[0]
45
+ hf_call.download(img, dest, space_root=ROOT)
46
+ print(f"[ok ] {slug} -> {dest} ({dest.stat().st_size//1024} kB)", flush=True)
47
+
48
+ print("DONE")
gen_splats.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Turn each monument image into a 3D gaussian splat (.ply) via the
3
+ VAST-AI/TripoSplat Gradio space."""
4
+ import pathlib, sys, time
5
+ import hf_call
6
+
7
+ ROOT = "https://vast-ai-triposplat.hf.space"
8
+ IMG = pathlib.Path(__file__).parent / "images"
9
+ OUT = pathlib.Path(__file__).parent / "splats"
10
+ OUT.mkdir(exist_ok=True)
11
+
12
+ SLUGS = ["tour-eiffel", "louvre-pyramid", "arc-de-triomphe",
13
+ "sacre-coeur", "notre-dame", "obelisque"]
14
+
15
+ # allow running a subset: python3 gen_splats.py tour-eiffel obelisque
16
+ if len(sys.argv) > 1:
17
+ SLUGS = sys.argv[1:]
18
+
19
+ for slug in SLUGS:
20
+ src = IMG / f"{slug}.jpg"
21
+ dest = OUT / f"{slug}.ply"
22
+ if dest.exists():
23
+ print(f"[skip] {slug}", flush=True)
24
+ continue
25
+ if not src.exists():
26
+ print(f"[miss] {slug} image not found", flush=True)
27
+ continue
28
+ ok = False
29
+ for attempt in range(1, 5):
30
+ try:
31
+ print(f"[up ] {slug} uploading image (try {attempt}) ...", flush=True)
32
+ filedata = hf_call.upload(ROOT, src)
33
+ print(f"[gen ] {slug} generating splat (this can take a few min) ...", flush=True)
34
+ data = hf_call.call(ROOT, "generate", [
35
+ filedata, # image
36
+ 42, # seed
37
+ 20, # steps
38
+ 3.0, # guidance_scale
39
+ 262144, # num_gaussians
40
+ "ply", # output_format
41
+ ], timeout=1800)
42
+ # returns (preprocessed_image, ply_file, download_file, info_string)
43
+ ply = data[1]
44
+ hf_call.download(ply, dest, space_root=ROOT)
45
+ print(f"[ok ] {slug} -> {dest} ({dest.stat().st_size//1024} kB)", flush=True)
46
+ ok = True
47
+ break
48
+ except Exception as e:
49
+ print(f"[err ] {slug} attempt {attempt}: {e}", flush=True)
50
+ time.sleep(15)
51
+ if not ok:
52
+ print(f"[FAIL] {slug} gave up after retries", flush=True)
53
+
54
+ print("DONE")
hf_call.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Minimal Gradio REST helper (no gradio_client dependency).
2
+ Implements: upload file, call endpoint, poll SSE result."""
3
+ import os, json, pathlib, requests
4
+
5
+ def token():
6
+ return (os.environ.get("HF_TOKEN")
7
+ or pathlib.Path("~/.cache/huggingface/token").expanduser().read_text().strip())
8
+
9
+ def _headers():
10
+ return {"Authorization": f"Bearer {token()}"}
11
+
12
+ def upload(space_root, filepath):
13
+ """Upload a local file, return the gradio FileData dict to reference it."""
14
+ with open(filepath, "rb") as f:
15
+ r = requests.post(f"{space_root}/gradio_api/upload",
16
+ headers=_headers(),
17
+ files={"files": (pathlib.Path(filepath).name, f)},
18
+ timeout=300)
19
+ r.raise_for_status()
20
+ server_path = r.json()[0]
21
+ return {"path": server_path, "meta": {"_type": "gradio.FileData"},
22
+ "orig_name": pathlib.Path(filepath).name, "url": None,
23
+ "size": None, "mime_type": None, "is_stream": False}
24
+
25
+ def call(space_root, api_name, data, timeout=900):
26
+ """Call /gradio_api/call/{api_name} with ordered `data` list; poll SSE; return data list."""
27
+ r = requests.post(f"{space_root}/gradio_api/call/{api_name}",
28
+ headers={**_headers(), "Content-Type": "application/json"},
29
+ data=json.dumps({"data": data}), timeout=60)
30
+ r.raise_for_status()
31
+ event_id = r.json()["event_id"]
32
+ # poll the SSE stream
33
+ with requests.get(f"{space_root}/gradio_api/call/{api_name}/{event_id}",
34
+ headers=_headers(), stream=True, timeout=timeout) as s:
35
+ s.raise_for_status()
36
+ event = None
37
+ for raw in s.iter_lines(decode_unicode=True):
38
+ if raw is None or raw == "":
39
+ continue
40
+ if raw.startswith("event:"):
41
+ event = raw.split(":", 1)[1].strip()
42
+ elif raw.startswith("data:"):
43
+ payload = raw.split(":", 1)[1].strip()
44
+ if event == "complete":
45
+ return json.loads(payload)
46
+ if event == "error":
47
+ raise RuntimeError(f"Gradio error: {payload}")
48
+ raise RuntimeError("SSE stream ended without a 'complete' event")
49
+
50
+ def download(url_or_data, dest, space_root=None):
51
+ """Download a gradio result (url string or FileData dict) to dest."""
52
+ if isinstance(url_or_data, dict):
53
+ url = url_or_data.get("url")
54
+ if not url and url_or_data.get("path") and space_root:
55
+ url = f"{space_root}/gradio_api/file={url_or_data['path']}"
56
+ else:
57
+ url = url_or_data
58
+ if url and url.startswith("/") and space_root:
59
+ url = space_root + url
60
+ r = requests.get(url, headers=_headers(), stream=True, timeout=600)
61
+ r.raise_for_status()
62
+ with open(dest, "wb") as f:
63
+ for chunk in r.iter_content(chunk_size=1 << 16):
64
+ f.write(chunk)
65
+ return dest