Spaces:
Configuration error
Configuration error
app.py
CHANGED
|
@@ -60,7 +60,6 @@ PAPER = """
|
|
| 60 |
year = {2024}
|
| 61 |
}
|
| 62 |
"""
|
| 63 |
-
|
| 64 |
BADGES_HTML = """
|
| 65 |
<div style="display:flex;gap:12px;align-items:center;flex-wrap:wrap;">
|
| 66 |
<a href="https://github.com/yyang181/colormnet" target="_blank" title="Open GitHub Repo">
|
|
@@ -74,6 +73,51 @@ BADGES_HTML = """
|
|
| 74 |
</div>
|
| 75 |
"""
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
# ----------------- TEMP WORKDIR -----------------
|
| 78 |
TEMP_ROOT = path.join(os.getcwd(), "_colormnet_tmp")
|
| 79 |
INPUT_DIR = "input_video"
|
|
@@ -298,7 +342,7 @@ def gradio_infer(
|
|
| 298 |
|
| 299 |
# 8) 同进程调用 test.py
|
| 300 |
try:
|
| 301 |
-
import test # 确保 test.py 同目录且
|
| 302 |
except Exception as e:
|
| 303 |
return None, f"导入 test.py 失败 / Failed to import test.py:\n{e}"
|
| 304 |
|
|
@@ -321,15 +365,11 @@ def gradio_infer(
|
|
| 321 |
log = f"Args: {' '.join(args_list)}\n\n{buf.getvalue()}\n\nERROR: {e}"
|
| 322 |
return None, log
|
| 323 |
|
| 324 |
-
# 在合成 mp4 之前:清空 CUDA
|
| 325 |
try:
|
| 326 |
torch.cuda.synchronize()
|
| 327 |
except Exception:
|
| 328 |
pass
|
| 329 |
-
try:
|
| 330 |
-
del network, processor, loader, vid_reader, data, rgb, msk, prob
|
| 331 |
-
except Exception:
|
| 332 |
-
pass
|
| 333 |
try:
|
| 334 |
torch.cuda.empty_cache()
|
| 335 |
except Exception:
|
|
@@ -339,7 +379,7 @@ def gradio_infer(
|
|
| 339 |
out_frames = path.join(output_root, video_stem)
|
| 340 |
if not path.isdir(out_frames):
|
| 341 |
return None, f"未找到输出帧目录 / Output frame dir not found:{out_frames}\n\n{log}"
|
| 342 |
-
final_mp4 = path.join(TEMP_ROOT, f"{video_stem}.mp4")
|
| 343 |
try:
|
| 344 |
encode_frames_to_video(out_frames, final_mp4, fps=fps)
|
| 345 |
except Exception as e:
|
|
@@ -350,10 +390,14 @@ def gradio_infer(
|
|
| 350 |
# ----------------- UI -----------------
|
| 351 |
with gr.Blocks() as demo:
|
| 352 |
gr.Markdown(f"# {TITLE}")
|
| 353 |
-
gr.HTML(BADGES_HTML)
|
| 354 |
gr.Markdown(PAPER)
|
| 355 |
gr.Markdown(DESC)
|
| 356 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
debug_shapes = gr.Checkbox(label="调试日志 / Debug Logs(仅用于显示更完整日志 / show verbose logs)", value=False)
|
| 358 |
|
| 359 |
with gr.Row():
|
|
@@ -390,7 +434,7 @@ with gr.Blocks() as demo:
|
|
| 390 |
|
| 391 |
run_btn = gr.Button("开始着色 / Start Coloring(同进程调用 test.py / in-process)")
|
| 392 |
with gr.Row():
|
| 393 |
-
out_video = gr.Video(label="输出视频(着色结果) / Output (Colorized)")
|
| 394 |
status = gr.Textbox(label="状态 / 日志输出(test.py stdout/stderr) / Status & Logs", interactive=False, lines=16)
|
| 395 |
|
| 396 |
run_btn.click(
|
|
@@ -406,7 +450,6 @@ with gr.Blocks() as demo:
|
|
| 406 |
outputs=[out_video, status]
|
| 407 |
)
|
| 408 |
|
| 409 |
-
# 页脚徽章
|
| 410 |
gr.HTML("<hr/>")
|
| 411 |
gr.HTML(BADGES_HTML)
|
| 412 |
|
|
|
|
| 60 |
year = {2024}
|
| 61 |
}
|
| 62 |
"""
|
|
|
|
| 63 |
BADGES_HTML = """
|
| 64 |
<div style="display:flex;gap:12px;align-items:center;flex-wrap:wrap;">
|
| 65 |
<a href="https://github.com/yyang181/colormnet" target="_blank" title="Open GitHub Repo">
|
|
|
|
| 73 |
</div>
|
| 74 |
"""
|
| 75 |
|
| 76 |
+
# ----------------- REFERENCE FRAME GUIDE (NO CROPPING) -----------------
|
| 77 |
+
REF_GUIDE_MD = r"""
|
| 78 |
+
## 参考帧制作指南 / Reference Frame Guide
|
| 79 |
+
|
| 80 |
+
**目的 / Goal**
|
| 81 |
+
为模型提供一张与你的视频关键帧在**姿态、光照、构图**尽量接近的**彩色参考图**,用来指导整段视频的着色风格与主体颜色。
|
| 82 |
+
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
### 中文步骤
|
| 86 |
+
1. **挑帧**:从视频里挑一帧(或相近角度的照片),尽量与要着色的镜头在**姿态 / 光照 / 场景**一致。
|
| 87 |
+
2. **上色方式**:若你只有黑白参考图、但需要彩色参考,可用 **通义千问·图像编辑(Qwen-Image)**:
|
| 88 |
+
- 打开:<https://chat.qwen.ai/> → 选择**图像编辑**
|
| 89 |
+
- 上传你的黑白参考图
|
| 90 |
+
- 在提示词里输入:
|
| 91 |
+
**「帮我给这张照片上色,只修改颜色,不要修改内容」**
|
| 92 |
+
- 可按需多次编辑(如补充「衣服为复古蓝、肤色自然、不要锐化」)
|
| 93 |
+
3. **保存格式**:PNG/JPG 均可;推荐分辨率 ≥ **480px**(短边)。
|
| 94 |
+
4. **文件放置**:本应用会自动放置为 `ref/<视频名>/ref.png`。
|
| 95 |
+
|
| 96 |
+
**注意事项(Do/Don’t)**
|
| 97 |
+
- ✅ 主体清晰、颜色干净,不要过曝或强滤镜。
|
| 98 |
+
- ✅ 关键区域(衣服、皮肤、头发、天空等)颜色与目标风格一致。
|
| 99 |
+
- ❌ 不要更改几何结构(如人脸形状/姿态),**只修改颜色**。
|
| 100 |
+
- ❌ 避免文字、贴纸、重度风格化滤镜。
|
| 101 |
+
|
| 102 |
+
---
|
| 103 |
+
|
| 104 |
+
### English Steps
|
| 105 |
+
1. **Pick a frame** (or a similar photo) that matches the target shot in **pose / lighting / composition**.
|
| 106 |
+
2. **Colorizing if your reference is B&W** — use **Qwen-Image (Image Editing)**:
|
| 107 |
+
- Open <https://chat.qwen.ai/> → **Image Editing**
|
| 108 |
+
- Upload your B&W reference
|
| 109 |
+
- Prompt: **“Help me colorize this photo; only change colors, do not alter the content.”**
|
| 110 |
+
- Iterate if needed (e.g., “vintage blue jacket, natural skin tone; avoid sharpening”).
|
| 111 |
+
3. **Format**: PNG/JPG; recommended short side ≥ **480px**.
|
| 112 |
+
4. **File placement**: The app will place it as `ref/<video_stem>/ref.png`.
|
| 113 |
+
|
| 114 |
+
**Do / Don’t**
|
| 115 |
+
- ✅ Clean subject and palette; avoid overexposure/harsh filters.
|
| 116 |
+
- ✅ Ensure key regions (clothes/skin/hair/sky) match the intended colors.
|
| 117 |
+
- ❌ Do not change geometry/structure — **colors only**.
|
| 118 |
+
- ❌ Avoid text/stickers/heavy stylization filters.
|
| 119 |
+
"""
|
| 120 |
+
|
| 121 |
# ----------------- TEMP WORKDIR -----------------
|
| 122 |
TEMP_ROOT = path.join(os.getcwd(), "_colormnet_tmp")
|
| 123 |
INPUT_DIR = "input_video"
|
|
|
|
| 342 |
|
| 343 |
# 8) 同进程调用 test.py
|
| 344 |
try:
|
| 345 |
+
import test # 确保 test.py 同目录且提供 run_cli(args_list)
|
| 346 |
except Exception as e:
|
| 347 |
return None, f"导入 test.py 失败 / Failed to import test.py:\n{e}"
|
| 348 |
|
|
|
|
| 365 |
log = f"Args: {' '.join(args_list)}\n\n{buf.getvalue()}\n\nERROR: {e}"
|
| 366 |
return None, log
|
| 367 |
|
| 368 |
+
# 在合成 mp4 之前:清空 CUDA(防止显存占用)
|
| 369 |
try:
|
| 370 |
torch.cuda.synchronize()
|
| 371 |
except Exception:
|
| 372 |
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
try:
|
| 374 |
torch.cuda.empty_cache()
|
| 375 |
except Exception:
|
|
|
|
| 379 |
out_frames = path.join(output_root, video_stem)
|
| 380 |
if not path.isdir(out_frames):
|
| 381 |
return None, f"未找到输出帧目录 / Output frame dir not found:{out_frames}\n\n{log}"
|
| 382 |
+
final_mp4 = path.abspath(path.join(TEMP_ROOT, f"{video_stem}.mp4"))
|
| 383 |
try:
|
| 384 |
encode_frames_to_video(out_frames, final_mp4, fps=fps)
|
| 385 |
except Exception as e:
|
|
|
|
| 390 |
# ----------------- UI -----------------
|
| 391 |
with gr.Blocks() as demo:
|
| 392 |
gr.Markdown(f"# {TITLE}")
|
| 393 |
+
gr.HTML(BADGES_HTML)
|
| 394 |
gr.Markdown(PAPER)
|
| 395 |
gr.Markdown(DESC)
|
| 396 |
|
| 397 |
+
# 参考帧制作指南(中英双语,无裁剪步骤)
|
| 398 |
+
with gr.Accordion("参考帧制作指南 / Reference Frame Guide", open=False):
|
| 399 |
+
gr.Markdown(REF_GUIDE_MD)
|
| 400 |
+
|
| 401 |
debug_shapes = gr.Checkbox(label="调试日志 / Debug Logs(仅用于显示更完整日志 / show verbose logs)", value=False)
|
| 402 |
|
| 403 |
with gr.Row():
|
|
|
|
| 434 |
|
| 435 |
run_btn = gr.Button("开始着色 / Start Coloring(同进程调用 test.py / in-process)")
|
| 436 |
with gr.Row():
|
| 437 |
+
out_video = gr.Video(label="输出视频(着色结果) / Output (Colorized)", autoplay=True)
|
| 438 |
status = gr.Textbox(label="状态 / 日志输出(test.py stdout/stderr) / Status & Logs", interactive=False, lines=16)
|
| 439 |
|
| 440 |
run_btn.click(
|
|
|
|
| 450 |
outputs=[out_video, status]
|
| 451 |
)
|
| 452 |
|
|
|
|
| 453 |
gr.HTML("<hr/>")
|
| 454 |
gr.HTML(BADGES_HTML)
|
| 455 |
|