ghadaAlmuaikel commited on
Commit
3081405
1 Parent(s): 2b995c4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +346 -0
app.py ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Imports
2
+ import gradio as gr
3
+ from PIL import Image, UnidentifiedImageError
4
+ from gtts import gTTS
5
+ import requests
6
+ import re
7
+ import torch
8
+ from transformers import CLIPProcessor, CLIPModel, pipeline
9
+ from sentence_transformers import SentenceTransformer, util
10
+ from langdetect import detect
11
+ from io import BytesIO
12
+ import pandas as pd
13
+
14
+ # DataFrame with information about the Paintings as image url, Title, description , stroy
15
+
16
+ data = {
17
+ "image_url": [
18
+ "https://s.turbifycdn.com/aah/gallerydirectart/vincent-van-gogh-estate-signed-limited-edition-giclee-starry-night-47.png", # Starry Night
19
+ "https://cdn.mos.cms.futurecdn.net/xRqbwS4odpkSQscn3jHECh-1200-80.jpg", # Mona Lisa
20
+ "https://upload.wikimedia.org/wikipedia/en/d/dd/The_Persistence_of_Memory.jpg", # The Persistence of Memory
21
+ "https://static.wixstatic.com/media/1071a8_cf1930f883e043e28d03d5a26a5960ef~mv2.jpg/v1/fill/w_568,h_718,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/1071a8_cf1930f883e043e28d03d5a26a5960ef~mv2.jpg", # The Scream
22
+ "https://images.artbrokerage.com/artthumb/magritte_158194_1/625x559/Rene_Magritte_Le_Fils_De_lhomme_the_Son_of_Man_1973.jpg", # The Son of Man
23
+ "https://www.artic.edu/iiif/2/25c31d8d-21a4-9ea1-1d73-6a2eca4dda7e/full/843,/0/default.jpg", # The Bedroom
24
+ "https://images.desenio.com/zoom/17047_1.jpg", # Girl with a Pearl Earring
25
+ "https://www.hastingsindependentpress.co.uk/wp-content/uploads/2021/03/Whistlers-Mother.jpg", # Whistler’s Mother
26
+ "https://live.staticflickr.com/7173/6713746433_652c3d9d4e_c.jpg" # The Basket of Apples
27
+ ],
28
+ "Title": [
29
+ "Starry Night", "Mona Lisa", "The Persistence of Memory", "The Scream",
30
+ "The Son of Man", "The Bedroom",
31
+ "Girl with a Pearl Earring", "Whistler’s Mother", "The Basket of Apples"
32
+ ],
33
+ "Description": [
34
+ # Starry Night
35
+ ("Starry Night by Vincent van Gogh, painted in 1889, is one of the most famous works of art in the world. "
36
+ "It depicts a swirling night sky filled with stars over a small town. The painting uses vibrant colors like blue and yellow, "
37
+ "with exaggerated swirling patterns that create a dreamlike, almost chaotic feeling."),
38
+
39
+ # Mona Lisa
40
+ ("The Mona Lisa by Leonardo da Vinci, painted between 1503 and 1506, is a portrait of a woman with a subtle, enigmatic smile. "
41
+ "The use of muted colors, including soft browns, greens, and black, emphasizes the serene and mysterious nature of the subject. "
42
+ "It is one of the most studied and recognized works of art in history."),
43
+
44
+ # The Persistence of Memory
45
+ ("The Persistence of Memory, created by Salvador Dalí in 1931, features melting clocks draped over a surreal landscape. "
46
+ "The painting, primarily in soft shades of brown, blue, and yellow, explores themes of time and memory. The abstract shapes "
47
+ "and dreamlike atmosphere make it one of Dalí’s most famous surrealist works."),
48
+
49
+ # The Scream
50
+ ("The Scream by Edvard Munch, painted in 1893, is one of the most iconic images in modern art. "
51
+ "It depicts a figure standing on a bridge, clutching their face in agony, as a blood-red sky swirls behind them. "
52
+ "The painting uses bold reds, oranges, and blues to evoke a sense of horror and existential despair."),
53
+
54
+ # The Son of Man
55
+ ("The Son of Man by René Magritte, painted in 1964, is a surrealist self-portrait of the artist. "
56
+ "It depicts a man in a bowler hat and suit, with his face obscured by a floating green apple. "
57
+ "The background features a cloudy sky and a low wall, contributing to the dreamlike atmosphere. The painting is rich in symbolism, "
58
+ "exploring themes of identity, concealment, and perception."),
59
+
60
+ # The Bedroom
61
+ ("The Bedroom by Vincent van Gogh, painted in 1888, depicts the artist’s simple bedroom in Arles, France. "
62
+ "The painting uses bold, contrasting colors—yellow, red, and blue—to create a vibrant, almost childlike view of the space. "
63
+ "Van Gogh painted this scene three times, each version representing his sense of comfort and sanctuary in his personal space."),
64
+
65
+ # Girl with a Pearl Earring
66
+ ("Girl with a Pearl Earring by Johannes Vermeer, painted in 1665, is often referred to as the 'Mona Lisa of the North.' "
67
+ "The painting shows a young girl looking over her shoulder, wearing a large pearl earring. The use of light and shadow, "
68
+ "combined with soft colors like blue and yellow, creates a lifelike, intimate portrait."),
69
+
70
+ # Whistler’s Mother
71
+ ("Whistler’s Mother by James McNeill Whistler, painted in 1871, is a portrait of the artist’s mother seated in profile. "
72
+ "The painting uses muted tones of black, gray, and brown, reflecting the simplicity and dignity of the subject. "
73
+ "It has become an icon of motherhood and restraint."),
74
+
75
+ # The Basket of Apples
76
+ ("The Basket of Apples by Paul Cézanne, painted around 1895, is a still life that challenges traditional perspectives. "
77
+ "The painting shows a table with a basket of apples, a bottle, and bread. The use of soft colors, including browns, reds, and greens, "
78
+ "along with the tilted angles, makes the objects seem to float, blurring the line between realism and abstraction.")
79
+ ],
80
+ "Story": [
81
+ # Starry Night
82
+ ("Vincent van Gogh painted 'Starry Night' while in a mental asylum in Saint-Rémy-de-Provence, France. "
83
+ "It was created from memory and imagination, rather than a direct view from his window. The swirling patterns "
84
+ "are thought to represent his emotional turbulence at the time. The painting is celebrated for its bold brushstrokes "
85
+ "and imaginative use of color, representing the tension between beauty and chaos in the natural world."),
86
+
87
+ # Mona Lisa
88
+ ("'Mona Lisa' was painted by Leonardo da Vinci during the Renaissance period. The subject of the painting, "
89
+ "believed to be Lisa Gherardini, is famed for her mysterious smile. The painting's sfumato technique, blending "
90
+ "soft transitions between light and shadow, creates a lifelike, three-dimensional appearance. The Mona Lisa has inspired "
91
+ "countless studies and interpretations over the centuries, and its theft in 1911 only increased its mystique."),
92
+
93
+ # The Persistence of Memory
94
+ ("Salvador Dalí's 'The Persistence of Memory' is a surrealist masterpiece that reflects the fluidity of time and memory. "
95
+ "The melting clocks draped over the landscape suggest the passage of time becoming meaningless. The inspiration for the painting "
96
+ "came from a melting camembert cheese. Dalí’s fascination with dream states and Freud's theories of the unconscious mind "
97
+ "are evident in this strange, dreamlike scene."),
98
+
99
+ # The Scream
100
+ ("'The Scream' by Edvard Munch is a vivid expression of anxiety and existential dread. Munch was inspired to create the work "
101
+ "after a walk during which he felt the 'great scream' of nature overwhelm him. The distorted figure and fiery red sky reflect "
102
+ "Munch’s inner turmoil. The painting has become an iconic representation of human anxiety and has been widely referenced in pop culture."),
103
+
104
+ # The Son of Man
105
+ ("René Magritte’s 'The Son of Man' is a quintessential example of surrealism, blending reality and fantasy. "
106
+ "The painting is a self-portrait with Magritte’s face hidden by a hovering green apple, symbolizing the tension between what is visible "
107
+ "and what is hidden. The painting has been widely interpreted as a statement on identity and the nature of perception."),
108
+
109
+ # The Bedroom
110
+ ("'The Bedroom' by Vincent van Gogh is a reflection of the artist’s longing for stability and tranquility. "
111
+ "The painting was created during one of the few peaceful periods in van Gogh’s turbulent life, and the vibrant colors convey "
112
+ "his emotions at the time. The bold, contrasting colors and exaggerated perspective make the simple room appear almost alive."),
113
+
114
+ # Girl with a Pearl Earring
115
+ ("'Girl with a Pearl Earring' by Johannes Vermeer is one of the most enigmatic portraits in Western art. Known for its simplicity and elegance, "
116
+ "the painting captures a fleeting moment of connection between the viewer and the subject. The girl’s mysterious gaze and the radiant light "
117
+ "on her face have captivated audiences for centuries."),
118
+
119
+ # Whistler’s Mother
120
+ ("James McNeill Whistler’s 'Arrangement in Grey and Black No. 1,' more commonly known as 'Whistler’s Mother,' is a stark, dignified portrait "
121
+ "of the artist’s mother. The painting is renowned for its minimalist composition and restrained use of color. Its iconic status grew after "
122
+ "its display at the Musée d'Orsay in Paris, becoming a symbol of maternal devotion and calm."),
123
+
124
+ # The Basket of Apples
125
+ ("Paul Cézanne’s 'The Basket of Apples' is a revolutionary work that defies the traditional rules of perspective. By tilting objects at different angles, "
126
+ "Cézanne challenges the viewer’s perception of space and reality. This still life is often cited as a precursor to Cubism, and its soft color palette "
127
+ "creates a serene yet dynamic composition.")
128
+ ]
129
+ }
130
+
131
+
132
+ df = pd.DataFrame(data)
133
+
134
+ # Load models
135
+
136
+ #Clip model and processor
137
+ model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
138
+ processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
139
+
140
+ #sentiment similarity model
141
+ semantic_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
142
+
143
+ # translation models
144
+ translator_ar_to_en = pipeline("translation_ar_to_en", model="Helsinki-NLP/opus-mt-ar-en")
145
+ translator_en_to_ar = pipeline("translation_en_to_arabic", model="Helsinki-NLP/opus-mt-en-ar")
146
+
147
+ # Function to Convert the text to Speech in Arabic using gTTS
148
+ def text_to_speech_arabic(story_text):
149
+ tts = gTTS(text=story_text, lang='ar')
150
+ tts.save("story_arabic.mp3")
151
+ return "story_arabic.mp3"
152
+
153
+ # Function to translate the full story in chunks
154
+ def translate_story_to_arabic(story_text):
155
+ sentences = re.split(r'(?<=[.!؟])\s+', story_text) # ٍSplit the story to list of sentences to translate
156
+ translated_sentences = []
157
+
158
+ for sentence in sentences: # For each sentence translate to arabic and append to the list
159
+ translation = translator_en_to_ar(sentence)[0]['translation_text']
160
+ translated_sentences.append(translation)
161
+
162
+ return ' '.join(translated_sentences) # Return the translated sentences list elements as one String
163
+
164
+ # Function to check if the image URL is valid and fetches the image
165
+ def fetch_image_from_url(url):
166
+ try:
167
+ response = requests.get(url, stream=True)
168
+ response.raise_for_status() # Check if the request was successful
169
+ return Image.open(BytesIO(response.content)) # Return the image if valid
170
+ except Exception as e:
171
+ print(f"Error fetching image from {url}: {str(e)}")
172
+ return None
173
+
174
+ # Process the result where result is shown base on selected language
175
+ def process_best_match(best_match, language):
176
+ best_image_url = best_match["image_url"]
177
+ best_story = best_match["Story"]
178
+
179
+ # Translate to Arabic if the language is Arabic
180
+ if language == "Arabic":
181
+ best_story_translated = translate_story_to_arabic(best_story)
182
+ info_html = f"<div dir='rtl' style='font-size: 18px; color: white; font-family: Arial, sans-serif;'>{best_story_translated}</div>"
183
+ audio_file = text_to_speech_arabic(best_story_translated)
184
+ return best_image_url, info_html, audio_file
185
+
186
+ # Otherwise, use English
187
+ info_html = f"<div style='font-size: 18px; color: white;'>{best_story}</div>"
188
+ tts = gTTS(text=best_story, lang='en')
189
+ tts.save("best_story_english.mp3")
190
+ return best_image_url, info_html, "best_story_english.mp3"
191
+
192
+ # Function to match the uploaded image with the DataFrame to retrive the image of painting from the Datafram and it story in text and audio
193
+ def compare_images(image, language):
194
+ try:
195
+ inputs = processor(images=image, return_tensors="pt")
196
+ image_features = model.get_image_features(**inputs)
197
+
198
+ best_score = -2.0
199
+ best_match_idx = None
200
+
201
+ for idx, image_url in enumerate(df['image_url']):
202
+ db_image = fetch_image_from_url(image_url)
203
+ if db_image is None:
204
+ continue
205
+
206
+ try:
207
+ db_inputs = processor(images=db_image, return_tensors="pt")
208
+ db_image_features = model.get_image_features(**db_inputs)
209
+
210
+ similarity = torch.nn.functional.cosine_similarity(image_features, db_image_features).item()
211
+ if similarity > best_score:
212
+ best_score = similarity
213
+ best_match_idx = idx
214
+ except UnidentifiedImageError:
215
+ continue
216
+
217
+ if best_match_idx is None:
218
+ return None, "Error: No valid image match found in the database.", None
219
+
220
+ best_match = df.iloc[best_match_idx]
221
+ return process_best_match(best_match, language)
222
+
223
+ except UnidentifiedImageError:
224
+ return None, "Error: The uploaded file is not a valid image.", None
225
+ except Exception as e:
226
+ return None, f"Error: {str(e)}", None
227
+
228
+ # Function to compare user input with descriptions in the DataFrame and return the best match Painting as image of painting with text and audio story of painting
229
+ def compare_description(input_text):
230
+ try:
231
+ language = detect(input_text) #detect the langauge of input
232
+ if language == 'ar':
233
+ input_text = translator_ar_to_en(input_text)[0]['translation_text']
234
+
235
+ input_embedding = semantic_model.encode(input_text, convert_to_tensor=True)
236
+ df_embeddings = semantic_model.encode(df["Description"].tolist(), convert_to_tensor=True)
237
+
238
+ similarities = util.pytorch_cos_sim(input_embedding, df_embeddings).squeeze()
239
+ best_match_idx = torch.argmax(similarities).item()
240
+ best_match = df.iloc[best_match_idx]
241
+
242
+ return process_best_match(best_match, language)
243
+
244
+ except Exception as e:
245
+ return None, f"Error: {str(e)}", None
246
+
247
+ # Custom CSS for Styling the Gradio
248
+
249
+ custom_css = """
250
+ .gradio-container {
251
+ background-image: url('https://images.squarespace-cdn.com/content/v1/587ee1eab3db2b428f68d221/1626734192415-LI75A3LVVFMJD5TVZ3HR/Gallery+2.jpg');
252
+ background-size: cover;
253
+ background-position: center;
254
+ background-repeat: no-repeat;
255
+ color: #333333;
256
+ font-family: 'Arial', sans-serif;
257
+ }
258
+
259
+ h1, #title, #description {
260
+ color: white !important;
261
+ }
262
+
263
+ #upload-text, #description-search-text {
264
+ color: white !important;
265
+ }
266
+
267
+ label, .gr-label {
268
+ color: #333333 !important;
269
+ }
270
+
271
+ button.primary {
272
+ background-color: #6A5ACD;
273
+ color: black;
274
+ border-radius: 10px;
275
+ padding: 10px;
276
+ margin: 5px;
277
+ font-size: 18px;
278
+ border: none;
279
+ transition: background-color 0.3s;
280
+ }
281
+
282
+ button.primary:hover {
283
+ background-color: #836FFF;
284
+ }
285
+
286
+ #image_output, #search_image_output {
287
+ border: 3px solid white;
288
+ border-radius: 10px;
289
+ }
290
+
291
+ /* Specifically targeting the example buttons */
292
+ .gr-examples button {
293
+ color: white !important;
294
+ background-color: transparent !important; /* Make the background blend in with the overall theme */
295
+ border: 1px solid white; /* Add a border if you want to highlight it */
296
+ }
297
+ """
298
+
299
+ image_upload_examples = [
300
+ ["https://pbs.twimg.com/media/DgAnD-FUcAAr3NT?format=jpg", "English"],
301
+ ["https://pbs.twimg.com/media/DgAnD-FUcAAr3NT?format=jpg", "Arabic"]
302
+ ]
303
+
304
+ # Sample Examples for the "Description Search" tab
305
+ description_search_examples = [
306
+ ["A painting of a swirling night sky over a town.", "English"],
307
+ ["امرأة بابتسامة غامضة.", "Arabic"]
308
+ ]
309
+
310
+ # Gradio interface with two tabs: "Image Upload" and "Description Search"
311
+ # Image Upload tab to get the Painting story by uploding an image
312
+ # Description Search tab is by getting Painting stroy by descriping the painting
313
+
314
+ with gr.Blocks(css=custom_css) as demo:
315
+ gr.Markdown("<h1 id='title'>Welcome to the Virtual Art Museum</h1>")
316
+ gr.Markdown("<p id='description'>Explore the most famous artworks. Upload an image or enter a description to learn about the story behind each piece.</p>")
317
+
318
+ with gr.Tab("Image Search"):
319
+ gr.Markdown("<h2 id='upload-text'>Upload Art to Recognize and Hear the Story Behind It</h2>")
320
+
321
+ image_input = gr.Image(type="pil", label="Upload an image of an art piece")
322
+ language_selector = gr.Radio(choices=["English", "Arabic"], label="Select Language for Story Narration", value="English")
323
+ recognize_button = gr.Button("Search")
324
+
325
+ image_output = gr.Image(label="Matched Art Piece", elem_id="image_output")
326
+ description_output = gr.HTML(label="Art Piece Information")
327
+ audio_output = gr.Audio(label="Narration of the Story")
328
+
329
+ recognize_button.click(compare_images, inputs=[image_input, language_selector], outputs=[image_output, description_output, audio_output])
330
+
331
+ gr.Examples(examples=image_upload_examples, inputs=[image_input, language_selector])
332
+ with gr.Tab("Description Search"):
333
+ gr.Markdown("<h2 id='description-search-text'>Description Search</h2>")
334
+
335
+ description_input = gr.Textbox(label="Enter a description (in English or Arabic)")
336
+ search_button = gr.Button("Search")
337
+
338
+ search_image_output = gr.Image(label="Matched Art Piece", elem_id="search_image_output")
339
+ search_description_output = gr.HTML(label="Art Piece Information")
340
+ search_audio_output = gr.Audio(label="Narration of the Story")
341
+
342
+ search_button.click(compare_description, inputs=description_input, outputs=[search_image_output, search_description_output, search_audio_output])
343
+
344
+ gr.Examples(examples=description_search_examples, inputs=description_input)
345
+
346
+ demo.launch()