NourFakih commited on
Commit
b8d4642
·
verified ·
1 Parent(s): 8a6dcf3

Upload 2 files

Browse files
Files changed (2) hide show
  1. requirements (2).txt +10 -0
  2. streamlit_app.py +284 -0
requirements (2).txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ transformers
3
+ torch
4
+ streamlit
5
+ opencv-python
6
+ opencv-python-headless
7
+ opencv-contrib-python-headless
8
+ Pillow
9
+ pandas
10
+ nltk
streamlit_app.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import cv2
4
+ import tempfile
5
+ import zipfile
6
+ from PIL import Image
7
+ from transformers import VisionEncoderDecoderModel, ViTFeatureExtractor, AutoTokenizer, pipeline
8
+ import torch
9
+ import pandas as pd
10
+ from nltk.corpus import wordnet
11
+ import nltk
12
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
13
+ from datetime import datetime
14
+ import base64
15
+ import io
16
+
17
+ nltk.download('wordnet')
18
+ nltk.download('omw-1.4')
19
+
20
+ # Load the pre-trained model for image captioning
21
+ model_name = "NourFakih/Vit-GPT2-COCO2017Flickr-85k-09"
22
+ model = VisionEncoderDecoderModel.from_pretrained(model_name)
23
+ feature_extractor = ViTFeatureExtractor.from_pretrained(model_name)
24
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
25
+
26
+ model_sum_name = "google-t5/t5-base"
27
+ tokenizer_sum = AutoTokenizer.from_pretrained("google-t5/t5-base")
28
+ model_sum = AutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-base")
29
+ # Initialize the summarization model
30
+ summarize_pipe = pipeline("summarization", model=model_sum_name)
31
+
32
+ captured_images = []
33
+
34
+ def generate_caption(image):
35
+ pixel_values = feature_extractor(images=image, return_tensors="pt").pixel_values
36
+ output_ids = model.generate(pixel_values)
37
+ caption = tokenizer.decode(output_ids[0], skip_special_tokens=True)
38
+ return caption
39
+
40
+ def get_synonyms(word):
41
+ synonyms = set()
42
+ for syn in wordnet.synsets(word):
43
+ for lemma in syn.lemmas():
44
+ synonyms.add(lemma.name())
45
+ return synonyms
46
+
47
+ def search_captions(query, captions):
48
+ query_words = query.split()
49
+ query_synonyms = set(query_words)
50
+ for word in query_words:
51
+ query_synonyms.update(get_synonyms(word))
52
+
53
+ results = []
54
+ for path, caption in captions.items():
55
+ if any(word in caption.split() for word in query_synonyms):
56
+ results.append((path, caption))
57
+
58
+ return results
59
+
60
+ def image_captioning_page():
61
+ st.title("Image Gallery with Captioning and Search")
62
+
63
+ # Sidebar for search functionality
64
+ with st.sidebar:
65
+ query = st.text_input("Search images by caption:")
66
+
67
+ # Right side for folder path input and displaying images
68
+ option = st.selectbox("Select input method:", ["Folder Path", "Upload Images"])
69
+
70
+ if option == "Folder Path":
71
+ folder_path = st.text_input("Enter the folder path containing images:")
72
+ image_files = []
73
+ if folder_path and os.path.isdir(folder_path):
74
+ image_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.lower().endswith(('png', 'jpg', 'jpeg'))]
75
+ else:
76
+ uploaded_files = st.file_uploader("Upload images or a zip file containing images:", type=['png', 'jpg', 'jpeg', 'zip'], accept_multiple_files=True)
77
+ image_files = []
78
+ if uploaded_files:
79
+ for uploaded_file in uploaded_files:
80
+ if uploaded_file.name.endswith('.zip'):
81
+ with zipfile.ZipFile(uploaded_file, 'r') as zip_ref:
82
+ zip_ref.extractall("uploaded_images")
83
+ for file in zip_ref.namelist():
84
+ if file.lower().endswith(('png', 'jpg', 'jpeg')):
85
+ image_files.append(os.path.join("uploaded_images", file))
86
+ else:
87
+ if uploaded_file.name.lower().endswith(('png', 'jpg', 'jpeg')):
88
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1])
89
+ temp_file.write(uploaded_file.read())
90
+ image_files.append(temp_file.name)
91
+
92
+ captions = {}
93
+ if st.button("Generate Captions"):
94
+ for image_file in image_files:
95
+ try:
96
+ image = Image.open(image_file)
97
+ caption = generate_caption(image)
98
+ if option == "Folder Path":
99
+ captions[os.path.join(folder_path, os.path.basename(image_file))] = caption
100
+ else:
101
+ if image_file.startswith("uploaded_images"):
102
+ captions[image_file.replace("uploaded_images/", "")] = caption
103
+ else:
104
+ captions[os.path.basename(image_file)] = caption
105
+ except Exception as e:
106
+ st.error(f"Error processing {image_file}: {e}")
107
+
108
+ # Display images in a 4-column grid
109
+ st.subheader("Images and Captions:")
110
+ cols = st.columns(4)
111
+ idx = 0
112
+ for image_path, caption in captions.items():
113
+ col = cols[idx % 4]
114
+ with col:
115
+ try:
116
+ with open(image_path, "rb") as img_file:
117
+ img_bytes = img_file.read()
118
+ encoded_image = base64.b64encode(img_bytes).decode()
119
+ st.markdown(
120
+ f"""
121
+ <div style='text-align: center;'>
122
+ <img src='data:image/jpeg;base64,{encoded_image}' width='100%'>
123
+ <p>{caption}</p>
124
+ </div>
125
+ """, unsafe_allow_html=True)
126
+ except Exception as e:
127
+ st.error(f"Error displaying {image_path}: {e}")
128
+ idx += 1
129
+
130
+ if query:
131
+ results = search_captions(query, captions)
132
+ st.write("Search Results:")
133
+ for image_path, caption in results:
134
+ try:
135
+ with open(image_path, "rb") as img_file:
136
+ img_bytes = img_file.read()
137
+ st.image(img_bytes, caption=caption, width=150)
138
+ st.write(caption)
139
+ except Exception as e:
140
+ st.error(f"Error displaying search result {image_path}: {e}")
141
+
142
+ # Save captions to Excel and provide a download button
143
+ df = pd.DataFrame(list(captions.items()), columns=['Image', 'Caption'])
144
+ excel_file = io.BytesIO()
145
+ df.to_excel(excel_file, index=False)
146
+ excel_file.seek(0)
147
+ st.download_button(label="Download captions as Excel",
148
+ data=excel_file,
149
+ file_name="captions.xlsx",
150
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
151
+
152
+ def live_camera_captioning_page():
153
+ st.title("Live Captioning with Webcam")
154
+ run = st.checkbox('Run')
155
+ FRAME_WINDOW = st.image([])
156
+
157
+ if 'camera' not in st.session_state:
158
+ st.session_state.camera = cv2.VideoCapture(0)
159
+
160
+ if run:
161
+ while run:
162
+ ret, frame = st.session_state.camera.read()
163
+ if not ret:
164
+ st.write("Failed to capture image.")
165
+ break
166
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
167
+ FRAME_WINDOW.image(frame)
168
+ pil_image = Image.fromarray(frame)
169
+ caption = generate_caption(pil_image)
170
+ capture_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
171
+ captured_images.append((frame, caption, capture_time))
172
+ st.write("Caption: ", caption)
173
+ cv2.waitKey(500) # Capture an image every 0.5 seconds
174
+
175
+ if not run and 'camera' in st.session_state:
176
+ st.session_state.camera.release()
177
+ del st.session_state.camera
178
+
179
+ st.sidebar.title("Search Captions")
180
+ query = st.sidebar.text_input("Enter a word to search in captions:")
181
+ if st.sidebar.button("Search"):
182
+ results = search_captions(query, captured_images)
183
+ if results:
184
+ st.subheader("Search Results:")
185
+ cols = st.columns(4)
186
+ for idx, (image, caption, capture_time) in enumerate(results):
187
+ col = cols[idx % 4]
188
+ with col:
189
+ st.image(image, caption=f"{caption}\n\n*{capture_time}*", width=150)
190
+ else:
191
+ st.write("No matching captions found.")
192
+
193
+ if st.button("Generate Report"):
194
+ if captured_images:
195
+ # Display captured images in a 4-column grid
196
+ st.subheader("Captured Images and Captions:")
197
+ cols = st.columns(4)
198
+ for idx, (image, caption, capture_time) in enumerate(captured_images):
199
+ col = cols[idx % 4]
200
+ with col:
201
+ st.image(image, caption=f"{caption}\n\n*{capture_time}*", width=150)
202
+
203
+ # Save captions to Excel and provide a download button
204
+ df = pd.DataFrame(captured_images, columns=['Image', 'Caption', 'Capture Time'])
205
+ excel_file = tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx')
206
+ df.to_excel(excel_file.name, index=False)
207
+ st.download_button(label="Download Captions as Excel",
208
+ data=open(excel_file.name, 'rb').read(),
209
+ file_name="camera_captions.xlsx",
210
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
211
+
212
+ # Summarize captions in groups of 10
213
+ summaries = []
214
+ for i in range(0, len(captured_images), 10):
215
+ batch_captions = " ".join([captured_images[j][1] for j in range(i, min(i+10, len(captured_images)))])
216
+ summary = summarize_pipe(batch_captions)[0]['summary_text']
217
+ summaries.append((captured_images[i][2], summary)) # Use the capture time of the first image in the batch
218
+
219
+ # Save summaries to Excel and provide a download button
220
+ df_summary = pd.DataFrame(summaries, columns=['Capture Time', 'Summary'])
221
+ summary_file = tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx')
222
+ df_summary.to_excel(summary_file.name, index=False)
223
+ st.download_button(label="Download Summary Report",
224
+ data=open(summary_file.name, 'rb').read(),
225
+ file_name="camera_summary_report.xlsx",
226
+ mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
227
+
228
+ def video_captioning_page():
229
+ st.title("Video Captioning")
230
+
231
+ # Sidebar for search functionality
232
+ with st.sidebar:
233
+ query = st.text_input("Search videos by caption:")
234
+
235
+ # Right side for folder path input and displaying videos
236
+ folder_path = st.text_input("Enter the folder path containing videos:")
237
+
238
+ if folder_path and os.path.isdir(folder_path):
239
+ video_files = [f for f in os.listdir(folder_path) if f.lower().endswith(('mp4', 'avi', 'mov', 'mkv'))]
240
+ captions = {}
241
+
242
+ for video_file in video_files:
243
+ video_path = os.path.join(folder_path, video_file)
244
+ frames, captions_df = process_video(video_path, frame_interval=20)
245
+
246
+ if frames and not captions_df.empty:
247
+ generated_captions = ' '.join(captions_df['Caption'])
248
+ summary = summarize_pipe(generated_captions)[0]['summary_text']
249
+ captions[video_path] = summary
250
+
251
+ # Display videos in a 4-column grid
252
+ cols = st.columns(4)
253
+ for idx, (video_path, summary) in enumerate(captions.items()):
254
+ with cols[idx % 4]:
255
+ st.video(video_path, caption=summary)
256
+
257
+ if query:
258
+ results = search_captions(query, captions)
259
+ st.write("Search Results:")
260
+ for video_path, summary in results:
261
+ st.video(video_path, caption=summary)
262
+
263
+ # Save captions to CSV and provide a download button
264
+ if st.button("Generate CSV"):
265
+ df = pd.DataFrame(list(captions.items()), columns=['Video', 'Caption'])
266
+ csv = df.to_csv(index=False)
267
+ st.download_button(label="Download captions as CSV",
268
+ data=csv,
269
+ file_name="captions.csv",
270
+ mime="text/csv")
271
+
272
+ def main():
273
+ st.sidebar.title("Navigation")
274
+ page = st.sidebar.selectbox("Select a page", ["Image Captioning", "Live Camera Captioning", "Video Captioning"])
275
+
276
+ if page == "Image Captioning":
277
+ image_captioning_page()
278
+ elif page == "Live Camera Captioning":
279
+ live_camera_captioning_page()
280
+ elif page == "Video Captioning":
281
+ video_captioning_page()
282
+
283
+ if __name__ == "__main__":
284
+ main()