Update app.py
Browse files
app.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
import gradio as gr
|
2 |
import pixeltable as pxt
|
3 |
-
from pixeltable.functions.huggingface import
|
4 |
from pixeltable.iterators import FrameIterator
|
5 |
import PIL.Image
|
6 |
import os
|
@@ -13,7 +13,7 @@ def process_video(video_file, progress=gr.Progress()):
|
|
13 |
pxt.drop_dir('video_search', force=True)
|
14 |
pxt.create_dir('video_search')
|
15 |
|
16 |
-
#
|
17 |
video_table = pxt.create_table('video_search.videos', {'video': pxt.Video})
|
18 |
|
19 |
frames_view = pxt.create_view(
|
@@ -26,11 +26,11 @@ def process_video(video_file, progress=gr.Progress()):
|
|
26 |
video_table.insert([{'video': video_file.name}])
|
27 |
|
28 |
progress(0.4, desc="Creating embedding index...")
|
29 |
-
#
|
30 |
frames_view.add_embedding_index(
|
31 |
'frame',
|
32 |
-
image_embed=
|
33 |
-
string_embed=
|
34 |
)
|
35 |
|
36 |
progress(1.0, desc="Processing complete")
|
@@ -41,52 +41,24 @@ def similarity_search(query, search_type, num_results, progress=gr.Progress()):
|
|
41 |
frames_view = pxt.get_table('video_search.frames')
|
42 |
|
43 |
progress(0.5, desc="Performing search...")
|
44 |
-
|
45 |
-
|
46 |
-
else: # Image search
|
47 |
-
sim = frames_view.frame.similarity(query)
|
48 |
|
49 |
results = frames_view.order_by(sim, asc=False).limit(num_results).select(frames_view.frame, sim=sim).collect()
|
50 |
|
51 |
progress(1.0, desc="Search complete")
|
52 |
return [row['frame'] for row in results]
|
53 |
|
54 |
-
#
|
55 |
with gr.Blocks() as demo:
|
56 |
-
gr.Markdown(
|
57 |
-
"""
|
58 |
-
<div style="margin-bottom: 20px;">
|
59 |
-
<img src="https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/pixeltable-logo-large.png" alt="Pixeltable" style="max-width: 150px;" />
|
60 |
-
<h2>Text and Image similarity search on video frames with embedding indexes</h2>
|
61 |
-
</div>
|
62 |
-
"""
|
63 |
-
)
|
64 |
-
gr.HTML(
|
65 |
-
"""
|
66 |
-
<p>
|
67 |
-
<a href="https://github.com/pixeltable/pixeltable" target="_blank" style="color: #F25022; text-decoration: none; font-weight: bold;">Pixeltable</a> is a declarative interface for working with text, images, embeddings, and even video, enabling you to store, transform, index, and iterate on data.
|
68 |
-
</p>
|
69 |
-
"""
|
70 |
-
)
|
71 |
-
|
72 |
|
73 |
with gr.Row():
|
74 |
with gr.Column(scale=1):
|
75 |
-
|
76 |
-
gr.Markdown(
|
77 |
-
"""
|
78 |
-
<h3>1. Insert video</h3>
|
79 |
-
""")
|
80 |
-
|
81 |
video_file = gr.File(label="Upload Video")
|
82 |
process_button = gr.Button("Process Video")
|
83 |
process_output = gr.Textbox(label="Status", lines=2)
|
84 |
|
85 |
-
gr.Markdown(
|
86 |
-
"""
|
87 |
-
<h3>2. Search video frames</h3>
|
88 |
-
""")
|
89 |
-
|
90 |
search_type = gr.Radio(["Text", "Image"], label="Search Type", value="Text")
|
91 |
text_input = gr.Textbox(label="Text Query")
|
92 |
image_input = gr.Image(label="Image Query", type="pil", visible=False)
|
@@ -94,24 +66,7 @@ with gr.Blocks() as demo:
|
|
94 |
search_button = gr.Button("Search")
|
95 |
|
96 |
with gr.Column(scale=2):
|
97 |
-
|
98 |
-
gr.Markdown(
|
99 |
-
"""
|
100 |
-
<h3>3. Visualize results</h3>
|
101 |
-
""")
|
102 |
-
|
103 |
results_gallery = gr.Gallery(label="Search Results", columns=3)
|
104 |
-
|
105 |
-
gr.Examples(
|
106 |
-
examples=[
|
107 |
-
["bangkok.mp4"],
|
108 |
-
["lotr.mp4"],
|
109 |
-
["mi.mp4"],
|
110 |
-
],
|
111 |
-
label="Click one of the examples below to get started",
|
112 |
-
inputs=[video_file],
|
113 |
-
fn=process_video
|
114 |
-
)
|
115 |
|
116 |
def update_search_input(choice):
|
117 |
return gr.update(visible=choice=="Text"), gr.update(visible=choice=="Image")
|
@@ -134,6 +89,6 @@ with gr.Blocks() as demo:
|
|
134 |
outputs=[results_gallery]
|
135 |
)
|
136 |
|
|
|
137 |
if __name__ == "__main__":
|
138 |
-
|
139 |
-
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
import pixeltable as pxt
|
3 |
+
from pixeltable.functions.huggingface import clip_image, clip_text
|
4 |
from pixeltable.iterators import FrameIterator
|
5 |
import PIL.Image
|
6 |
import os
|
|
|
13 |
pxt.drop_dir('video_search', force=True)
|
14 |
pxt.create_dir('video_search')
|
15 |
|
16 |
+
# Create the video table
|
17 |
video_table = pxt.create_table('video_search.videos', {'video': pxt.Video})
|
18 |
|
19 |
frames_view = pxt.create_view(
|
|
|
26 |
video_table.insert([{'video': video_file.name}])
|
27 |
|
28 |
progress(0.4, desc="Creating embedding index...")
|
29 |
+
# Use separate methods for image and text embedding
|
30 |
frames_view.add_embedding_index(
|
31 |
'frame',
|
32 |
+
image_embed=clip_image.using(model_id='openai/clip-vit-base-patch32'),
|
33 |
+
string_embed=clip_text.using(model_id='openai/clip-vit-base-patch32')
|
34 |
)
|
35 |
|
36 |
progress(1.0, desc="Processing complete")
|
|
|
41 |
frames_view = pxt.get_table('video_search.frames')
|
42 |
|
43 |
progress(0.5, desc="Performing search...")
|
44 |
+
# The query is the same either way, but this makes it clearer what's happening
|
45 |
+
sim = frames_view.frame.similarity(query)
|
|
|
|
|
46 |
|
47 |
results = frames_view.order_by(sim, asc=False).limit(num_results).select(frames_view.frame, sim=sim).collect()
|
48 |
|
49 |
progress(1.0, desc="Search complete")
|
50 |
return [row['frame'] for row in results]
|
51 |
|
52 |
+
# Simplified gradio interface with minimal styling
|
53 |
with gr.Blocks() as demo:
|
54 |
+
gr.Markdown("# Text and Image Search on Video Frames with Pixeltable")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
with gr.Row():
|
57 |
with gr.Column(scale=1):
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
video_file = gr.File(label="Upload Video")
|
59 |
process_button = gr.Button("Process Video")
|
60 |
process_output = gr.Textbox(label="Status", lines=2)
|
61 |
|
|
|
|
|
|
|
|
|
|
|
62 |
search_type = gr.Radio(["Text", "Image"], label="Search Type", value="Text")
|
63 |
text_input = gr.Textbox(label="Text Query")
|
64 |
image_input = gr.Image(label="Image Query", type="pil", visible=False)
|
|
|
66 |
search_button = gr.Button("Search")
|
67 |
|
68 |
with gr.Column(scale=2):
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
results_gallery = gr.Gallery(label="Search Results", columns=3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
def update_search_input(choice):
|
72 |
return gr.update(visible=choice=="Text"), gr.update(visible=choice=="Image")
|
|
|
89 |
outputs=[results_gallery]
|
90 |
)
|
91 |
|
92 |
+
# Launch with share=True to fix the localhost issue
|
93 |
if __name__ == "__main__":
|
94 |
+
demo.launch(share=True)
|
|