jfforero commited on
Commit
5f9b6b2
·
verified ·
1 Parent(s): 9d4d0d9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -90
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import gradio as gr
 
2
  import numpy as np
3
  import librosa
4
  import requests
@@ -7,15 +8,11 @@ from PIL import Image
7
  import os
8
  from tensorflow.keras.models import load_model
9
  from faster_whisper import WhisperModel
10
- import random
11
  from textblob import TextBlob
12
  import torch
13
  import scipy.io.wavfile
14
  from transformers import AutoProcessor, MusicgenForConditionalGeneration
15
  import tempfile
16
- import base64
17
- import plotly.graph_objects as go
18
- from plotly.subplots import make_subplots
19
 
20
  # Load the emotion prediction model
21
  def load_emotion_model(model_path):
@@ -213,95 +210,49 @@ def generate_image(sentiment_prediction, transcribed_text):
213
  # Return a fallback image
214
  return Image.new('RGB', (1024, 512), color='white')
215
 
216
- # Function to create a visualization with both the equirectangular image and a 3D sphere
217
- # Function to create a visualization with both the equirectangular image and a 3D sphere
218
  def create_texture_and_sphere_preview(image):
219
  try:
220
- # Convert PIL image to numpy array
221
- img_array = np.array(image)
222
- height, width = img_array.shape[0], img_array.shape[1]
 
223
 
224
- # Create a subplot with the equirectangular image and a 3D sphere
225
- fig = make_subplots(
226
- rows=1, cols=2,
227
- subplot_titles=("Equirectangular Texture", "3D Sphere with Texture Mapping"),
228
- specs=[[{"type": "image"}, {"type": "scatter3d"}]],
229
- horizontal_spacing=0.1
230
- )
231
-
232
- # Add the equirectangular image to the first subplot
233
- fig.add_trace(go.Image(z=img_array), row=1, col=1)
234
-
235
- # Create sphere coordinates
236
- u_res, v_res = 50, 25
237
- u = np.linspace(0, 2 * np.pi, u_res)
238
- v = np.linspace(0, np.pi, v_res)
239
- u, v = np.meshgrid(u, v)
240
-
241
- # Convert spherical coordinates to Cartesian coordinates
242
- x = np.sin(v) * np.cos(u)
243
- y = np.sin(v) * np.sin(u)
244
- z = np.cos(v)
245
 
246
- # Sample colors from the equirectangular image based on UV coordinates
247
- # This approximates texture mapping by sampling the image at the correct UV coordinates
248
- texture_colors = np.zeros((v_res, u_res, 3), dtype=np.uint8)
249
 
250
- for i in range(v_res):
251
- for j in range(u_res):
252
- # Convert spherical coordinates to image coordinates
253
- img_x = int((u[i, j] / (2 * np.pi)) * (width - 1))
254
- img_y = int((v[i, j] / np.pi) * (height - 1))
255
-
256
- # Ensure coordinates are within bounds
257
- img_x = max(0, min(img_x, width - 1))
258
- img_y = max(0, min(img_y, height - 1))
259
-
260
- # Get color from image
261
- if len(img_array.shape) == 3: # RGB image
262
- texture_colors[i, j] = img_array[img_y, img_x, :3]
263
- else: # Grayscale image
264
- texture_colors[i, j] = [img_array[img_y, img_x]] * 3
265
 
266
- # Convert colors to Plotly format (normalized to [0,1])
267
- surface_colors = texture_colors.astype(float) / 255.0
 
268
 
269
- # Create surface with sampled colors
270
- fig.add_trace(go.Surface(
271
- x=x, y=y, z=z,
272
- surfacecolor=surface_colors,
273
- showscale=False,
274
- opacity=1.0,
275
- lighting=dict(ambient=0.8, diffuse=0.8, specular=0.1, roughness=0.5),
276
- lightposition=dict(x=100, y=100, z=100)
277
- ), row=1, col=2)
278
 
279
- # Update layout
280
- fig.update_layout(
281
- height=500,
282
- title_text="Equirectangular Texture and 3D Sphere Preview",
283
- showlegend=False,
284
- scene2=dict(
285
- xaxis=dict(visible=False, showticklabels=False),
286
- yaxis=dict(visible=False, showticklabels=False),
287
- zaxis=dict(visible=False, showticklabels=False),
288
- aspectmode='data',
289
- camera=dict(
290
- eye=dict(x=1.8, y=1.8, z=1.8)
291
- ),
292
- bgcolor='rgba(0,0,0,0)'
293
- )
294
- )
295
-
296
- # Update axes for the image subplot
297
- fig.update_xaxes(visible=False, row=1, col=1)
298
- fig.update_yaxes(visible=False, row=1, col=1)
299
 
300
- return fig
 
 
 
 
301
 
302
- except Exception as e:
303
- print("Error creating texture and sphere preview:", e)
304
- return go.Figure()
305
 
306
  # Function to get predictions
307
  def get_predictions(audio_input):
@@ -320,10 +271,10 @@ def get_predictions(audio_input):
320
  # Generate music using ACOUSTIC EMOTION prediction with specific prompt
321
  music_path = generate_music(transcribed_text, emotion_prediction)
322
 
323
- # Create visualization with both texture and sphere
324
- preview_fig = create_texture_and_sphere_preview(image)
325
 
326
- return emotion_prediction, transcribed_text, f"Sentiment: {sentiment} (Polarity: {polarity:.2f})", image, music_path, preview_fig
327
 
328
  # Create the Gradio interface
329
  interface = gr.Interface(
@@ -333,12 +284,11 @@ interface = gr.Interface(
333
  gr.Label(label="Acoustic Emotion Prediction (for music)"),
334
  gr.Label(label="Transcribed Text"),
335
  gr.Label(label="Sentiment Analysis (for image)"),
336
- gr.Image(type='pil', label="Generated Equirectangular Image"),
337
- gr.Audio(label="Generated Music", type="filepath"),
338
- gr.Plot(label="Texture and Sphere Preview")
339
  ],
340
  title="Affective Virtual Environments",
341
- description="Create an AVE using your voice. Get emotion prediction (for music), transcription, sentiment analysis (for image), a generated equirectangular image, music, and a preview of how it would look as a texture on a sphere."
342
  )
343
 
344
  interface.launch()
 
1
  import gradio as gr
2
+ import pyvista as pv
3
  import numpy as np
4
  import librosa
5
  import requests
 
8
  import os
9
  from tensorflow.keras.models import load_model
10
  from faster_whisper import WhisperModel
 
11
  from textblob import TextBlob
12
  import torch
13
  import scipy.io.wavfile
14
  from transformers import AutoProcessor, MusicgenForConditionalGeneration
15
  import tempfile
 
 
 
16
 
17
  # Load the emotion prediction model
18
  def load_emotion_model(model_path):
 
210
  # Return a fallback image
211
  return Image.new('RGB', (1024, 512), color='white')
212
 
213
+ # Function to create a proper texture-mapped sphere visualization using PyVista
 
214
  def create_texture_and_sphere_preview(image):
215
  try:
216
+ # Save image to temporary file
217
+ with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
218
+ image.save(tmp.name)
219
+ texture_file = tmp.name
220
 
221
+ # Create a sphere with PyVista
222
+ sphere = pv.Sphere(radius=1, theta_resolution=100, phi_resolution=50)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
+ # Load and apply the texture
225
+ texture = pv.read_texture(texture_file)
 
226
 
227
+ # Plot with PyVista (off-screen rendering)
228
+ plotter = pv.Plotter(off_screen=True, window_size=[800, 400])
229
+ plotter.add_mesh(sphere, texture=texture)
230
+ plotter.camera_position = 'xy'
231
+ plotter.camera.azimuth = 30
232
+ plotter.camera.elevation = 30
233
+ plotter.background_color = 'white'
 
 
 
 
 
 
 
 
234
 
235
+ # Capture the image
236
+ img_array = plotter.screenshot(transparent_background=False)
237
+ plotter.close()
238
 
239
+ # Convert to PIL Image
240
+ return Image.fromarray(img_array)
 
 
 
 
 
 
 
241
 
242
+ except Exception as e:
243
+ print("Error creating texture and sphere preview with PyVista:", e)
244
+ # Fallback: create a composite image showing both
245
+ width, height = image.size
246
+ composite = Image.new('RGB', (width * 2, height), color='white')
247
+ composite.paste(image, (0, 0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
 
249
+ # Add text indicating the sphere visualization
250
+ from PIL import ImageDraw
251
+ draw = ImageDraw.Draw(composite)
252
+ draw.text((width + 20, height//2 - 20), "3D Sphere Preview", fill='black')
253
+ draw.text((width + 20, height//2), "(Texture mapped sphere)", fill='gray')
254
 
255
+ return composite
 
 
256
 
257
  # Function to get predictions
258
  def get_predictions(audio_input):
 
271
  # Generate music using ACOUSTIC EMOTION prediction with specific prompt
272
  music_path = generate_music(transcribed_text, emotion_prediction)
273
 
274
+ # Create visualization with texture mapped sphere
275
+ sphere_visualization = create_texture_and_sphere_preview(image)
276
 
277
+ return emotion_prediction, transcribed_text, f"Sentiment: {sentiment} (Polarity: {polarity:.2f})", sphere_visualization, music_path
278
 
279
  # Create the Gradio interface
280
  interface = gr.Interface(
 
284
  gr.Label(label="Acoustic Emotion Prediction (for music)"),
285
  gr.Label(label="Transcribed Text"),
286
  gr.Label(label="Sentiment Analysis (for image)"),
287
+ gr.Image(type='pil', label="Texture Mapped Sphere Visualization"),
288
+ gr.Audio(label="Generated Music", type="filepath")
 
289
  ],
290
  title="Affective Virtual Environments",
291
+ description="Create an AVE using your voice. Get emotion prediction (for music), transcription, sentiment analysis (for image), a texture-mapped sphere visualization, and generated music."
292
  )
293
 
294
  interface.launch()