File size: 7,439 Bytes
96530e2
677723b
2a1df8f
 
98ea845
677723b
96530e2
677723b
2a1df8f
98ea845
 
 
677723b
98ea845
 
 
677723b
98ea845
 
 
677723b
98ea845
 
 
 
 
 
96530e2
98ea845
 
677723b
98ea845
677723b
 
98ea845
 
677723b
98ea845
 
2a1df8f
677723b
 
 
 
 
 
2a1df8f
98ea845
 
677723b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98ea845
677723b
 
98ea845
677723b
98ea845
677723b
 
98ea845
 
 
677723b
 
 
 
 
 
 
 
98ea845
677723b
 
 
 
 
 
 
 
 
 
2a1df8f
98ea845
5662266
677723b
 
 
 
 
 
 
 
2a1df8f
98ea845
677723b
2a1df8f
 
98ea845
 
677723b
98ea845
2a1df8f
 
 
677723b
 
 
 
2a1df8f
 
98ea845
677723b
 
98ea845
 
 
677723b
 
2a1df8f
 
677723b
2a1df8f
 
677723b
98ea845
677723b
 
 
2a1df8f
677723b
 
 
 
 
2a1df8f
677723b
 
2a1df8f
98ea845
2a1df8f
677723b
2a1df8f
 
 
 
 
 
 
 
 
 
 
98ea845
677723b
 
2a1df8f
98ea845
677723b
2a1df8f
677723b
98ea845
677723b
 
2a1df8f
 
 
5662266
2a1df8f
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import gradio as gr
from PIL import Image, ImageDraw
import numpy as np
from sklearn.cluster import KMeans
import random
import colorsys

class LocalStyler:
    def __init__(self):
        self.style_patterns = {
            "Casual": {
                "colors": ["#4A90E2", "#58B957", "#F5A623", "#D0021B"],
                "patterns": ["solid", "stripes", "dots"]
            },
            "Formal": {
                "colors": ["#000000", "#1A237E", "#212121", "#37474F"],
                "patterns": ["solid", "pinstripe", "subtle"]
            },
            "Sporty": {
                "colors": ["#FF5722", "#2196F3", "#4CAF50", "#FFC107"],
                "patterns": ["colorblock", "geometric", "tech"]
            },
            "Bohemian": {
                "colors": ["#795548", "#FF9800", "#9C27B0", "#009688"],
                "patterns": ["floral", "paisley", "ethnic"]
            }
        }

    def extract_dominant_colors(self, image, n_colors=5):
        """Extract dominant colors from the image."""
        # Convert image to numpy array
        img_array = np.array(image)
        
        # Reshape the array to a list of pixels
        pixels = img_array.reshape(-1, 3)
        
        # Perform k-means clustering
        kmeans = KMeans(n_clusters=n_colors, random_state=42)
        kmeans.fit(pixels)
        
        # Get the RGB values of the cluster centers
        colors = kmeans.cluster_centers_.astype(int)
        
        # Convert to hex codes
        hex_colors = ['#{:02x}{:02x}{:02x}'.format(r, g, b) 
                     for r, g, b in colors]
        
        return hex_colors

    def create_pattern(self, draw, width, height, pattern_type, color):
        """Create pattern on the image."""
        if pattern_type == "stripes":
            for y in range(0, height, 20):
                draw.line([(0, y), (width, y)], fill='white', width=2)
        elif pattern_type == "dots":
            for x in range(0, width, 30):
                for y in range(0, height, 30):
                    draw.ellipse([x, y, x+10, y+10], fill='white')
        elif pattern_type == "geometric":
            for i in range(0, width, 50):
                draw.polygon([
                    (i, 0),
                    (i+50, 0),
                    (i+25, 50)
                ], fill=self.adjust_color(color))
        elif pattern_type == "colorblock":
            draw.rectangle([0, 0, width//2, height], fill=self.adjust_color(color))

    def adjust_color(self, hex_color):
        """Adjust color brightness."""
        # Convert hex to RGB
        hex_color = hex_color.lstrip('#')
        r, g, b = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
        
        # Convert to HSV
        h, s, v = colorsys.rgb_to_hsv(r/255, g/255, b/255)
        
        # Adjust brightness
        v = min(1.0, v * 1.2)
        
        # Convert back to RGB
        r, g, b = colorsys.hsv_to_rgb(h, s, v)
        
        # Convert to hex
        return '#{:02x}{:02x}{:02x}'.format(int(r*255), int(g*255), int(b*255))

    def generate_styled_image(self, original_image, style, color_preference):
        """Generate a styled version of the clothing item."""
        # Get base width and height
        width, height = 512, 512
        
        # Create base image
        styled_image = Image.new('RGB', (width, height), color='white')
        draw = ImageDraw.Draw(styled_image)
        
        # Get style information
        style_info = self.style_patterns[style]
        main_color = random.choice(style_info["colors"])
        pattern = random.choice(style_info["patterns"])
        
        # Draw basic clothing shape
        clothing_points = [
            (width//4, height//4),
            (3*width//4, height//4),
            (3*width//4, 3*height//4),
            (width//4, 3*height//4)
        ]
        draw.polygon(clothing_points, fill=main_color)
        
        # Add pattern
        self.create_pattern(draw, width, height, pattern, main_color)
        
        # Add some shading for depth
        shade_color = self.adjust_color(main_color)
        draw.polygon([
            (width//4, height//4),
            (width//3, height//3),
            (width//4, height//2)
        ], fill=shade_color)
        
        return styled_image

    def analyze_colors(self, image):
        """Analyze the color composition of the image."""
        colors = self.extract_dominant_colors(image)
        return {
            "dominant_colors": colors,
            "color_scheme": "Warm" if any("FF" in c or "E2" in c for c in colors) else "Cool"
        }

def create_interface():
    """Create the Gradio interface."""
    styler = LocalStyler()
    
    with gr.Blocks(theme=gr.themes.Soft()) as demo:
        gr.Markdown("""
        # AI Fashion Stylist
        Upload your clothing item for color analysis and style suggestions!
        """)
        
        with gr.Row():
            with gr.Column(scale=1):
                input_image = gr.Image(
                    type="pil",
                    label="Upload Clothing Image"
                )
                with gr.Row():
                    style_dropdown = gr.Dropdown(
                        choices=list(styler.style_patterns.keys()),
                        label="Desired Style",
                        value="Casual"
                    )
                    color_dropdown = gr.Dropdown(
                        choices=["Warm", "Cool", "Neutral", "Bold"],
                        label="Color Preference",
                        value="Warm"
                    )
                
                generate_button = gr.Button("Generate Style", variant="primary")
            
            with gr.Column(scale=1):
                color_analysis = gr.JSON(label="Color Analysis")
                color_palette = gr.HTML(label="Color Palette")
                styled_image_output = gr.Image(label="Style Suggestion")
                
        def process_and_generate(image, style, color_pref):
            if image is None:
                return (
                    {"error": "Please upload an image"},
                    "No color palette available",
                    None
                )
            
            # Analyze colors
            color_analysis = styler.analyze_colors(image)
            
            # Generate color palette HTML
            color_html = "<div style='display: flex; gap: 10px; margin: 10px 0;'>"
            for color in color_analysis["dominant_colors"]:
                color_html += f"""
                    <div style='
                        width: 50px;
                        height: 50px;
                        background-color: {color};
                        border: 1px solid #ccc;
                        border-radius: 5px;
                    '></div>
                """
            color_html += "</div>"
            
            # Generate styled image
            styled_image = styler.generate_styled_image(
                image, style, color_pref
            )
            
            return color_analysis, color_html, styled_image
        
        generate_button.click(
            fn=process_and_generate,
            inputs=[input_image, style_dropdown, color_dropdown],
            outputs=[color_analysis, color_palette, styled_image_output]
        )
    
    return demo

if __name__ == "__main__":
    demo = create_interface()
    demo.launch()