padmanabhbosamia commited on
Commit
afabb3b
·
verified ·
1 Parent(s): eed8efb

Upload 8 files

Browse files

Uploaded all the files

Files changed (8) hide show
  1. README.md +108 -14
  2. app.py +459 -0
  3. bird_style.bin +3 -0
  4. canna-lily-flowers102.bin +3 -0
  5. pop_art.bin +3 -0
  6. requirements.txt +7 -0
  7. ronaldo.bin +3 -0
  8. threestooges.bin +3 -0
README.md CHANGED
@@ -1,14 +1,108 @@
1
- ---
2
- title: Stable Styles
3
- emoji: 🐨
4
- colorFrom: indigo
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.17.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- short_description: A pretrained Stable Diffusion model combined with 5 themes
12
- ---
13
-
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stable Diffusion Style Transfer with Color Distance Loss
2
+
3
+ This project implements a Stable Diffusion-based image generation system with custom style transfers and color enhancement through a distance loss function.
4
+
5
+ ## 🎨 Features
6
+
7
+ ### Style Transfer
8
+ - Implements 5 different artistic styles:
9
+ - Ronaldo Style (Sports scenes)
10
+ - Canna Lily (Nature and flowers)
11
+ - Three Stooges (Comedy scenes)
12
+ - Pop Art (Vibrant artistic style)
13
+ - Bird Style (Wildlife imagery)
14
+
15
+ ### Color Distance Loss
16
+ The project implements a unique color enhancement through RGB channel separation:
17
+ - Calculates distances between RGB channels
18
+ - Enhances color vibrancy and contrast
19
+ - Creates more distinct color separation
20
+ - Reduces color mixing and muddiness
21
+
22
+ ### Interactive Interface
23
+ - User-friendly Gradio web interface
24
+ - Side-by-side comparison of original and enhanced images
25
+ - Real-time style selection
26
+ - Example prompts for each style
27
+
28
+ ## 🚀 Setup and Installation
29
+
30
+ 1. Install dependencies:
31
+ bash
32
+ pip install -r requirements.txt
33
+
34
+ 2. Required files:
35
+ - Style embeddings (.bin files):
36
+ - ronaldo.bin
37
+ - canna-lily-flowers102.bin
38
+ - threestooges.bin
39
+ - pop_art.bin
40
+ - bird_style.bin
41
+
42
+ 3. Run the application:
43
+ bash
44
+ python app.py
45
+
46
+ ## 🎮 Usage
47
+
48
+ 1. Enter a text prompt describing your desired image
49
+ 2. Select a style using the radio buttons
50
+ 3. Click "Generate Images" to create:
51
+ - Left: Original styled image
52
+ - Right: Image with color distance loss applied
53
+
54
+ ## 🔧 Technical Details
55
+
56
+ ### Distance Loss Function
57
+ def Distance_loss(images):
58
+ # Extract RGB channels
59
+ red = images[:,0:1]
60
+ green = images[:,1:2]
61
+ blue = images[:,2:3]
62
+ # Calculate channel distances
63
+ rg_distance = ((red - green) 2).mean()
64
+ rb_distance = ((red - blue) 2).mean()
65
+ gb_distance = ((green - blue) 2).mean()
66
+ return (rg_distance + rb_distance + gb_distance) 100
67
+
68
+ This loss function:
69
+ - Separates RGB channels
70
+ - Calculates squared distances between channels
71
+ - Enhances color distinctiveness
72
+ - Applies during the generation process
73
+
74
+ ## 📝 Example Prompts
75
+
76
+ - Sports: "a soccer player celebrating a goal"
77
+ - Nature: "beautiful flowers in a garden"
78
+ - Comedy: "three comedians performing a skit"
79
+ - Art: "a colorful portrait in pop art style"
80
+ - Wildlife: "birds flying in a natural landscape"
81
+
82
+ ## 🛠️ Requirements
83
+
84
+ - Python 3.8+
85
+ - PyTorch
86
+ - Diffusers
87
+ - Transformers
88
+ - Gradio
89
+ - CUDA-capable GPU recommended
90
+
91
+ ## 📊 Results
92
+
93
+ The color distance loss typically produces:
94
+ - More vibrant colors
95
+ - Better color separation
96
+ - Enhanced contrast
97
+ - More distinctive style characteristics
98
+
99
+ ## 🤝 Contributing
100
+
101
+ Feel free to:
102
+ - Submit issues
103
+ - Fork the repository
104
+ - Submit pull requests
105
+
106
+ ## 📜 License
107
+
108
+ This project is open-source and available under the MIT License.
app.py ADDED
@@ -0,0 +1,459 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import StableDiffusionPipeline
3
+ from torch import autocast
4
+ import gradio as gr
5
+ from huggingface_hub import hf_hub_download
6
+ import os
7
+ from pathlib import Path
8
+ import traceback
9
+
10
+ # Reuse the same load_learned_embed_in_clip and Distance_loss functions
11
+ def load_learned_embed_in_clip(learned_embeds_path, text_encoder, tokenizer, token=None):
12
+ loaded_learned_embeds = torch.load(learned_embeds_path, map_location="cpu")
13
+ trained_token = list(loaded_learned_embeds.keys())[0]
14
+ embeds = loaded_learned_embeds[trained_token]
15
+
16
+ # Get the expected dimension from the text encoder
17
+ expected_dim = text_encoder.get_input_embeddings().weight.shape[1]
18
+ current_dim = embeds.shape[0]
19
+
20
+ # Resize embeddings if dimensions don't match
21
+ if current_dim != expected_dim:
22
+ print(f"Resizing embedding from {current_dim} to {expected_dim}")
23
+ # Option 1: Truncate or pad with zeros
24
+ if current_dim > expected_dim:
25
+ embeds = embeds[:expected_dim]
26
+ else:
27
+ embeds = torch.cat([embeds, torch.zeros(expected_dim - current_dim)], dim=0)
28
+
29
+ # Reshape to match expected dimensions
30
+ embeds = embeds.unsqueeze(0) # Add batch dimension
31
+
32
+ # Cast to dtype of text_encoder
33
+ dtype = text_encoder.get_input_embeddings().weight.dtype
34
+ embeds = embeds.to(dtype)
35
+
36
+ # Add the token in tokenizer
37
+ token = token if token is not None else trained_token
38
+ num_added_tokens = tokenizer.add_tokens(token)
39
+
40
+ # Resize the token embeddings
41
+ text_encoder.resize_token_embeddings(len(tokenizer))
42
+
43
+ # Get the id for the token and assign the embeds
44
+ token_id = tokenizer.convert_tokens_to_ids(token)
45
+ text_encoder.get_input_embeddings().weight.data[token_id] = embeds[0]
46
+ return token
47
+
48
+ def Distance_loss(images):
49
+ # Ensure we're working with gradients
50
+ if not images.requires_grad:
51
+ images = images.detach().requires_grad_(True)
52
+
53
+ # Convert to float32 and normalize
54
+ images = images.float() / 2 + 0.5
55
+
56
+ # Get RGB channels
57
+ red = images[:,0:1]
58
+ green = images[:,1:2]
59
+ blue = images[:,2:3]
60
+
61
+ # Calculate color distances using L2 norm
62
+ rg_distance = ((red - green) ** 2).mean()
63
+ rb_distance = ((red - blue) ** 2).mean()
64
+ gb_distance = ((green - blue) ** 2).mean()
65
+
66
+ return (rg_distance + rb_distance + gb_distance) * 100 # Scale up the loss
67
+
68
+ class StyleGenerator:
69
+ _instance = None
70
+
71
+ @classmethod
72
+ def get_instance(cls):
73
+ if cls._instance is None:
74
+ cls._instance = cls()
75
+ return cls._instance
76
+
77
+ def __init__(self):
78
+ self.pipe = None
79
+ self.style_tokens = []
80
+ self.styles = [
81
+ "ronaldo",
82
+ "canna-lily-flowers102",
83
+ "threestooges",
84
+ "pop_art",
85
+ "bird_style"
86
+ ]
87
+ self.style_names = [
88
+ "Ronaldo",
89
+ "Canna Lily",
90
+ "Three Stooges",
91
+ "Pop Art",
92
+ "Bird Style"
93
+ ]
94
+ self.is_initialized = False
95
+
96
+ def initialize_model(self):
97
+ if self.is_initialized:
98
+ return
99
+
100
+ try:
101
+ print("Initializing Stable Diffusion model...")
102
+ model_id = "runwayml/stable-diffusion-v1-5"
103
+ self.pipe = StableDiffusionPipeline.from_pretrained(
104
+ model_id,
105
+ torch_dtype=torch.float16,
106
+ safety_checker=None
107
+ )
108
+ self.pipe = self.pipe.to("cuda")
109
+
110
+ # Load style embeddings from current directory
111
+ current_dir = Path(__file__).parent
112
+
113
+ for style, style_name in zip(self.styles, self.style_names):
114
+ style_path = current_dir / f"{style}.bin"
115
+ if not style_path.exists():
116
+ raise FileNotFoundError(f"Style embedding not found: {style_path}")
117
+
118
+ print(f"Loading style: {style_name}")
119
+ token = load_learned_embed_in_clip(str(style_path), self.pipe.text_encoder, self.pipe.tokenizer)
120
+ self.style_tokens.append(token)
121
+ print(f"✓ Loaded style: {style_name}")
122
+
123
+ self.is_initialized = True
124
+ print("Model initialization complete!")
125
+
126
+ except Exception as e:
127
+ print(f"Error during initialization: {str(e)}")
128
+ print(traceback.format_exc())
129
+ raise
130
+
131
+ def generate_images(self, prompt, apply_loss=False, num_inference_steps=50, guidance_scale=7.5):
132
+ if not self.is_initialized:
133
+ self.initialize_model()
134
+
135
+ images = []
136
+ style_names = []
137
+
138
+ try:
139
+ def callback_fn(i, t, latents):
140
+ if i % 5 == 0 and apply_loss:
141
+ try:
142
+ # Ensure latents are in the correct format and require gradients
143
+ latents = latents.float()
144
+ latents.requires_grad_(True)
145
+
146
+ # Compute loss
147
+ loss = Distance_loss(latents)
148
+
149
+ # Compute gradients manually
150
+ grads = torch.autograd.grad(
151
+ outputs=loss,
152
+ inputs=latents,
153
+ create_graph=False,
154
+ retain_graph=False,
155
+ only_inputs=True
156
+ )[0]
157
+
158
+ # Update latents
159
+ with torch.no_grad():
160
+ latents = latents - 0.1 * grads
161
+
162
+ except Exception as e:
163
+ print(f"Error in callback: {e}")
164
+ return latents
165
+
166
+ return latents
167
+
168
+ for style_token, style_name in zip(self.style_tokens, self.style_names):
169
+ styled_prompt = f"{prompt}, {style_token}"
170
+ style_names.append(style_name)
171
+
172
+ # Disable autocast for better gradient computation
173
+ image = self.pipe(
174
+ styled_prompt,
175
+ num_inference_steps=num_inference_steps,
176
+ guidance_scale=guidance_scale,
177
+ callback=callback_fn if apply_loss else None,
178
+ callback_steps=5
179
+ ).images[0]
180
+
181
+ images.append(image)
182
+
183
+ return images, style_names
184
+
185
+ except Exception as e:
186
+ print(f"Error during image generation: {str(e)}")
187
+ print(traceback.format_exc())
188
+ raise
189
+
190
+ def callback_fn(self, i, t, latents):
191
+ if i % 5 == 0: # Apply loss every 5 steps
192
+ try:
193
+ # Create a copy that requires gradients
194
+ latents_copy = latents.detach().clone()
195
+ latents_copy.requires_grad_(True)
196
+
197
+ # Compute loss
198
+ loss = Distance_loss(latents_copy)
199
+
200
+ # Compute gradients
201
+ if loss.requires_grad:
202
+ grads = torch.autograd.grad(
203
+ outputs=loss,
204
+ inputs=latents_copy,
205
+ allow_unused=True,
206
+ retain_graph=False
207
+ )[0]
208
+
209
+ if grads is not None:
210
+ # Apply gradients to original latents
211
+ return latents - 0.1 * grads.detach()
212
+
213
+ except Exception as e:
214
+ print(f"Error in callback: {e}")
215
+
216
+ return latents
217
+
218
+ def generate_all_variations(prompt):
219
+ try:
220
+ generator = StyleGenerator.get_instance()
221
+ if not generator.is_initialized:
222
+ generator.initialize_model()
223
+
224
+ # Generate images without loss
225
+ regular_images, style_names = generator.generate_images(prompt, apply_loss=False)
226
+
227
+ # Generate images with loss
228
+ loss_images, _ = generator.generate_images(prompt, apply_loss=True)
229
+
230
+ return regular_images, loss_images, style_names
231
+
232
+ except Exception as e:
233
+ print(f"Error in generate_all_variations: {str(e)}")
234
+ print(traceback.format_exc())
235
+ raise
236
+
237
+ def gradio_interface(prompt):
238
+ try:
239
+ regular_images, loss_images, style_names = generate_all_variations(prompt)
240
+
241
+ return (
242
+ regular_images, # Just return the images directly
243
+ loss_images # Just return the images directly
244
+ )
245
+ except Exception as e:
246
+ print(f"Error in interface: {str(e)}")
247
+ print(traceback.format_exc())
248
+ # Return empty lists in case of error
249
+ return [], []
250
+
251
+ # Create a more beautiful interface with custom styling
252
+ with gr.Blocks(css="""
253
+ .gradio-container {
254
+ background-color: #1f2937 !important;
255
+ }
256
+ .dark-theme {
257
+ background-color: #111827;
258
+ border-radius: 10px;
259
+ padding: 20px;
260
+ margin: 10px;
261
+ border: 1px solid #374151;
262
+ color: #f3f4f6;
263
+ }
264
+ """) as iface:
265
+ # Header section with dark theme
266
+ gr.Markdown(
267
+ """
268
+ <div class="dark-theme" style="text-align: center; max-width: 800px; margin: 0 auto;">
269
+ # 🎨 AI Style Transfer Studio
270
+ ### Transform your ideas into artistic masterpieces with custom styles and enhanced colors
271
+ </div>
272
+ """
273
+ )
274
+
275
+ # Define the generate_single_style function first
276
+ def generate_single_style(prompt, selected_style):
277
+ try:
278
+ generator = StyleGenerator.get_instance()
279
+ if not generator.is_initialized:
280
+ generator.initialize_model()
281
+
282
+ # Find the index of the selected style
283
+ style_idx = generator.style_names.index(generator.style_names[selected_style])
284
+
285
+ # Generate single image with selected style
286
+ styled_prompt = f"{prompt}, {generator.style_tokens[style_idx]}"
287
+
288
+ # Set seed for reproducibility
289
+ generator_seed = 42
290
+ torch.manual_seed(generator_seed)
291
+ torch.cuda.manual_seed(generator_seed)
292
+
293
+ # Generate base image
294
+ with autocast("cuda"):
295
+ base_image = generator.pipe(
296
+ styled_prompt,
297
+ num_inference_steps=50,
298
+ guidance_scale=7.5,
299
+ generator=torch.Generator("cuda").manual_seed(generator_seed)
300
+ ).images[0]
301
+
302
+ # Generate same image with loss
303
+ with autocast("cuda"):
304
+ loss_image = generator.pipe(
305
+ styled_prompt,
306
+ num_inference_steps=50,
307
+ guidance_scale=7.5,
308
+ callback=generator.callback_fn,
309
+ callback_steps=5,
310
+ generator=torch.Generator("cuda").manual_seed(generator_seed)
311
+ ).images[0]
312
+
313
+ return [
314
+ gr.update(visible=False), # error_message
315
+ base_image, # original_image
316
+ loss_image # loss_image
317
+ ]
318
+ except Exception as e:
319
+ print(f"Error in generate_single_style: {e}")
320
+ return [
321
+ gr.update(value=f"Error: {str(e)}", visible=True), # error_message
322
+ None, # original_image
323
+ None # loss_image
324
+ ]
325
+
326
+ # Main content
327
+ with gr.Row():
328
+ # Left sidebar for controls
329
+ with gr.Column(scale=1, min_width=300):
330
+ gr.Markdown("## 🎯 Controls")
331
+
332
+ prompt = gr.Textbox(
333
+ label="What would you like to create?",
334
+ placeholder="e.g., a soccer player celebrating a goal",
335
+ lines=3
336
+ )
337
+
338
+ style_radio = gr.Radio(
339
+ choices=[
340
+ "Ronaldo Style",
341
+ "Canna Lily",
342
+ "Three Stooges",
343
+ "Pop Art",
344
+ "Bird Style"
345
+ ],
346
+ label="Choose Your Style",
347
+ value="Ronaldo Style",
348
+ type="index"
349
+ )
350
+
351
+ generate_btn = gr.Button(
352
+ "🚀 Generate Artwork",
353
+ variant="primary",
354
+ size="lg"
355
+ )
356
+
357
+ # Error messages
358
+ error_message = gr.Markdown(visible=False)
359
+
360
+ # Style description
361
+ style_description = gr.Markdown()
362
+
363
+ # Right side for image display
364
+ with gr.Column(scale=2):
365
+ gr.Markdown("## 🖼️ Generated Artwork")
366
+ with gr.Row():
367
+ with gr.Column():
368
+ original_image = gr.Image(
369
+ label="Original Style",
370
+ show_label=True,
371
+ height=400
372
+ )
373
+ with gr.Column():
374
+ loss_image = gr.Image(
375
+ label="Color Enhanced",
376
+ show_label=True,
377
+ height=400
378
+ )
379
+
380
+ # Info section
381
+ with gr.Row():
382
+ with gr.Column():
383
+ gr.Markdown(
384
+ """
385
+ <div class="dark-theme">
386
+ ## 🎨 Style Guide
387
+
388
+ | Style | Best For |
389
+ |-------|----------|
390
+ | **Ronaldo Style** | Dynamic sports scenes, action shots, celebrations |
391
+ | **Canna Lily** | Natural scenes, floral compositions, garden imagery |
392
+ | **Three Stooges** | Comedy, humor, expressive character portraits |
393
+ | **Pop Art** | Vibrant artwork, bold colors, stylized designs |
394
+ | **Bird Style** | Wildlife, nature scenes, peaceful landscapes |
395
+
396
+ *Choose the style that best matches your creative vision*
397
+ </div>
398
+ """
399
+ )
400
+ with gr.Column():
401
+ gr.Markdown(
402
+ """
403
+ <div class="dark-theme">
404
+ ## 🔍 Color Enhancement Technology
405
+
406
+ Our advanced color processing uses distance loss to enhance your images:
407
+
408
+ ### 🌈 Color Dynamics
409
+ - **Vibrancy**: Intensifies colors naturally
410
+ - **Contrast**: Improves depth and definition
411
+ - **Balance**: Optimizes color relationships
412
+
413
+ ### 🎨 Technical Features
414
+ - **Channel Separation**: RGB optimization
415
+ - **Loss Function**: Mathematical color enhancement
416
+ - **Real-time Processing**: Dynamic adjustments
417
+
418
+ ### ✨ Benefits
419
+ - Richer, more vivid colors
420
+ - Clearer color boundaries
421
+ - Reduced color muddiness
422
+ - Enhanced artistic impact
423
+
424
+ <small>*Our color distance loss technology mathematically optimizes RGB channel relationships*</small>
425
+ </div>
426
+ """
427
+ )
428
+
429
+ # Update style description on change
430
+ def update_style_description(style_idx):
431
+ descriptions = [
432
+ "Perfect for capturing dynamic sports moments and celebrations",
433
+ "Ideal for creating beautiful natural and floral compositions",
434
+ "Great for adding humor and expressiveness to your scenes",
435
+ "Transform your ideas into vibrant pop art masterpieces",
436
+ "Specialized in capturing the beauty of nature and wildlife"
437
+ ]
438
+ styles = ["Ronaldo Style", "Canna Lily", "Three Stooges", "Pop Art", "Bird Style"]
439
+ return f"### Selected: {styles[style_idx]}\n{descriptions[style_idx]}"
440
+
441
+ style_radio.change(
442
+ fn=update_style_description,
443
+ inputs=style_radio,
444
+ outputs=style_description
445
+ )
446
+
447
+ # Connect the generate button
448
+ generate_btn.click(
449
+ fn=generate_single_style,
450
+ inputs=[prompt, style_radio],
451
+ outputs=[error_message, original_image, loss_image]
452
+ )
453
+
454
+ # Launch the app
455
+ if __name__ == "__main__":
456
+ iface.launch(
457
+ share=True,
458
+ show_error=True
459
+ )
bird_style.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f2e23a8f2d3628ed77acb8151751ecd4efc4017e8da86bc29af10f855ca308d9
3
+ size 3819
canna-lily-flowers102.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94ea71a266f316b97d74698a308e9748549211facfb9b9a17c6f7b16068cb5ba
3
+ size 5311
pop_art.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7d2a60820b9e89660dc1c8cc7cd99a78759e5fe20545576acf9437618474b274
3
+ size 3840
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ diffusers>=0.24.0
3
+ transformers>=4.35.0
4
+ gradio>=4.0.0
5
+ huggingface_hub>=0.19.0
6
+ accelerate>=0.24.0
7
+ safetensors>=0.4.0
ronaldo.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fe2b93171c39de9b7e5172cade4afb6d6aa672097e2f5a79f2b29bf330ba8e47
3
+ size 3840
threestooges.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6041318f157a72c6d482ffbd23041112678b17ebbef31a36d0cc4c28db3607b2
3
+ size 3819