kish613 commited on
Commit
ee98fce
Β·
verified Β·
1 Parent(s): 7764d78

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +347 -0
app.py ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import io
4
+ import base64
5
+ import time
6
+ from PIL import Image
7
+ import numpy as np
8
+
9
+ # Advanced structure-preserving models with different capabilities
10
+ STRUCTURE_PRESERVING_MODELS = [
11
+ {
12
+ "name": "FLUX.1-dev ControlNet Union Pro",
13
+ "model_id": "Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro-2.0",
14
+ "description": "Advanced ControlNet with multiple control types for precise structure preservation",
15
+ "supports_controlnet": True
16
+ },
17
+ {
18
+ "name": "ControlNet Room Segmentation",
19
+ "model_id": "BertChristiaens/controlnet-seg-room",
20
+ "description": "Specialized for interior design with room segmentation",
21
+ "supports_controlnet": True
22
+ },
23
+ {
24
+ "name": "FLUX.1 ControlNet Union",
25
+ "model_id": "InstantX/FLUX.1-dev-Controlnet-Union",
26
+ "description": "High-quality ControlNet for structure preservation",
27
+ "supports_controlnet": True
28
+ },
29
+ {
30
+ "name": "Stable Diffusion Depth Img2Img",
31
+ "model_id": "radames/stable-diffusion-2-depth-img2img",
32
+ "description": "Uses depth information for structure preservation",
33
+ "supports_controlnet": False
34
+ },
35
+ {
36
+ "name": "Stable Diffusion v1.5 Img2Img",
37
+ "model_id": "radames/stable-diffusion-v1-5-img2img",
38
+ "description": "Reliable image-to-image transformation",
39
+ "supports_controlnet": False
40
+ },
41
+ {
42
+ "name": "FLUX.1-dev (Fallback)",
43
+ "model_id": "black-forest-labs/FLUX.1-dev",
44
+ "description": "General purpose model (fallback)",
45
+ "supports_controlnet": False
46
+ }
47
+ ]
48
+
49
+ # Enhanced style presets with structure preservation focus
50
+ ENHANCED_STYLE_PRESETS = {
51
+ "Modern Minimalist": {
52
+ "positive": "modern minimalist interior design, clean lines, neutral colors, natural light, contemporary furniture, open space, architectural details preserved, structural elements maintained, room layout unchanged, high quality, professional photography",
53
+ "negative": "cluttered, busy patterns, dark lighting, traditional style, ornate details, structural changes, layout modifications"
54
+ },
55
+ "Luxury Contemporary": {
56
+ "positive": "luxury contemporary interior, high-end materials, marble surfaces, designer furniture, elegant lighting, sophisticated color palette, architectural structure preserved, room proportions maintained, premium finishes, professional staging",
57
+ "negative": "cheap materials, poor lighting, basic furniture, structural alterations, room layout changes"
58
+ },
59
+ "Scandinavian Style": {
60
+ "positive": "scandinavian interior design, light wood textures, cozy atmosphere, hygge concept, natural materials, white and light tones, functional furniture, architectural bones preserved, room structure intact, nordic style",
61
+ "negative": "dark colors, heavy furniture, ornate decorations, structural modifications, layout changes"
62
+ },
63
+ "Industrial Chic": {
64
+ "positive": "industrial interior design, exposed brick, metal fixtures, concrete surfaces, loft style, urban aesthetic, raw materials, architectural features highlighted, structural elements enhanced, warehouse feel",
65
+ "negative": "soft decorations, pastel colors, traditional style, structural hiding, layout alterations"
66
+ },
67
+ "Cozy Traditional": {
68
+ "positive": "cozy traditional interior, warm colors, comfortable furniture, classic patterns, timeless design, welcoming atmosphere, architectural character preserved, room proportions maintained, heritage style",
69
+ "negative": "modern minimalism, cold materials, stark lighting, structural changes, contemporary style"
70
+ }
71
+ }
72
+
73
+ def encode_image_to_base64(image):
74
+ """Convert PIL Image to base64 string for API transmission"""
75
+ if image is None:
76
+ return None
77
+
78
+ # Convert to RGB if necessary
79
+ if image.mode != 'RGB':
80
+ image = image.convert('RGB')
81
+
82
+ # Resize if too large (max 1024x1024 for most models)
83
+ max_size = 1024
84
+ if max(image.size) > max_size:
85
+ ratio = max_size / max(image.size)
86
+ new_size = tuple(int(dim * ratio) for dim in image.size)
87
+ image = image.resize(new_size, Image.LANCZOS)
88
+
89
+ # Convert to base64
90
+ buffer = io.BytesIO()
91
+ image.save(buffer, format='JPEG', quality=95)
92
+ image_bytes = buffer.getvalue()
93
+ base64_string = base64.b64encode(image_bytes).decode('utf-8')
94
+
95
+ return f"data:image/jpeg;base64,{base64_string}"
96
+
97
+ def call_huggingface_api(model_id, inputs, api_token):
98
+ """Enhanced API call with better error handling and retry logic"""
99
+ api_url = f"https://api-inference.huggingface.co/models/{model_id}"
100
+
101
+ headers = {
102
+ "Authorization": f"Bearer {api_token}",
103
+ "Content-Type": "application/json"
104
+ }
105
+
106
+ max_retries = 3
107
+ for attempt in range(max_retries):
108
+ try:
109
+ response = requests.post(api_url, headers=headers, json=inputs, timeout=60)
110
+
111
+ if response.status_code == 200:
112
+ return response.content, None
113
+ elif response.status_code == 503:
114
+ error_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {}
115
+ estimated_time = error_data.get('estimated_time', 10)
116
+ return None, f"Model is loading. Estimated time: {estimated_time}s"
117
+ elif response.status_code == 404:
118
+ return None, f"Model {model_id} not found or not accessible"
119
+ else:
120
+ return None, f"API Error {response.status_code}: {response.text[:200]}"
121
+
122
+ except requests.exceptions.Timeout:
123
+ if attempt < max_retries - 1:
124
+ time.sleep(2 ** attempt) # Exponential backoff
125
+ continue
126
+ return None, "Request timeout. Please try again."
127
+ except Exception as e:
128
+ return None, f"Network error: {str(e)}"
129
+
130
+ return None, "Failed after multiple retries"
131
+
132
+ def transform_room_with_structure_preservation(input_image, style_preset, custom_prompt="", strength=0.7, guidance_scale=7.5, api_token=""):
133
+ """
134
+ Transform room design while preserving structural elements
135
+ """
136
+ if input_image is None:
137
+ return None, "Please upload an image first."
138
+
139
+ if not api_token or api_token == "your_token_here":
140
+ return None, "Please provide a valid HuggingFace API token."
141
+
142
+ # Get style configuration
143
+ style_config = ENHANCED_STYLE_PRESETS.get(style_preset, ENHANCED_STYLE_PRESETS["Modern Minimalist"])
144
+
145
+ # Build enhanced prompt with structure preservation keywords
146
+ if custom_prompt.strip():
147
+ positive_prompt = f"{custom_prompt}, {style_config['positive']}"
148
+ else:
149
+ positive_prompt = style_config['positive']
150
+
151
+ # Add extra structure preservation keywords
152
+ positive_prompt += ", maintain room structure, preserve architectural layout, keep spatial relationships, same room dimensions, identical floor plan"
153
+
154
+ negative_prompt = style_config['negative'] + ", structural changes, room layout modifications, different room, changed proportions, architectural alterations"
155
+
156
+ # Encode image
157
+ base64_image = encode_image_to_base64(input_image)
158
+ if not base64_image:
159
+ return None, "Failed to process input image."
160
+
161
+ # Try models in order of preference
162
+ for model_info in STRUCTURE_PRESERVING_MODELS:
163
+ model_id = model_info["model_id"]
164
+ model_name = model_info["name"]
165
+
166
+ print(f"Trying model: {model_name} ({model_id})")
167
+
168
+ # Prepare inputs based on model capabilities
169
+ if model_info["supports_controlnet"]:
170
+ # ControlNet models
171
+ inputs = {
172
+ "prompt": positive_prompt,
173
+ "negative_prompt": negative_prompt,
174
+ "image": base64_image,
175
+ "strength": strength,
176
+ "guidance_scale": guidance_scale,
177
+ "num_inference_steps": 20,
178
+ "controlnet_conditioning_scale": 1.0
179
+ }
180
+ else:
181
+ # Standard img2img models
182
+ inputs = {
183
+ "prompt": positive_prompt,
184
+ "negative_prompt": negative_prompt,
185
+ "image": base64_image,
186
+ "strength": strength,
187
+ "guidance_scale": guidance_scale,
188
+ "num_inference_steps": 25
189
+ }
190
+
191
+ # Call API
192
+ image_bytes, error = call_huggingface_api(model_id, inputs, api_token)
193
+
194
+ if image_bytes:
195
+ try:
196
+ # Convert response to PIL Image
197
+ result_image = Image.open(io.BytesIO(image_bytes))
198
+ success_message = f"βœ… Successfully generated with {model_name}!\n\nPrompt used: {positive_prompt[:200]}..." if len(positive_prompt) > 200 else positive_prompt
199
+ return result_image, success_message
200
+ except Exception as e:
201
+ print(f"Failed to process image from {model_name}: {str(e)}")
202
+ continue
203
+ else:
204
+ print(f"Model {model_name} failed: {error}")
205
+ continue
206
+
207
+ # If all models fail
208
+ return None, "❌ All structure-preserving models are currently unavailable. This could be due to:\n\nβ€’ Models are still loading (try again in a few minutes)\nβ€’ High demand on the servers\nβ€’ Temporary API issues\n\nPlease try again later or check the model availability on HuggingFace Hub."
209
+
210
+ # Create the Gradio interface
211
+ def create_interface():
212
+ """Create the enhanced Gradio interface for structure-preserving room transformation"""
213
+
214
+ with gr.Blocks(title="🏠 AI Interior Design - Structure Preserving", theme=gr.themes.Soft()) as interface:
215
+ gr.Markdown("""
216
+ # 🏠 AI Interior Design - Structure Preserving
217
+
218
+ Transform your room's style while **preserving the original structure, layout, and architectural elements**.
219
+
220
+ This app uses advanced **image-to-image** and **ControlNet** models that can:
221
+ - βœ… Maintain room dimensions and proportions
222
+ - βœ… Preserve architectural features (windows, doors, walls)
223
+ - βœ… Keep furniture placement and spatial relationships
224
+ - βœ… Transform only the **style, colors, and materials**
225
+
226
+ ## πŸ“‹ How to use:
227
+ 1. **Upload** your room photo
228
+ 2. **Choose** a style preset or add custom prompt
229
+ 3. **Adjust** transformation strength (lower = more preservation)
230
+ 4. **Generate** your transformed design!
231
+ """)
232
+
233
+ with gr.Row():
234
+ with gr.Column(scale=1):
235
+ # Input section
236
+ gr.Markdown("### πŸ“€ Input")
237
+ input_image = gr.Image(
238
+ label="Upload Room Photo",
239
+ type="pil",
240
+ height=300
241
+ )
242
+
243
+ style_preset = gr.Dropdown(
244
+ choices=list(ENHANCED_STYLE_PRESETS.keys()),
245
+ value="Modern Minimalist",
246
+ label="🎨 Style Preset",
247
+ info="Choose a predefined style"
248
+ )
249
+
250
+ custom_prompt = gr.Textbox(
251
+ label="✏️ Custom Style Description (Optional)",
252
+ placeholder="Add specific details like 'add plants', 'wooden floors', 'blue walls'...",
253
+ lines=2
254
+ )
255
+
256
+ # API Token input
257
+ api_token = gr.Textbox(
258
+ label="πŸ”‘ HuggingFace API Token",
259
+ placeholder="Enter your HF API token (hf_...)",
260
+ type="password",
261
+ info="Required for accessing the models. Get yours at https://huggingface.co/settings/tokens"
262
+ )
263
+
264
+ # Advanced settings
265
+ with gr.Accordion("βš™οΈ Advanced Settings", open=False):
266
+ strength = gr.Slider(
267
+ minimum=0.3,
268
+ maximum=0.9,
269
+ value=0.7,
270
+ step=0.1,
271
+ label="Transformation Strength",
272
+ info="Lower = more preservation, Higher = more change"
273
+ )
274
+
275
+ guidance_scale = gr.Slider(
276
+ minimum=5.0,
277
+ maximum=15.0,
278
+ value=7.5,
279
+ step=0.5,
280
+ label="Guidance Scale",
281
+ info="How closely to follow the prompt"
282
+ )
283
+
284
+ transform_btn = gr.Button(
285
+ "πŸš€ Transform Room",
286
+ variant="primary",
287
+ size="lg"
288
+ )
289
+
290
+ with gr.Column(scale=1):
291
+ # Output section
292
+ gr.Markdown("### πŸ“€ Result")
293
+ output_image = gr.Image(
294
+ label="Transformed Room",
295
+ height=300
296
+ )
297
+
298
+ output_message = gr.Textbox(
299
+ label="Status",
300
+ lines=8,
301
+ max_lines=15
302
+ )
303
+
304
+ # Model information
305
+ with gr.Accordion("πŸ€– Available Models", open=False):
306
+ model_info_md = "This app tries the following structure-preserving models in order:\n\n"
307
+ for i, model in enumerate(STRUCTURE_PRESERVING_MODELS, 1):
308
+ model_info_md += f"**{i}. {model['name']}**\n"
309
+ model_info_md += f" - Model: `{model['model_id']}`\n"
310
+ model_info_md += f" - Description: {model['description']}\n"
311
+ model_info_md += f" - ControlNet Support: {'βœ…' if model['supports_controlnet'] else '❌'}\n\n"
312
+
313
+ gr.Markdown(model_info_md)
314
+
315
+ # Examples
316
+ gr.Markdown("### πŸ–ΌοΈ Example Transformations")
317
+ gr.Markdown("Upload your room photos to see similar transformations with preserved structure!")
318
+
319
+ # Event handlers
320
+ transform_btn.click(
321
+ fn=transform_room_with_structure_preservation,
322
+ inputs=[input_image, style_preset, custom_prompt, strength, guidance_scale, api_token],
323
+ outputs=[output_image, output_message],
324
+ show_progress=True
325
+ )
326
+
327
+ # Footer
328
+ gr.Markdown("""
329
+ ---
330
+
331
+ ### πŸ’‘ Tips for Best Results:
332
+ - Use well-lit, clear photos of rooms
333
+ - Avoid blurry or dark images
334
+ - Lower strength values preserve more of the original structure
335
+ - Try different style presets to find your favorite
336
+
337
+ ### πŸ”§ Technical Details:
338
+ This app uses advanced **image-to-image** models and **ControlNet** technology to maintain structural integrity while transforming style.
339
+ The models are specifically chosen for their ability to preserve room layout and architectural elements.
340
+ """)
341
+
342
+ return interface
343
+
344
+ # Create and launch the interface
345
+ if __name__ == "__main__":
346
+ demo = create_interface()
347
+ demo.launch()