Spaces:
Runtime error
Runtime error
| # app.py — 可直接替换你原项目中的文件 | |
| import os | |
| import sys | |
| import logging | |
| import time | |
| import random | |
| import warnings | |
| import json | |
| import numpy as np | |
| from PIL import Image, ImageDraw, ImageFont | |
| import gradio as gr | |
| import colorsys | |
| # 设置环境变量解决 OpenMP 问题 | |
| os.environ['OMP_NUM_THREADS'] = '1' | |
| os.environ['MKL_NUM_THREADS'] = '1' | |
| # 抑制警告 | |
| warnings.filterwarnings("ignore") | |
| # 设置日志 | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
| logger = logging.getLogger(__name__) | |
| # 检查模型管理器是否存在(注意:路径已调整为你指定的 model/modal_manager.py) | |
| try: | |
| from models.model_manager import ModelManager | |
| MODELS_AVAILABLE = True | |
| logger.info("模型管理器导入成功") | |
| except ImportError as e: | |
| logger.warning(f"模型管理器导入失败: {e}") | |
| logger.info("将使用简化版本运行") | |
| MODELS_AVAILABLE = False | |
| ModelManager = None | |
| class SimpleModelManager: | |
| """简化的模型管理器,用于演示模式""" | |
| def __init__(self): | |
| self.device = "cpu" | |
| logger.info("使用简化模型管理器") | |
| def generate_caption(self, image): | |
| if 'last_generated_design' not in globals() or last_generated_design is None: | |
| return '请先生成建议设计' | |
| return "一件时尚的{}服装,采用{}设计".format( | |
| random.choice(["夏季", "冬季", "春秋季"]), | |
| random.choice(["简约", "复古", "现代", "街头"]) | |
| ) | |
| def analyze_style(self, image): | |
| styles = ["商务正装", "休闲风", "运动风", "时尚潮流", "复古风", "街头风", "优雅风"] | |
| scores = {style: random.uniform(0.3, 0.9) for style in random.sample(styles, 3)} | |
| return scores | |
| def generate_image(self, prompt, **kwargs): | |
| width = kwargs.get('width', 512) | |
| height = kwargs.get('height', 512) | |
| img = Image.new('RGB', (width, height), color=(200, 200, 200)) | |
| draw = ImageDraw.Draw(img) | |
| try: | |
| font = ImageFont.load_default() | |
| draw.text((8, 8), prompt[:240], fill=(10,10,10), font=font) | |
| except Exception: | |
| pass | |
| return img | |
| def generate_controlnet_image(self, image, prompt, reference_image=None, **kwargs): | |
| return self.generate_image(prompt, width=512, height=768) | |
| def cleanup(self): | |
| pass | |
| def move_models_to_cpu(self): | |
| pass | |
| def move_models_to_gpu(self): | |
| pass | |
| def force_reload_all_models(self): | |
| pass | |
| # 改进的全局状态管理 | |
| class DesignState: | |
| def __init__(self): | |
| self.reset() | |
| def reset(self): | |
| self.original_image = None | |
| self.image_caption = "" | |
| self.style_analysis = {} | |
| self.color_analysis = {} | |
| self.fabric_analysis = {} | |
| self.design_direction = "" | |
| self.design_concepts = [] | |
| self.generated_designs = [] | |
| self.generated_design_seeds = [] | |
| self.selected_design_index = -1 | |
| self.fitting_result = None | |
| self.fitting_multiview = [] | |
| def get_design_context(self): | |
| """获取完整的设计上下文,用于生成连贯的设计""" | |
| return { | |
| "caption": self.image_caption, | |
| "main_style": max(self.style_analysis.keys(), key=self.style_analysis.get) if self.style_analysis else "时尚", | |
| "style_scores": self.style_analysis, | |
| "dominant_colors": self.color_analysis.get("dominant_colors", []), | |
| "color_palette": self.color_analysis.get("color_palette", {}), | |
| "fabric_type": self.fabric_analysis.get("predicted_fabric", "棉质"), | |
| "texture": self.fabric_analysis.get("texture", "光滑"), | |
| "design_direction": self.design_direction | |
| } | |
| # 初始化模型管理器 | |
| if MODELS_AVAILABLE: | |
| try: | |
| model_manager = ModelManager() | |
| logger.info("使用完整模型管理器") | |
| except Exception as e: | |
| logger.error(f"初始化完整模型管理器失败: {e}") | |
| model_manager = SimpleModelManager() | |
| else: | |
| model_manager = SimpleModelManager() | |
| design_state = DesignState() | |
| def advanced_color_analysis(image): | |
| """高级颜色分析 - 提取颜色调色板和情感色彩""" | |
| try: | |
| from sklearn.cluster import KMeans | |
| # 调整图像大小 | |
| image = image.resize((150, 150)) | |
| img_array = np.array(image) | |
| pixels = img_array.reshape(-1, 3) | |
| # 使用KMeans提取主要颜色 | |
| kmeans = KMeans(n_clusters=5, random_state=42, n_init=10) | |
| kmeans.fit(pixels) | |
| colors = kmeans.cluster_centers_.astype(int) | |
| labels = kmeans.labels_ | |
| # 计算每种颜色的比例 | |
| color_percentages = [] | |
| for i in range(5): | |
| percentage = np.sum(labels == i) / len(labels) | |
| color_percentages.append(percentage) | |
| # 按比例排序 | |
| color_data = list(zip(colors, color_percentages)) | |
| color_data.sort(key=lambda x: x[1], reverse=True) | |
| # 生成颜色信息 | |
| dominant_colors = [] | |
| color_palette = {} | |
| for i, (color, percentage) in enumerate(color_data): | |
| color_name = rgb_to_detailed_color_name(color) | |
| color_emotion = get_color_emotion(color) | |
| dominant_colors.append(color_name) | |
| color_palette[f"颜色{i+1}"] = { | |
| "name": color_name, | |
| "rgb": color.tolist(), | |
| "hex": rgb_to_hex(color), | |
| "percentage": f"{percentage:.1%}", | |
| "emotion": color_emotion, | |
| "fashion_application": get_fashion_application(color_name) | |
| } | |
| return { | |
| "dominant_colors": dominant_colors[:3], # 前3种主要颜色 | |
| "color_palette": color_palette, | |
| "color_harmony": analyze_color_harmony(colors[:3]), | |
| "season_analysis": analyze_seasonal_colors(colors[:3]) | |
| } | |
| except Exception as e: | |
| logger.error(f"高级颜色分析失败: {e}") | |
| return { | |
| "dominant_colors": ["经典色调"], | |
| "color_palette": {"颜色1": {"name": "经典色调", "emotion": "中性"}}, | |
| "color_harmony": "单色调", | |
| "season_analysis": "四季通用" | |
| } | |
| def rgb_to_detailed_color_name(rgb): | |
| """更详细的RGB到颜色名称转换""" | |
| r, g, b = rgb | |
| # 转换到HSV空间进行更精确的颜色分类 | |
| h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0) | |
| h = h * 360 | |
| s = s * 100 | |
| v = v * 100 | |
| # 基于HSV值进行精确分类 | |
| if v < 20: | |
| return "深黑色" | |
| elif v > 90 and s < 10: | |
| return "纯白色" | |
| elif s < 15: | |
| if v < 30: | |
| return "深灰色" | |
| elif v < 70: | |
| return "中灰色" | |
| else: | |
| return "浅灰色" | |
| # 彩色分类 | |
| color_ranges = [ | |
| (0, 15, "深红色"), (15, 45, "橙红色"), (45, 75, "金黄色"), | |
| (75, 105, "草绿色"), (105, 135, "翠绿色"), (135, 165, "青绿色"), | |
| (165, 195, "天蓝色"), (195, 225, "宝蓝色"), (225, 255, "紫蓝色"), | |
| (255, 285, "紫色"), (285, 315, "紫红色"), (315, 345, "玫红色"), | |
| (345, 360, "深红色") | |
| ] | |
| for start, end, color_name in color_ranges: | |
| if start <= h < end: | |
| if v < 40: | |
| return f"深{color_name}" | |
| elif v > 80: | |
| return f"亮{color_name}" | |
| else: | |
| return color_name | |
| return "混合色调" | |
| def rgb_to_hex(rgb): | |
| """RGB转十六进制""" | |
| return "#{:02x}{:02x}{:02x}".format(int(rgb[0]), int(rgb[1]), int(rgb[2])) | |
| def get_color_emotion(rgb): | |
| """获取颜色的情感属性""" | |
| r, g, b = rgb | |
| # 基于颜色心理学的情感映射 | |
| if r > 180 and g < 100 and b < 100: | |
| return "热情、力量、激情" | |
| elif r < 100 and g > 150 and b < 100: | |
| return "自然、平静、成长" | |
| elif r < 100 and g < 100 and b > 150: | |
| return "专业、信任、稳定" | |
| elif r > 150 and g > 150 and b < 100: | |
| return "温暖、活力、创意" | |
| elif r > 100 and g < 100 and b > 150: | |
| return "神秘、高贵、优雅" | |
| elif r < 50 and g < 50 and b < 50: | |
| return "经典、正式、权威" | |
| elif r > 200 and g > 200 and b > 200: | |
| return "纯洁、简约、现代" | |
| else: | |
| return "平衡、和谐、中性" | |
| def get_fashion_application(color_name): | |
| """获取颜色在时尚中的应用建议""" | |
| applications = { | |
| "深红色": "晚装、正装细节、配饰", | |
| "橙红色": "夏季休闲、运动装、配饰", | |
| "金黄色": "夏季单品、配饰、装饰细节", | |
| "草绿色": "春夏装、休闲装、自然风格", | |
| "翠绿色": "春装、度假装、民族风格", | |
| "天蓝色": "衬衫、夏装、商务休闲", | |
| "宝蓝色": "正装、晚装、经典款式", | |
| "紫色": "晚装、艺术风格、个性单品", | |
| "深黑色": "基础款、正装、经典设计", | |
| "纯白色": "基础款、夏装、简约风格", | |
| "深灰色": "商务装、基础款、现代风格" | |
| } | |
| return applications.get(color_name, "通用时尚单品") | |
| def analyze_color_harmony(colors): | |
| """分析颜色和谐度""" | |
| if len(colors) < 2: | |
| return "单色调" | |
| # 转换为HSV进行分析 | |
| hsv_colors = [] | |
| for color in colors: | |
| h, s, v = colorsys.rgb_to_hsv(color[0]/255.0, color[1]/255.0, color[2]/255.0) | |
| hsv_colors.append((h*360, s*100, v*100)) | |
| h_values = [hsv[0] for hsv in hsv_colors] | |
| # 判断配色方案 | |
| h_diff = max(h_values) - min(h_values) | |
| if h_diff < 30: | |
| return "同色系配色" | |
| elif h_diff < 60: | |
| return "相邻色配色" | |
| elif 150 < h_diff < 210: | |
| return "对比色配色" | |
| else: | |
| return "多色调配色" | |
| def analyze_seasonal_colors(colors): | |
| """分析季节色彩倾向""" | |
| # 计算平均饱和度和明度 | |
| total_s, total_v = 0, 0 | |
| for color in colors: | |
| h, s, v = colorsys.rgb_to_hsv(color[0]/255.0, color[1]/255.0, color[2]/255.0) | |
| total_s += s | |
| total_v += v | |
| avg_s = total_s / len(colors) | |
| avg_v = total_v / len(colors) | |
| if avg_s > 0.6 and avg_v > 0.6: | |
| return "春季色彩(明亮、清新)" | |
| elif avg_s > 0.6 and avg_v < 0.6: | |
| return "秋季色彩(浓郁、温暖)" | |
| elif avg_s < 0.6 and avg_v > 0.6: | |
| return "夏季色彩(柔和、清淡)" | |
| else: | |
| return "冬季色彩(深沉、对比)" | |
| def analyze_fabric_texture(image): | |
| """分析面料和质地(基于图像特征)""" | |
| try: | |
| # 转换为灰度图进行纹理分析 | |
| gray_image = image.convert('L') | |
| img_array = np.array(gray_image) | |
| # 计算纹理特征 | |
| # 1. 计算标准差(纹理粗糙度) | |
| texture_variance = np.std(img_array) | |
| # 2. 计算边缘密度 | |
| from scipy import ndimage | |
| edges = ndimage.sobel(img_array) | |
| edge_density = np.mean(np.abs(edges)) | |
| # 基于特征推断面料类型 | |
| if texture_variance < 20: | |
| if edge_density < 10: | |
| fabric_type = "丝绸" | |
| texture = "光滑丝滑" | |
| else: | |
| fabric_type = "棉质" | |
| texture = "柔软光滑" | |
| elif texture_variance < 40: | |
| fabric_type = "混纺" | |
| texture = "适中质感" | |
| else: | |
| if edge_density > 30: | |
| fabric_type = "牛仔" | |
| texture = "粗糙硬挺" | |
| else: | |
| fabric_type = "毛呢" | |
| texture = "厚实温暖" | |
| return { | |
| "predicted_fabric": fabric_type, | |
| "texture": texture, | |
| "texture_score": texture_variance, | |
| "edge_score": edge_density, | |
| "fabric_properties": get_fabric_properties(fabric_type) | |
| } | |
| except Exception as e: | |
| logger.error(f"面料分析失败: {e}") | |
| return { | |
| "predicted_fabric": "棉质", | |
| "texture": "舒适", | |
| "fabric_properties": "透气、舒适、日常" | |
| } | |
| def get_fabric_properties(fabric_type): | |
| """获取面料特性""" | |
| properties = { | |
| "丝绸": "光泽感强、垂坠性好、高级感、适合正装", | |
| "棉质": "透气舒适、日常休闲、易打理、四季适用", | |
| "混纺": "结合优点、性价比高、适应性强、现代感", | |
| "牛仔": "硬挺耐用、休闲风格、经典时尚、年轻活力", | |
| "毛呢": "保暖性好、正式高级、秋冬首选、商务感强" | |
| } | |
| return properties.get(fabric_type, "舒适实用") | |
| def comprehensive_image_analysis(image_path, progress=gr.Progress()): | |
| """综合图像分析 - 整合所有分析维度""" | |
| try: | |
| design_state.reset() | |
| if image_path is None: | |
| return {}, {}, gr.Radio(choices=[]), gr.Gallery(value=[]) | |
| progress(0.05, desc="加载图片...") | |
| image = Image.open(image_path).convert('RGB') | |
| design_state.original_image = image | |
| # 1. BLIP图像描述 | |
| progress(0.15, desc="AI图像理解中...") | |
| try: | |
| caption = model_manager.generate_caption(image) | |
| design_state.image_caption = caption | |
| logger.info(f"BLIP描述: {caption}") | |
| except Exception as e: | |
| logger.error(f"图像描述生成失败: {e}") | |
| caption = "时尚服装设计作品" | |
| design_state.image_caption = caption | |
| # 2. CLIP风格分析 | |
| progress(0.3, desc="AI风格识别中...") | |
| try: | |
| style_scores = model_manager.analyze_style(image) | |
| design_state.style_analysis = style_scores | |
| logger.info(f"风格分析: {style_scores}") | |
| except Exception as e: | |
| logger.error(f"风格分析失败: {e}") | |
| style_scores = {"时尚潮流": 0.8, "现代风格": 0.6} | |
| design_state.style_analysis = style_scores | |
| # 3. 高级颜色分析 | |
| progress(0.5, desc="深度颜色分析中...") | |
| color_analysis = advanced_color_analysis(image) | |
| design_state.color_analysis = color_analysis | |
| # 4. 面料质地分析 | |
| progress(0.7, desc="面料质地分析中...") | |
| fabric_analysis = analyze_fabric_texture(image) | |
| design_state.fabric_analysis = fabric_analysis | |
| # 5. 生成综合分析报告 | |
| progress(0.85, desc="生成分析报告...") | |
| comprehensive_analysis = { | |
| "基础信息": { | |
| "图像描述": caption, | |
| "图像尺寸": f"{image.width} x {image.height}", | |
| "分析时间": time.strftime("%Y-%m-%d %H:%M:%S") | |
| }, | |
| "风格分析": { | |
| "主要风格": max(style_scores.keys(), key=style_scores.get), | |
| "风格置信度": f"{max(style_scores.values()):.1%}", | |
| "所有风格评分": {k: f"{v:.1%}" for k, v in sorted(style_scores.items(), key=lambda x: x[1], reverse=True)} | |
| }, | |
| "颜色分析": { | |
| "主色调": color_analysis["dominant_colors"][0] if color_analysis["dominant_colors"] else "经典色调", | |
| "配色方案": color_analysis["color_harmony"], | |
| "季节倾向": color_analysis["season_analysis"], | |
| "颜色情感": color_analysis["color_palette"].get("颜色1", {}).get("emotion", "中性") | |
| }, | |
| "材质分析": { | |
| "预测面料": fabric_analysis["predicted_fabric"], | |
| "质地特征": fabric_analysis["texture"], | |
| "面料特性": fabric_analysis["fabric_properties"] | |
| } | |
| } | |
| # 6. 基于综合分析生成设计建议 | |
| design_suggestions = generate_intelligent_suggestions() | |
| progress(1.0, desc="分析完成") | |
| choices = list(design_suggestions.keys()) | |
| return ( | |
| comprehensive_analysis, | |
| design_suggestions, | |
| gr.Radio(choices=choices, value=choices[0] if choices else None), | |
| gr.Gallery(value=[]) | |
| ) | |
| except Exception as e: | |
| logger.error(f"综合分析失败: {e}", exc_info=True) | |
| return {"错误": f"分析失败: {str(e)}"}, {}, gr.Radio(choices=[]), gr.Gallery(value=[]) | |
| def generate_intelligent_suggestions(): | |
| """基于所有分析维度生成智能设计建议""" | |
| context = design_state.get_design_context() | |
| # 获取关键信息 | |
| main_style = context["main_style"] | |
| dominant_color = context["dominant_colors"][0] if context["dominant_colors"] else "经典色调" | |
| fabric_type = context["fabric_type"] | |
| color_emotion = design_state.color_analysis.get("color_palette", {}).get("颜色1", {}).get("emotion", "中性") | |
| # 基于综合分析生成建议 | |
| suggestions = {} | |
| # 1. 风格延续建议 | |
| suggestions[f"经典{main_style}"] = f"保持{main_style}核心特色,运用{dominant_color}主色调,体现{color_emotion}的情感表达" | |
| # 2. 材质创新建议 | |
| suggestions[f"{fabric_type}质感创新"] = f"基于{fabric_type}面料特性,结合{dominant_color}配色,打造现代{main_style}风格" | |
| # 3. 配色方案建议 | |
| color_harmony = design_state.color_analysis.get("color_harmony", "和谐配色") | |
| suggestions[f"{color_harmony}设计"] = f"采用{color_harmony}策略,以{dominant_color}为主调,营造{color_emotion}氛围" | |
| # 4. 季节适应建议 | |
| season_analysis = design_state.color_analysis.get("season_analysis", "四季通用") | |
| suggestions[f"{season_analysis}款式"] = f"针对{season_analysis}特点,融合{main_style}元素,突出{fabric_type}质感" | |
| # 5. 情感导向建议 | |
| suggestions[f"{color_emotion}表达"] = f"强化{color_emotion}的情感传达,通过{main_style}剪裁体现{fabric_type}的独特魅力" | |
| # 6. 创新融合建议 | |
| suggestions["跨界融合创新"] = f"打破传统{main_style}界限,创新运用{dominant_color},结合现代设计理念" | |
| return suggestions | |
| def generate_professional_designs(selected_suggestion, progress=gr.Progress()): | |
| """生成专业服装设计图 - 三视图风格(改进版)""" | |
| try: | |
| if not selected_suggestion or not design_state.original_image: | |
| return gr.Gallery(value=[]), gr.Radio(choices=[]) | |
| design_state.design_direction = selected_suggestion | |
| progress(0.1, desc="准备设计生成...") | |
| # 获取完整设计上下文 | |
| context = design_state.get_design_context() | |
| # 生成三种专业设计视图 | |
| design_views = ["正面设计图", "背面设计图", "侧面设计图"] | |
| generated_designs = [] | |
| design_choices = [] | |
| for i, view in enumerate(design_views): | |
| try: | |
| progress(0.2 + i*0.25, desc=f"生成{view}...") | |
| # 创建专业的设计提示词 | |
| # 使用基于 suggestion 的 seed 保证三视图一致 | |
| base_seed = abs(hash(selected_suggestion)) % (2 ** 31 - 1) | |
| view_seed = (base_seed + i * 9973) % (2 ** 31 - 1) | |
| design_prompt = create_professional_design_prompt(view, context, selected_suggestion) | |
| # 使用SD模型生成设计 | |
| design_image = model_manager.generate_image( | |
| prompt=design_prompt, | |
| negative_prompt="person, face, model, background, blurry, low quality, text, watermark, realistic photo, 3d render", | |
| num_inference_steps=30, | |
| width=512, | |
| height=640, | |
| guidance_scale=8.0, | |
| seed=view_seed | |
| ) | |
| generated_designs.append(design_image) | |
| design_choices.append(f"{selected_suggestion} - {view}") | |
| logger.info(f"成功生成{view}") | |
| except Exception as e: | |
| logger.error(f"生成{view}失败: {e}") | |
| # 创建占位图像 | |
| placeholder = create_design_placeholder(view, 512, 640) | |
| generated_designs.append(placeholder) | |
| design_choices.append(f"{selected_suggestion} - {view} (占位)") | |
| design_state.generated_designs = generated_designs | |
| progress(1.0, desc="设计生成完成") | |
| return ( | |
| gr.Gallery(value=generated_designs, columns=3), | |
| gr.Radio(choices=design_choices, value=design_choices[0] if design_choices else None) | |
| ) | |
| except Exception as e: | |
| logger.error(f"专业设计生成失败: {e}") | |
| return gr.Gallery(value=[]), gr.Radio(choices=[]) | |
| def create_professional_design_prompt(view, context, suggestion): | |
| """创建专业的服装设计提示词 - 避免token截断""" | |
| # 关键词映射,避免中文token问题 | |
| style_keywords = { | |
| "商务正装": "business formal suit professional", | |
| "休闲风": "casual comfortable relaxed", | |
| "运动风": "sportswear athletic active", | |
| "时尚潮流": "fashion trendy modern stylish", | |
| "复古风": "vintage retro classic", | |
| "街头风": "streetwear urban hip", | |
| "优雅风": "elegant sophisticated graceful" | |
| } | |
| color_keywords = { | |
| "深红色": "deep red burgundy", | |
| "橙红色": "orange red coral", | |
| "金黄色": "golden yellow amber", | |
| "草绿色": "grass green olive", | |
| "翠绿色": "emerald green jade", | |
| "天蓝色": "sky blue azure", | |
| "宝蓝色": "royal blue navy", | |
| "紫色": "purple violet", | |
| "深黑色": "deep black charcoal", | |
| "纯白色": "pure white ivory", | |
| "深灰色": "dark gray slate" | |
| } | |
| fabric_keywords = { | |
| "丝绸": "silk smooth luxurious", | |
| "棉质": "cotton comfortable breathable", | |
| "混纺": "blend modern synthetic", | |
| "牛仔": "denim sturdy casual", | |
| "毛呢": "wool warm textured" | |
| } | |
| view_keywords = { | |
| "正面设计图": "front view technical drawing fashion flat", | |
| "背面设计图": "back view technical drawing fashion flat", | |
| "侧面设计图": "side view technical drawing fashion flat" | |
| } | |
| # 构建英文提示词 | |
| style_eng = style_keywords.get(context["main_style"], "modern fashion") | |
| color_eng = color_keywords.get(context["dominant_colors"][0] if context["dominant_colors"] else "", "neutral colors") | |
| fabric_eng = fabric_keywords.get(context["fabric_type"], "quality fabric") | |
| view_eng = view_keywords.get(view, "technical fashion drawing") | |
| # 专业服装设计提示词 | |
| prompt = ( | |
| f"{view_eng}, {style_eng} garment design, " | |
| f"{color_eng} color scheme, {fabric_eng} material, " | |
| f"clean fashion illustration, professional technical drawing, " | |
| f"flat lay design, no model, clothing only, " | |
| f"detailed stitching, precise proportions, " | |
| f"fashion design sketch, minimalist background, " | |
| f"high quality illustration, vector style" | |
| ) | |
| logger.info(f"{view}设计提示词: {prompt}") | |
| return prompt | |
| def create_design_placeholder(view, width, height): | |
| """创建设计占位图""" | |
| img = Image.new('RGB', (width, height), color=(240, 240, 240)) | |
| draw = ImageDraw.Draw(img) | |
| # 绘制基本轮廓 | |
| if "正面" in view: | |
| # 画一个基本的衣服正面轮廓 | |
| draw.rectangle([width//4, height//6, 3*width//4, 5*height//6], outline=(100, 100, 100), width=3) | |
| elif "背面" in view: | |
| # 画一个基本的衣服背面轮廓 | |
| draw.rectangle([width//4, height//6, 3*width//4, 5*height//6], outline=(120, 120, 120), width=3) | |
| else: | |
| # 侧面轮廓 | |
| draw.ellipse([width//3, height//6, 2*width//3, 5*height//6], outline=(140, 140, 140), width=3) | |
| # 添加文字 | |
| try: | |
| font = ImageFont.load_default() | |
| text = view | |
| draw.text((width//2-50, height//2), text, fill=(80, 80, 80), font=font) | |
| except: | |
| pass | |
| return img | |
| def generate_3d_fitting_effect(selected_design_index, progress=gr.Progress()): | |
| """生成专业3D试穿效果 - 标准模特展示""" | |
| try: | |
| if not design_state.generated_designs or selected_design_index is None: | |
| return None | |
| design_state.selected_design_index = selected_design_index | |
| progress(0.1, desc="准备3D建模...") | |
| # 获取设计上下文和选中的设计 | |
| context = design_state.get_design_context() | |
| selected_design = design_state.generated_designs[selected_design_index] | |
| progress(0.3, desc="构建3D试穿场景...") | |
| # 创建专业3D试穿提示词 | |
| fitting_prompt = create_3d_fitting_prompt(context, selected_design_index) | |
| progress(0.5, desc="AI 3D渲染中...") | |
| try: | |
| # 使用ControlNet生成高质量3D试穿效果 | |
| fitting_image = model_manager.generate_controlnet_image( | |
| image=design_state.original_image, | |
| prompt=fitting_prompt, | |
| reference_image=selected_design, | |
| negative_prompt="blurry, distorted, low quality, unrealistic, extra limbs, deformed, bad anatomy, text, watermark, multiple people", | |
| num_inference_steps=40, | |
| guidance_scale=8.5 | |
| ) | |
| progress(0.9, desc="完成3D渲染") | |
| design_state.fitting_result = fitting_image | |
| logger.info("使用ControlNet生成3D试穿效果") | |
| return fitting_image | |
| except Exception as e: | |
| logger.warning(f"ControlNet 3D试穿失败: {e}") | |
| # 回退到标准模型 | |
| progress(0.6, desc="使用标准模型生成...") | |
| fitting_image = model_manager.generate_image( | |
| prompt=fitting_prompt, | |
| negative_prompt="blurry, distorted, low quality, unrealistic, extra limbs, deformed, bad anatomy, multiple people", | |
| num_inference_steps=35, | |
| width=512, | |
| height=768, | |
| guidance_scale=8.0 | |
| ) | |
| progress(0.9, desc="完成渲染") | |
| design_state.fitting_result = fitting_image | |
| return fitting_image | |
| except Exception as e: | |
| logger.error(f"3D试穿生成失败: {e}") | |
| return create_fitting_placeholder() | |
| def create_3d_fitting_prompt(context, design_index): | |
| """创建3D试穿提示词 - 英文避免token截断""" | |
| # 风格关键词映射 | |
| style_keywords = { | |
| "商务正装": "professional business attire formal suit", | |
| "休闲风": "casual comfortable everyday wear", | |
| "运动风": "athletic sportswear activewear", | |
| "时尚潮流": "fashion forward trendy modern", | |
| "复古风": "vintage retro classic style", | |
| "街头风": "streetwear urban contemporary", | |
| "优雅风": "elegant sophisticated refined" | |
| } | |
| color_keywords = { | |
| "深红色": "deep red burgundy rich", | |
| "橙红色": "coral orange warm", | |
| "金黄色": "golden amber bright", | |
| "草绿色": "olive green natural", | |
| "翠绿色": "emerald jade vibrant", | |
| "天蓝色": "sky blue light", | |
| "宝蓝色": "royal navy deep", | |
| "紫色": "purple violet", | |
| "深黑色": "black charcoal dark", | |
| "纯白色": "white clean pure", | |
| "深灰色": "charcoal slate gray" | |
| } | |
| fabric_keywords = { | |
| "丝绸": "silk luxurious smooth draping", | |
| "棉质": "cotton comfortable natural texture", | |
| "混纺": "modern blend synthetic comfort", | |
| "牛仔": "denim sturdy casual texture", | |
| "毛呢": "wool textured warm sophisticated" | |
| } | |
| # 获取英文关键词 | |
| style_eng = style_keywords.get(context["main_style"], "modern fashion") | |
| color_eng = color_keywords.get(context["dominant_colors"][0] if context["dominant_colors"] else "", "neutral tones") | |
| fabric_eng = fabric_keywords.get(context["fabric_type"], "quality fabric") | |
| # 构建3D试穿提示词 | |
| prompt = ( | |
| f"professional 3D fashion model wearing {style_eng}, " | |
| f"{color_eng} color scheme, {fabric_eng} material, " | |
| f"full body pose, studio lighting, clean background, " | |
| f"high quality 3D render, realistic fabric texture, " | |
| f"perfect fit tailoring, fashion photography style, " | |
| f"detailed clothing construction, professional modeling" | |
| ) | |
| logger.info(f"3D试穿提示词: {prompt}") | |
| return prompt | |
| def create_fitting_placeholder(): | |
| """创建3D试穿占位图""" | |
| img = Image.new('RGB', (512, 768), color=(245, 245, 245)) | |
| draw = ImageDraw.Draw(img) | |
| # 画一个基本的人体轮廓 | |
| # 头部 | |
| draw.ellipse([206, 50, 306, 150], outline=(150, 150, 150), width=2) | |
| # 身体 | |
| draw.rectangle([226, 150, 286, 400], outline=(150, 150, 150), width=2) | |
| # 手臂 | |
| draw.rectangle([186, 170, 226, 350], outline=(150, 150, 150), width=2) | |
| draw.rectangle([286, 170, 326, 350], outline=(150, 150, 150), width=2) | |
| # 腿部 | |
| draw.rectangle([236, 400, 266, 650], outline=(150, 150, 150), width=2) | |
| draw.rectangle([266, 400, 296, 650], outline=(150, 150, 150), width=2) | |
| # 添加文字 | |
| try: | |
| font = ImageFont.load_default() | |
| draw.text((200, 380), "3D Fitting", fill=(100, 100, 100), font=font) | |
| except: | |
| pass | |
| return img | |
| def export_design_report(): | |
| """导出完整的设计报告""" | |
| if not design_state.original_image: | |
| return "没有设计数据可导出" | |
| try: | |
| context = design_state.get_design_context() | |
| report = { | |
| "设计项目报告": { | |
| "生成时间": time.strftime("%Y-%m-%d %H:%M:%S"), | |
| "项目概述": { | |
| "设计描述": context["caption"], | |
| "设计方向": context["design_direction"], | |
| "主要风格": context["main_style"] | |
| }, | |
| "色彩分析": { | |
| "主色调": context["dominant_colors"], | |
| "配色方案": design_state.color_analysis.get("color_harmony", ""), | |
| "季节特征": design_state.color_analysis.get("season_analysis", ""), | |
| "情感表达": design_state.color_analysis.get("color_palette", {}).get("颜色1", {}).get("emotion", "") | |
| }, | |
| "材质分析": { | |
| "面料类型": context["fabric_type"], | |
| "质地特征": design_state.fabric_analysis.get("texture", ""), | |
| "材质特性": design_state.fabric_analysis.get("fabric_properties", "") | |
| }, | |
| "设计建议": { | |
| "选择方向": design_state.design_direction, | |
| "设计理念": f"基于{context['main_style']}风格,运用{context['dominant_colors'][0] if context['dominant_colors'] else '经典'}色调" | |
| } | |
| } | |
| } | |
| return json.dumps(report, ensure_ascii=False, indent=2) | |
| except Exception as e: | |
| return f"报告生成失败: {str(e)}" | |
| def create_gradio_interface(): | |
| """创建改进的Gradio界面""" | |
| with gr.Blocks(title="AI时尚设计师 Pro", theme="soft") as demo: | |
| gr.Markdown("# 🎨 AI时尚设计师 Pro") | |
| gr.Markdown("**专业AI驱动的服装设计平台** - 深度分析、智能设计、3D试穿") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| image_input = gr.Image(type="filepath", label="📸 上传服装参考图", height=400) | |
| analyze_btn = gr.Button("🔍 AI深度分析", variant="primary", size="lg") | |
| # 分析结果展示 | |
| with gr.Accordion("📊 详细分析报告", open=False): | |
| analysis_output = gr.JSON(label="综合分析结果") | |
| with gr.Column(scale=2): | |
| # 设计建议标签页 | |
| with gr.Tab("💡 智能设计建议"): | |
| suggestions_output = gr.JSON(label="🎯 基于AI分析的个性化建议") | |
| suggestion_choice = gr.Radio(label="🎨 选择设计方向", interactive=True) | |
| generate_designs_btn = gr.Button("✨ 生成专业设计图", variant="primary", size="lg") | |
| # 设计图标签页 | |
| with gr.Tab("👔 专业设计图"): | |
| gr.Markdown("**服装设计三视图** - 正面/背面/侧面专业技术图") | |
| designs_gallery = gr.Gallery(label="AI生成的专业设计图", columns=3, height=500) | |
| design_choice = gr.Radio(label="🎯 选择设计方案", type="index", interactive=True) | |
| generate_3d_btn = gr.Button("🎭 生成3D试穿效果", variant="primary", size="lg") | |
| # 3D试穿标签页 | |
| with gr.Tab("🎭 3D虚拟试穿"): | |
| gr.Markdown("**专业3D试穿展示** - 标准模特效果图") | |
| fitting_result = gr.Image(label="3D虚拟试穿效果", height=600) | |
| with gr.Row(): | |
| export_btn = gr.Button("📄 导出设计报告", variant="secondary") | |
| reset_btn = gr.Button("🔄 重置项目", variant="secondary") | |
| # 导出结果 | |
| with gr.Tab("📋 设计报告"): | |
| report_output = gr.Textbox(label="完整设计报告", lines=20, max_lines=30) | |
| # 系统控制面板 | |
| with gr.Accordion("🔧 系统控制面板", open=False): | |
| with gr.Row(): | |
| cleanup_btn = gr.Button("🧹 清理显存", variant="secondary") | |
| cpu_btn = gr.Button("💾 模型→CPU", variant="secondary") | |
| gpu_btn = gr.Button("🚀 模型→GPU", variant="secondary") | |
| reload_btn = gr.Button("🔄 重载模型", variant="primary") | |
| gr.Markdown(""" | |
| **系统优化说明**: | |
| - 🧹 清理显存:清理GPU缓存,不影响模型 | |
| - 💾 模型→CPU:释放GPU显存,推理速度会降低 | |
| - 🚀 模型→GPU:恢复GPU加速,提升生成速度 | |
| - 🔄 重载模型:强制重新加载所有AI模型 | |
| """) | |
| # 事件绑定 - 完整工作流程 | |
| analyze_btn.click( | |
| fn=comprehensive_image_analysis, | |
| inputs=[image_input], | |
| outputs=[analysis_output, suggestions_output, suggestion_choice, designs_gallery] | |
| ) | |
| generate_designs_btn.click( | |
| fn=generate_professional_designs, | |
| inputs=[suggestion_choice], | |
| outputs=[designs_gallery, design_choice] | |
| ) | |
| generate_3d_btn.click( | |
| fn=generate_3d_fitting_effect, | |
| inputs=[design_choice], | |
| outputs=[fitting_result] | |
| ) | |
| export_btn.click( | |
| fn=export_design_report, | |
| inputs=[], | |
| outputs=[report_output] | |
| ) | |
| reset_btn.click( | |
| fn=lambda: (design_state.reset(), {}, {}, gr.Radio(choices=[]), gr.Gallery(value=[]), None, ""), | |
| inputs=[], | |
| outputs=[analysis_output, suggestions_output, suggestion_choice, designs_gallery, fitting_result, report_output] | |
| ) | |
| # 系统控制 | |
| cleanup_btn.click(fn=model_manager.cleanup, inputs=[], outputs=[]) | |
| cpu_btn.click(fn=model_manager.move_models_to_cpu, inputs=[], outputs=[]) | |
| gpu_btn.click(fn=model_manager.move_models_to_gpu, inputs=[], outputs=[]) | |
| reload_btn.click(fn=model_manager.force_reload_all_models, inputs=[], outputs=[]) | |
| # 使用指南 | |
| with gr.Accordion("📖 专业使用指南", open=False): | |
| gr.Markdown(""" | |
| ## 🚀 完整工作流程 | |
| ### 第一步:AI深度分析 | |
| 1. 上传高清服装参考图片 | |
| 2. 点击"AI深度分析"进行多维度智能分析 | |
| 3. 查看详细的风格、颜色、材质分析报告 | |
| ### 第二步:选择设计方向 | |
| 1. 在"智能设计建议"中查看个性化建议 | |
| 2. 基于AI分析结果选择最符合需求的设计方向 | |
| 3. 建议会整合风格、色彩、材质等所有分析维度 | |
| ### 第三步:生成专业设计 | |
| 1. 点击"生成专业设计图"获取三视图 | |
| 2. 包含正面、背面、侧面的专业技术图 | |
| 3. 所有设计都基于前期分析结果,确保一致性 | |
| ### 第四步:3D虚拟试穿 | |
| 1. 选择心仪的设计方案 | |
| 2. 生成标准模特的3D试穿效果 | |
| 3. 展示真实的着装效果和服装细节 | |
| ### 第五步:导出设计报告 | |
| 1. 获取完整的项目设计报告 | |
| 2. 包含所有分析数据和设计决策依据 | |
| 3. 支持进一步的设计开发和制作 | |
| ## 💡 专业建议 | |
| - **图片质量**:使用高分辨率、光线良好的服装图片 | |
| - **分析准确性**:让AI完整分析后再进行设计选择 | |
| - **设计连贯性**:所有生成内容都基于初始分析,确保风格统一 | |
| - **3D效果**:基于ControlNet技术,提供专业级试穿展示 | |
| """) | |
| return demo | |
| if __name__ == "__main__": | |
| logger.info(f"Python版本: {sys.version}") | |
| logger.info(f"当前工作目录: {os.getcwd()}") | |
| logger.info(f"模型管理器状态: {'完整版' if MODELS_AVAILABLE else '简化版'}") | |
| demo = create_gradio_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True, | |
| max_threads=4 # 增加线程数支持并发 | |
| ) | |