| import gradio as gr |
| import os |
| import tempfile |
| from PIL import Image, ImageEnhance |
| import numpy as np |
| import axengine as axe |
| import cv2 |
| import socket |
|
|
| |
| |
| |
| def init_DeOldifymodel(DeOldifyStable_path="../model/colorize_stable.axmodel", |
| DeOldifyArtistic_path="../model/colorize_artistic.axmodel"): |
| |
| DeOldifyStable_session = axe.InferenceSession(DeOldifyStable_path) |
| DeOldifyArtistic_session = axe.InferenceSession(DeOldifyArtistic_path) |
|
|
| return [DeOldifyStable_session, DeOldifyArtistic_session] |
|
|
| DeOldify_sessions=init_DeOldifymodel() |
|
|
| def from_numpy(x): |
| return x if isinstance(x, np.ndarray) else np.array(x) |
| |
| def post_process(raw_color, orig): |
| color_np = np.asarray(raw_color) |
| orig_np = np.asarray(orig) |
| color_yuv = cv2.cvtColor(color_np, cv2.COLOR_RGB2YUV) |
| |
| orig_yuv = cv2.cvtColor(orig_np, cv2.COLOR_RGB2YUV) |
| hires = np.copy(orig_yuv) |
| hires[:, :, 1:3] = color_yuv[:, :, 1:3] |
| final = cv2.cvtColor(hires, cv2.COLOR_YUV2RGB) |
| return final |
|
|
| def colorize_with_model(img_path, session): |
| output_names = [x.name for x in session.get_outputs()] |
| input_name = session.get_inputs()[0].name |
|
|
| ori_image = cv2.imread(img_path) |
| h, w = ori_image.shape[:2] |
| image = cv2.resize(ori_image, (512, 512)) |
| image = (image[..., ::-1] /255.0).astype(np.float32) |
| |
| mean = [0.485, 0.456, 0.406] |
| std = [0.229, 0.224, 0.225] |
| image = ((image - mean) / std).astype(np.float32) |
|
|
| |
| image = np.transpose(np.expand_dims(np.ascontiguousarray(image), axis=0), (0,3,1,2)) |
| |
| |
| sr = session.run(output_names, {input_name: image}) |
| |
| if isinstance(sr, (list, tuple)): |
| sr = from_numpy(sr[0]) if len(sr) == 1 else [from_numpy(x) for x in sr] |
| else: |
| sr = from_numpy(sr) |
|
|
| |
| sr = np.transpose(sr.squeeze(0), (1,2,0)) |
| sr = (sr*std + mean).astype(np.float32) |
| |
| |
| ndarr = np.clip((sr*255.0), 0, 255.0).astype(np.uint8) |
| ndarr = cv2.resize(ndarr[..., ::-1], (w, h)) |
| out_image = post_process(ndarr, ori_image) |
|
|
| return out_image |
|
|
| def colorize_image(input_img_path: str, model_name: str, progress=gr.Progress()): |
| if not input_img_path: |
| raise gr.Error("未上传图片") |
|
|
| |
| progress(0.3, desc="加载图像...") |
|
|
| |
| if model_name == "colorize_stable": |
| session = DeOldify_sessions[0] |
| else: |
| session = DeOldify_sessions[1] |
| out = colorize_with_model(input_img_path, session) |
|
|
| progress(0.9, desc="保存结果...") |
|
|
| |
| output_path = os.path.join(tempfile.gettempdir(), "colorized_output.jpg") |
| cv2.imwrite(output_path, out) |
|
|
| progress(1.0, desc="完成!") |
| return output_path |
|
|
|
|
| |
| |
| |
| custom_css = """ |
| body, .gradio-container { |
| font-family: 'Microsoft YaHei', 'PingFang SC', 'Helvetica Neue', Arial, sans-serif; |
| } |
| .model-buttons .wrap { |
| display: flex; |
| gap: 10px; |
| } |
| .model-buttons .wrap label { |
| background-color: #f0f0f0; |
| padding: 10px 20px; |
| border-radius: 8px; |
| cursor: pointer; |
| text-align: center; |
| font-weight: 600; |
| border: 2px solid transparent; |
| flex: 1; |
| } |
| .model-buttons .wrap label:hover { |
| background-color: #e0e0e0; |
| } |
| .model-buttons .wrap input[type="radio"]:checked + label { |
| background-color: #4CAF50; |
| color: white; |
| border-color: #45a049; |
| } |
| """ |
|
|
| with gr.Blocks(title="AI 图片上色工具") as demo: |
| gr.Markdown("## 🎨 AI 黑白图片自动上色演示") |
|
|
| with gr.Row(equal_height=True): |
| |
| with gr.Column(scale=1, min_width=300): |
| gr.Markdown("### 📤 输入") |
| input_image = gr.Image( |
| type="filepath", |
| label="上传黑白/灰度图片", |
| sources=["upload"], |
| height=300 |
| ) |
| |
| gr.Markdown("### 🔧 选择上色模型") |
| model_choice = gr.Radio( |
| choices=["colorize_stable", "colorize_artistic"], |
| value="colorize_stable", |
| label=None, |
| elem_classes="model-buttons" |
| ) |
| |
| run_btn = gr.Button("🚀 开始上色", variant="primary") |
|
|
| |
| with gr.Column(scale=1, min_width=600): |
| gr.Markdown("### 🖼️ 上色结果") |
| output_image = gr.Image( |
| label="上色后图片", |
| interactive=False, |
| height=600 |
| ) |
| download_btn = gr.File(label="📥 下载上色图片") |
|
|
| |
| def on_colorize(img_path, model, progress=gr.Progress()): |
| if img_path is None: |
| raise gr.Error("请先上传图片!") |
| try: |
| result_path = colorize_image(img_path, model, progress=progress) |
| return result_path, result_path |
| except Exception as e: |
| raise gr.Error(f"处理失败: {str(e)}") |
|
|
| run_btn.click( |
| fn=on_colorize, |
| inputs=[input_image, model_choice], |
| outputs=[output_image, download_btn] |
| ) |
| def get_local_ip(): |
| """获取本机局域网IP地址""" |
| try: |
| |
| with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: |
| s.connect(("8.8.8.8", 80)) |
| ip = s.getsockname()[0] |
| return ip |
| except Exception: |
| |
| return "127.0.0.1" |
|
|
|
|
| if __name__ == "__main__": |
| |
|
|
| server_port = 7860 |
| server_name = "0.0.0.0" |
| |
| |
| local_ip = get_local_ip() |
| |
| |
| print("\n" + "="*50) |
| print("🌐 AI图片上色 Web UI 已启动!") |
| print(f"🔗 本地访问: http://127.0.0.1:{server_port}") |
| if local_ip != "127.0.0.1": |
| print(f"🔗 局域网访问: http://{local_ip}:{server_port}") |
| print("="*50 + "\n") |
|
|
| |
| demo.launch( |
| server_name=server_name, |
| server_port=server_port, |
| theme=gr.themes.Soft() |
| ) |