eusholli commited on
Commit
59844f8
·
1 Parent(s): cae98ae

updated README and link to README

Browse files
Files changed (2) hide show
  1. README.md +190 -4
  2. app.py +41 -19
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Sentiment Analyzer
3
  emoji: 🦀
4
  colorFrom: indigo
5
  colorTo: blue
@@ -10,12 +10,198 @@ pinned: false
10
  license: mit
11
  ---
12
 
13
- # Facial Sentiment Analysis with Streamlit
14
 
15
- This Streamlit application streams video from the webcam, analyzes facial sentiment, and displays the results in real-time.
16
 
17
  ## How to Use
18
 
19
  1. Clone the repository.
20
  2. Ensure you have the necessary packages installed: `pip install -r requirements.txt`
21
- 3. Run the application: `streamlit run app.py`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Computer Vision Playground
3
  emoji: 🦀
4
  colorFrom: indigo
5
  colorTo: blue
 
10
  license: mit
11
  ---
12
 
13
+ # Computer Vision Playground
14
 
15
+ This Streamlit application streams video from the webcam, analyzes facial sentiment, and displays the results in real-time. It serves as a playground for computer vision projects, with an example facial sentiment analysis demo.
16
 
17
  ## How to Use
18
 
19
  1. Clone the repository.
20
  2. Ensure you have the necessary packages installed: `pip install -r requirements.txt`
21
+ 3. Run the application: `streamlit run app.py`
22
+
23
+ ## Create Your Own Analysis Space
24
+
25
+ Follow these steps to set up and modify the application for your own image analysis:
26
+
27
+ ### Step 1: Clone the Repository
28
+
29
+ First, you need to clone the repository to your local machine. Open your terminal or command prompt and run:
30
+
31
+ ```sh
32
+ git clone https://huggingface.co/spaces/eusholli/computer-vision-playground
33
+ cd computer-vision-playground
34
+ ```
35
+
36
+
37
+ ### Step 2: Install Dependencies
38
+
39
+ Make sure you have Python installed on your machine. You can download it from [python.org](https://www.python.org/).
40
+
41
+ Next, install the required packages. In the terminal, navigate to the cloned repository directory and run:
42
+
43
+ ```sh
44
+ pip install -r requirements.txt
45
+ ```
46
+
47
+ This will install all the necessary libraries specified in the \`requirements.txt\` file.
48
+
49
+ ### Step 3: Run the Application
50
+
51
+ To start the Streamlit application, run:
52
+
53
+ ```sh
54
+ streamlit run app.py
55
+ ```
56
+
57
+ This will open a new tab in your default web browser with the Streamlit interface.
58
+
59
+ ### Step 4: Using the Application
60
+
61
+ #### Webcam Stream
62
+
63
+ - Allow access to your webcam when prompted.
64
+ - You will see the live stream from your webcam in the "Input Stream" section.
65
+ - The application will analyze the video frames in real-time and display the sentiment results in the "Analysis" section.
66
+
67
+ #### Uploading Images
68
+
69
+ - In the "Input Stream" section, under "Upload an Image", click on the "Choose an image..." button.
70
+ - Select an image file (jpg, jpeg, png) from your computer.
71
+ - The application will analyze the uploaded image and display the sentiment results.
72
+
73
+ #### Image URL
74
+
75
+ - In the "Input Stream" section, under "Or Enter Image URL", paste an image URL and press Enter.
76
+ - The application will download and analyze the image from the provided URL and display the sentiment results.
77
+
78
+ #### Uploading Videos
79
+
80
+ - In the "Input Stream" section, under "Upload a Video", click on the "Choose a video..." button.
81
+ - Select a video file (mp4, avi, mov, mkv) from your computer.
82
+ - The application will analyze the video frames and display the sentiment results.
83
+
84
+ #### Video URL
85
+
86
+ - In the "Input Stream" section, under "Or Enter Video Download URL", paste a video URL and press Enter.
87
+ - The application will download and analyze the video from the provided URL and display the sentiment results.
88
+
89
+ ### Step 5: Customize the Analysis
90
+
91
+ You can customize the analysis function to perform your own image analysis. The default function \`analyze_frame\` performs facial sentiment analysis. To use your own analysis:
92
+
93
+ 1. Replace the contents of the \`analyze_frame\` function in \`app.py\` with your custom analysis code.
94
+ 2. Update any necessary imports at the top of the \`app.py\` file.
95
+ 3. Adjust the \`ANALYSIS_TITLE\` variable to reflect your custom analysis.
96
+
97
+ Example:
98
+
99
+ ```python
100
+ ANALYSIS_TITLE = "Custom Analysis"
101
+
102
+ def analyze_frame(frame: np.ndarray):
103
+ # Your custom analysis code here
104
+ ...
105
+ ```
106
+
107
+ ### Troubleshooting
108
+
109
+ If you encounter any issues:
110
+
111
+ - Ensure all dependencies are correctly installed.
112
+ - Check that your webcam is working and accessible.
113
+ - Verify the URLs you provide are correct and accessible.
114
+
115
+ For more detailed information, refer to the comments in the \`app.py\` file.
116
+
117
+ # How to Create a New Huggingface Space and Push Code to It
118
+
119
+ ## Step 1: Create a New Huggingface Space
120
+ 1. Log in to your [Huggingface](https://huggingface.co/) account.
121
+ 2. Go to the [Spaces](https://huggingface.co/spaces) section.
122
+ 3. Click on the **Create new Space** button.
123
+ 4. Fill in the details for your new Space:
124
+ - **Space name**: Choose a unique name for your Space.
125
+ - **Owner**: Ensure your username is selected.
126
+ - **Visibility**: Choose between Public or Private based on your preference.
127
+ - **SDK**: Select the SDK you will use (in this case`streamlit`).
128
+ 5. Click on the **Create Space** button to create your new Space.
129
+
130
+ ## Step 2: Change the Local Git Remote Repo Reference
131
+ 1. Open your terminal or command prompt.
132
+ 2. Navigate to your local project directory:
133
+ ```bash
134
+ cd /path/to/your/project
135
+ ```
136
+ 3. Remove the existing remote reference (if any):
137
+ ```bash
138
+ git remote remove origin
139
+ ```
140
+ 4. Add the new remote reference pointing to your newly created Huggingface Space. Replace `<your-username>` and `<your-space-name>` with your actual Huggingface username and Space name:
141
+ ```bash
142
+ git remote add origin https://huggingface.co/spaces/<your-username>/<your-space-name>.git
143
+ ```
144
+
145
+ ## Step 3: Add, Commit, and Push the Code to the New Space
146
+ 1. Stage all the changes in your local project directory:
147
+ ```bash
148
+ git add .
149
+ ```
150
+ 2. Commit the changes with a meaningful commit message:
151
+ ```bash
152
+ git commit -m "Initial commit to Huggingface Space"
153
+ ```
154
+ 3. Push the changes to the new Huggingface Space:
155
+ ```bash
156
+ git push origin main
157
+ ```
158
+
159
+ > **Note**: If your default branch is not `main`, replace `main` with the appropriate branch name in the push command.
160
+
161
+ ## Conclusion
162
+ You have now successfully created a new Huggingface Space, updated your local Git remote reference, and pushed your code to the new Space. You can verify that your code has been uploaded by visiting your Huggingface Space's URL.
163
+
164
+ ## Webcam STUN/TURN Server
165
+
166
+ When running remotely on Huggingface, the code needs to access your remote webcam. It does this using the [streamlit-webrtc](https://github.com/whitphx/streamlit-webrtc) module but requires a Twilio account to be established and the credentials uploaded to the Huggingface space.
167
+
168
+ ### How to Create a Free Twilio Account and Add Credentials to Huggingface Space Settings
169
+
170
+ #### Step 1: Create a Free Twilio Account
171
+ 1. Go to the [Twilio Sign-Up Page](https://www.twilio.com/try-twilio).
172
+ 2. Fill in your details to create a new account.
173
+ 3. Verify your email address and phone number.
174
+ 4. After verification, log in to your Twilio dashboard.
175
+
176
+ #### Step 2: Obtain `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN`
177
+ 1. In the Twilio dashboard, navigate to the **Console**.
178
+ 2. Look for the **Account Info** section on the dashboard.
179
+ 3. Here, you will find your `Account SID` (referred to as `TWILIO_ACCOUNT_SID`).
180
+ 4. To obtain your `Auth Token` (referred to as `TWILIO_AUTH_TOKEN`), click on the **Show** button next to the `Auth Token`.
181
+
182
+ #### Step 3: Add Twilio Credentials to Huggingface Space Settings
183
+ 1. Log in to your [Huggingface](https://huggingface.co/) account.
184
+ 2. Navigate to your Huggingface Space where you need to add the credentials.
185
+ 3. Go to the **Settings** of your Space.
186
+ 4. In the **Variables and secrets** section:
187
+ - Click on the **New variable** button to add `TWILIO_ACCOUNT_SID`:
188
+ - Name: `TWILIO_ACCOUNT_SID`
189
+ - Value: Copy your `Account SID` from the Twilio dashboard and paste it here.
190
+ - Click on the **New secret** button to add `TWILIO_AUTH_TOKEN`:
191
+ - Name: `TWILIO_AUTH_TOKEN`
192
+ - Value: Copy your `Auth Token` from the Twilio dashboard and paste it here.
193
+
194
+ 5. Save the changes.
195
+
196
+ You have now successfully added your Twilio credentials to the Huggingface Space settings. Your application should now be able to access and use the Twilio API for WebRTC functionality.
197
+
198
+
199
+
200
+
201
+ ### Contributing
202
+
203
+ We welcome contributions! If you have suggestions or improvements, feel free to open an issue or submit a pull request.
204
+
205
+ ### License
206
+
207
+ This project is licensed under the MIT License.
app.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import time
2
  import os
3
  import logging
@@ -38,12 +40,10 @@ result_queue: "queue.Queue[List[Detection]]" = queue.Queue()
38
 
39
  # Appropriate imports needed for analysis
40
 
41
- from mtcnn import MTCNN # Import MTCNN for face detection
42
- from PIL import Image, ImageDraw # Import PIL for image processing
43
- from transformers import pipeline # Import Hugging Face transformers pipeline
44
 
45
  # Initialize the Hugging Face pipeline for facial emotion detection
46
- emotion_pipeline = pipeline("image-classification", model="trpakov/vit-face-expression")
 
47
 
48
 
49
  # Default title - "Facial Sentiment Analysis"
@@ -76,8 +76,9 @@ def analyze_frame(frame: np.ndarray):
76
  results = mtcnn.detect_faces(frame) # Detect faces in the frame
77
  for result in results:
78
  x, y, w, h = result["box"] # Get the bounding box of the detected face
79
- face = frame[y : y + h, x : x + w] # Extract the face from the frame
80
- sentiment = analyze_sentiment(face) # Analyze the sentiment of the face
 
81
  result["label"] = sentiment
82
  # Draw a rectangle around the face
83
  cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), LINE_SIZE)
@@ -89,7 +90,8 @@ def analyze_frame(frame: np.ndarray):
89
  background_tl = (text_x, text_y - text_size[1])
90
  background_br = (text_x + text_size[0], text_y + 5)
91
  # Draw a black background for the text
92
- cv2.rectangle(frame, background_tl, background_br, (0, 0, 0), cv2.FILLED)
 
93
  # Put the sentiment text on the image
94
  cv2.putText(
95
  frame,
@@ -105,7 +107,8 @@ def analyze_frame(frame: np.ndarray):
105
  execution_time_ms = round(
106
  (end_time - start_time) * 1000, 2
107
  ) # Calculate execution time in milliseconds
108
- img_container["analysis_time"] = execution_time_ms # Store the execution time
 
109
 
110
  result_queue.put(results) # Put the results in the result queue
111
  img_container["analyzed"] = frame # Store the analyzed frame
@@ -118,7 +121,8 @@ def analyze_frame(frame: np.ndarray):
118
  # uses a pre-trained emotion detection model to get emotion predictions,
119
  # and finally returns the most dominant emotion detected.
120
  def analyze_sentiment(face):
121
- rgb_face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB) # Convert face to RGB format
 
122
  pil_image = Image.fromarray(rgb_face) # Convert to PIL image
123
  results = emotion_pipeline(pil_image) # Run emotion detection on the image
124
  dominant_emotion = max(results, key=lambda x: x["score"])[
@@ -137,13 +141,11 @@ def analyze_sentiment(face):
137
  os.environ["FFMPEG_LOG_LEVEL"] = "quiet"
138
 
139
  # Suppress TensorFlow or PyTorch progress bars
140
- import tensorflow as tf
141
 
142
  tf.get_logger().setLevel("ERROR")
143
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
144
 
145
  # Suppress PyTorch logs
146
- import torch
147
 
148
  logging.getLogger().setLevel(logging.WARNING)
149
  torch.set_num_threads(1)
@@ -167,7 +169,8 @@ logger = logging.getLogger(__name__)
167
  # It converts the frame to a numpy array in RGB format, analyzes the frame,
168
  # and returns the original frame.
169
  def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
170
- img = frame.to_ndarray(format="rgb24") # Convert frame to numpy array in RGB format
 
171
  analyze_frame(img) # Analyze the frame
172
  return frame # Return the original frame
173
 
@@ -207,6 +210,18 @@ st.markdown(
207
 
208
  # Streamlit page title and subtitle
209
  st.title("Computer Vision Playground")
 
 
 
 
 
 
 
 
 
 
 
 
210
  st.subheader(ANALYSIS_TITLE)
211
 
212
  # Columns for input and output streams
@@ -227,7 +242,8 @@ with col1:
227
 
228
  # File uploader for images
229
  st.subheader("Upload an Image")
230
- uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
 
231
 
232
  # Text input for image URL
233
  st.subheader("Or Enter Image URL")
@@ -283,12 +299,14 @@ def publish_frame():
283
  analyzed = img_container["analyzed"]
284
  if analyzed is None:
285
  return
286
- output_placeholder.image(analyzed, channels="RGB") # Display the analyzed frame
 
287
 
288
  time = img_container["analysis_time"]
289
  if time is None:
290
  return
291
- analysis_time.text(f"Analysis Time: {time} ms") # Display the analysis time
 
292
 
293
 
294
  # If the WebRTC streamer is playing, initialize and publish frames
@@ -308,7 +326,8 @@ if uploaded_file is not None or image_url:
308
  img = np.array(image.convert("RGB")) # Convert the image to RGB format
309
  else:
310
  response = requests.get(image_url) # Download the image from the URL
311
- image = Image.open(BytesIO(response.content)) # Open the downloaded image
 
312
  img = np.array(image.convert("RGB")) # Convert the image to RGB format
313
 
314
  analyze_frame(img) # Analyze the image
@@ -325,7 +344,8 @@ def process_video(video_path):
325
  if not ret:
326
  break # Exit the loop if no more frames are available
327
 
328
- input_placeholder.image(frame) # Display the current frame as the input frame
 
329
  analyze_frame(
330
  frame
331
  ) # Analyze the frame for face detection and sentiment analysis
@@ -348,8 +368,10 @@ if uploaded_video is not None or video_url:
348
  if uploaded_video is not None:
349
  video_path = uploaded_video.name # Get the name of the uploaded video
350
  with open(video_path, "wb") as f:
351
- f.write(uploaded_video.getbuffer()) # Save the uploaded video to a file
 
352
  else:
353
- video_path = download_file(video_url) # Download the video from the URL
 
354
 
355
  process_video(video_path) # Process the video
 
1
+ import torch
2
+ import tensorflow as tf
3
  import time
4
  import os
5
  import logging
 
40
 
41
  # Appropriate imports needed for analysis
42
 
 
 
 
43
 
44
  # Initialize the Hugging Face pipeline for facial emotion detection
45
+ emotion_pipeline = pipeline("image-classification",
46
+ model="trpakov/vit-face-expression")
47
 
48
 
49
  # Default title - "Facial Sentiment Analysis"
 
76
  results = mtcnn.detect_faces(frame) # Detect faces in the frame
77
  for result in results:
78
  x, y, w, h = result["box"] # Get the bounding box of the detected face
79
+ face = frame[y: y + h, x: x + w] # Extract the face from the frame
80
+ # Analyze the sentiment of the face
81
+ sentiment = analyze_sentiment(face)
82
  result["label"] = sentiment
83
  # Draw a rectangle around the face
84
  cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), LINE_SIZE)
 
90
  background_tl = (text_x, text_y - text_size[1])
91
  background_br = (text_x + text_size[0], text_y + 5)
92
  # Draw a black background for the text
93
+ cv2.rectangle(frame, background_tl, background_br,
94
+ (0, 0, 0), cv2.FILLED)
95
  # Put the sentiment text on the image
96
  cv2.putText(
97
  frame,
 
107
  execution_time_ms = round(
108
  (end_time - start_time) * 1000, 2
109
  ) # Calculate execution time in milliseconds
110
+ # Store the execution time
111
+ img_container["analysis_time"] = execution_time_ms
112
 
113
  result_queue.put(results) # Put the results in the result queue
114
  img_container["analyzed"] = frame # Store the analyzed frame
 
121
  # uses a pre-trained emotion detection model to get emotion predictions,
122
  # and finally returns the most dominant emotion detected.
123
  def analyze_sentiment(face):
124
+ # Convert face to RGB format
125
+ rgb_face = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
126
  pil_image = Image.fromarray(rgb_face) # Convert to PIL image
127
  results = emotion_pipeline(pil_image) # Run emotion detection on the image
128
  dominant_emotion = max(results, key=lambda x: x["score"])[
 
141
  os.environ["FFMPEG_LOG_LEVEL"] = "quiet"
142
 
143
  # Suppress TensorFlow or PyTorch progress bars
 
144
 
145
  tf.get_logger().setLevel("ERROR")
146
  os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
147
 
148
  # Suppress PyTorch logs
 
149
 
150
  logging.getLogger().setLevel(logging.WARNING)
151
  torch.set_num_threads(1)
 
169
  # It converts the frame to a numpy array in RGB format, analyzes the frame,
170
  # and returns the original frame.
171
  def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
172
+ # Convert frame to numpy array in RGB format
173
+ img = frame.to_ndarray(format="rgb24")
174
  analyze_frame(img) # Analyze the frame
175
  return frame # Return the original frame
176
 
 
210
 
211
  # Streamlit page title and subtitle
212
  st.title("Computer Vision Playground")
213
+
214
+ # Add a link to the README file
215
+ st.markdown(
216
+ """
217
+ <div style="text-align: left;">
218
+ <p>See the <a href="https://huggingface.co/spaces/eusholli/sentiment-analyzer/blob/main/README.md"
219
+ target="_blank">README</a> to learn how to use this code to help you start your computer vision exploration.</p>
220
+ </div>
221
+ """,
222
+ unsafe_allow_html=True,
223
+ )
224
+
225
  st.subheader(ANALYSIS_TITLE)
226
 
227
  # Columns for input and output streams
 
242
 
243
  # File uploader for images
244
  st.subheader("Upload an Image")
245
+ uploaded_file = st.file_uploader(
246
+ "Choose an image...", type=["jpg", "jpeg", "png"])
247
 
248
  # Text input for image URL
249
  st.subheader("Or Enter Image URL")
 
299
  analyzed = img_container["analyzed"]
300
  if analyzed is None:
301
  return
302
+ # Display the analyzed frame
303
+ output_placeholder.image(analyzed, channels="RGB")
304
 
305
  time = img_container["analysis_time"]
306
  if time is None:
307
  return
308
+ # Display the analysis time
309
+ analysis_time.text(f"Analysis Time: {time} ms")
310
 
311
 
312
  # If the WebRTC streamer is playing, initialize and publish frames
 
326
  img = np.array(image.convert("RGB")) # Convert the image to RGB format
327
  else:
328
  response = requests.get(image_url) # Download the image from the URL
329
+ # Open the downloaded image
330
+ image = Image.open(BytesIO(response.content))
331
  img = np.array(image.convert("RGB")) # Convert the image to RGB format
332
 
333
  analyze_frame(img) # Analyze the image
 
344
  if not ret:
345
  break # Exit the loop if no more frames are available
346
 
347
+ # Display the current frame as the input frame
348
+ input_placeholder.image(frame)
349
  analyze_frame(
350
  frame
351
  ) # Analyze the frame for face detection and sentiment analysis
 
368
  if uploaded_video is not None:
369
  video_path = uploaded_video.name # Get the name of the uploaded video
370
  with open(video_path, "wb") as f:
371
+ # Save the uploaded video to a file
372
+ f.write(uploaded_video.getbuffer())
373
  else:
374
+ # Download the video from the URL
375
+ video_path = download_file(video_url)
376
 
377
  process_video(video_path) # Process the video