PierreBrunelle commited on
Commit
b41cec1
·
verified ·
1 Parent(s): ce8aef9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -47
app.py CHANGED
@@ -57,61 +57,97 @@ def similarity_search(query, search_type, num_results, progress=gr.Progress()):
57
 
58
  return [row['frame'] for row in results]
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  # Gradio interface
61
  with gr.Blocks(theme=gr.themes.Base()) as demo:
62
  gr.Markdown(
63
  """
64
- <div style=margin: 0 auto;">
65
- <img src="https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/source/data/pixeltable-logo-large.png" alt="Pixeltable" style="max-width: 200px; margin-bottom: 20px;" />
66
- <h1 style="margin-bottom: 0.5em;">Text and image similarity search on video frames with embedding indexes</h1>
67
  </div>
68
  """
69
  )
70
- gr.HTML(
71
- """
72
- <p>
73
- <a href="https://github.com/pixeltable/pixeltable" target="_blank" style="color: #4D148C; text-decoration: none; font-weight: bold;">Pixeltable</a>
74
- enables storage, versioning, indexing, and similarity search on video frames.
75
- </p>
76
- """
77
- )
78
-
79
- with gr.Tab("1. Upload and Process Video"):
80
- video_file = gr.File(label="Upload Video")
81
- process_button = gr.Button("Process Video")
82
- process_output = gr.Textbox(label="Processing Status")
83
-
84
- process_button.click(
85
- process_video,
86
- inputs=[video_file],
87
- outputs=[process_output]
88
- )
89
-
90
- with gr.Tab("2. Text and Image Similarity Search on Frames"):
91
- with gr.Row():
92
- with gr.Column():
93
- search_type = gr.Radio(["Text", "Image"], label="Search Type", value="Text")
94
- text_input = gr.Textbox(label="Text Query")
95
- image_input = gr.Image(label="Image Query", type="pil")
96
- num_results = gr.Slider(minimum=1, maximum=20, value=5, step=1, label="Number of Results")
97
- with gr.Column():
98
- search_button = gr.Button("Search")
99
- results_gallery = gr.Gallery(label="Search Results")
100
-
101
- def update_search_input(choice):
102
- return gr.update(visible=choice=="Text"), gr.update(visible=choice=="Image")
103
-
104
- search_type.change(update_search_input, search_type, [text_input, image_input])
105
 
106
- def perform_search(search_type, text_query, image_query, num_results):
107
- query = text_query if search_type == "Text" else image_query
108
- return similarity_search(query, search_type, num_results)
 
 
109
 
110
- search_button.click(
111
- perform_search,
112
- inputs=[search_type, text_input, image_input, num_results],
113
- outputs=[results_gallery]
114
- )
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  if __name__ == "__main__":
117
- demo.launch(debug=True)
 
57
 
58
  return [row['frame'] for row in results]
59
 
60
+ # Process video and create index
61
+ def process_video(video_file, progress=gr.Progress()):
62
+
63
+ progress(0, desc="Initializing...")
64
+
65
+ # Pixeltable setup
66
+ pxt.drop_dir('video_search', force=True)
67
+ pxt.create_dir('video_search')
68
+
69
+ video_table = pxt.create_table('video_search.videos', {'video': pxt.VideoType()})
70
+
71
+ frames_view = pxt.create_view(
72
+ 'video_search.frames',
73
+ video_table,
74
+ iterator=FrameIterator.create(video=video_table.video, fps=1)
75
+ )
76
+
77
+ progress(0.2, desc="Inserting video...")
78
+ video_table.insert([{'video': video_file.name}])
79
+
80
+ progress(0.4, desc="Creating embedding index...")
81
+ frames_view.add_embedding_index('frame', string_embed=str_embed, image_embed=embed_image)
82
+
83
+ progress(1.0, desc="Processing complete")
84
+ return "Video processed and indexed successfully!"
85
+
86
+ # Perform similarity search
87
+ def similarity_search(query, search_type, num_results, progress=gr.Progress()):
88
+
89
+ frames_view = pxt.get_table('video_search.frames')
90
+
91
+ progress(0.5, desc="Performing search...")
92
+ if search_type == "Text":
93
+ sim = frames_view.frame.similarity(query)
94
+ else: # Image search
95
+ sim = frames_view.frame.similarity(query)
96
+
97
+ results = frames_view.order_by(sim, asc=False).limit(num_results).select(frames_view.frame, sim=sim).collect()
98
+
99
+ progress(1.0, desc="Search complete")
100
+
101
+ return [row['frame'] for row in results]
102
+
103
  # Gradio interface
104
  with gr.Blocks(theme=gr.themes.Base()) as demo:
105
  gr.Markdown(
106
  """
107
+ <div style= margin-bottom: 20px;">
108
+ <img src="https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/source/data/pixeltable-logo-large.png" alt="Pixeltable" style="max-width: 150px;" />
109
+ <h2>Video Frame Search with Pixeltable</h2>
110
  </div>
111
  """
112
  )
113
+
114
+ with gr.Row():
115
+ with gr.Column(scale=1):
116
+ video_file = gr.File(label="Upload Video")
117
+ process_button = gr.Button("Process Video")
118
+ process_output = gr.Textbox(label="Status", lines=2)
119
+
120
+ gr.Markdown("---")
121
+
122
+ search_type = gr.Radio(["Text", "Image"], label="Search Type", value="Text")
123
+ text_input = gr.Textbox(label="Text Query")
124
+ image_input = gr.Image(label="Image Query", type="pil", visible=False)
125
+ num_results = gr.Slider(minimum=1, maximum=20, value=5, step=1, label="Number of Results")
126
+ search_button = gr.Button("Search")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ with gr.Column(scale=2):
129
+ results_gallery = gr.Gallery(label="Search Results", columns=3)
130
+
131
+ def update_search_input(choice):
132
+ return gr.update(visible=choice=="Text"), gr.update(visible=choice=="Image")
133
 
134
+ search_type.change(update_search_input, search_type, [text_input, image_input])
135
+
136
+ process_button.click(
137
+ process_video,
138
+ inputs=[video_file],
139
+ outputs=[process_output]
140
+ )
141
+
142
+ def perform_search(search_type, text_query, image_query, num_results):
143
+ query = text_query if search_type == "Text" else image_query
144
+ return similarity_search(query, search_type, num_results)
145
+
146
+ search_button.click(
147
+ perform_search,
148
+ inputs=[search_type, text_input, image_input, num_results],
149
+ outputs=[results_gallery]
150
+ )
151
 
152
  if __name__ == "__main__":
153
+ demo.launch()