|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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__) |
|
|
|
|
|
|
|
|
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(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], |
|
|
"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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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_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) |
|
|
|
|
|
|
|
|
|
|
|
texture_variance = np.std(img_array) |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
progress(0.5, desc="深度颜色分析中...") |
|
|
color_analysis = advanced_color_analysis(image) |
|
|
design_state.color_analysis = color_analysis |
|
|
|
|
|
|
|
|
progress(0.7, desc="面料质地分析中...") |
|
|
fabric_analysis = analyze_fabric_texture(image) |
|
|
design_state.fabric_analysis = fabric_analysis |
|
|
|
|
|
|
|
|
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"] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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 = {} |
|
|
|
|
|
|
|
|
suggestions[f"经典{main_style}"] = f"保持{main_style}核心特色,运用{dominant_color}主色调,体现{color_emotion}的情感表达" |
|
|
|
|
|
|
|
|
suggestions[f"{fabric_type}质感创新"] = f"基于{fabric_type}面料特性,结合{dominant_color}配色,打造现代{main_style}风格" |
|
|
|
|
|
|
|
|
color_harmony = design_state.color_analysis.get("color_harmony", "和谐配色") |
|
|
suggestions[f"{color_harmony}设计"] = f"采用{color_harmony}策略,以{dominant_color}为主调,营造{color_emotion}氛围" |
|
|
|
|
|
|
|
|
season_analysis = design_state.color_analysis.get("season_analysis", "四季通用") |
|
|
suggestions[f"{season_analysis}款式"] = f"针对{season_analysis}特点,融合{main_style}元素,突出{fabric_type}质感" |
|
|
|
|
|
|
|
|
suggestions[f"{color_emotion}表达"] = f"强化{color_emotion}的情感传达,通过{main_style}剪裁体现{fabric_type}的独特魅力" |
|
|
|
|
|
|
|
|
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}...") |
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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截断""" |
|
|
|
|
|
|
|
|
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试穿场景...") |
|
|
|
|
|
|
|
|
fitting_prompt = create_3d_fitting_prompt(context, selected_design_index) |
|
|
|
|
|
progress(0.5, desc="AI 3D渲染中...") |
|
|
|
|
|
try: |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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 |
|
|
) |
|
|
|