Download app.py from hillol7/SnapShot: direct link, hf CLI and curl.
- Browser
- Download file 2.61 kB
-
https://huggingface.co/spaces/hillol7/SnapShot/resolve/main/app.py
- Command line
-
hf download hf://spaces/hillol7/SnapShot/app.py
-
curl -L -o app.py https://huggingface.co/spaces/hillol7/SnapShot/resolve/main/app.py
2.61 kB
| import streamlit as st | |
| import cv2 | |
| import numpy as np | |
| import tempfile | |
| def main(): | |
| st.title("SIFT Object Tracking in Video") | |
| st.sidebar.title("Upload Files") | |
| uploaded_image = st.sidebar.file_uploader("Upload an image (PNG or JPG)", type=["png", "jpg"]) | |
| uploaded_video = st.sidebar.file_uploader("Upload a video (MP4)", type=["mp4"]) | |
| if uploaded_image and uploaded_video: | |
| st.sidebar.success("Files successfully uploaded!") | |
| # Save the uploaded image to a temporary file | |
| with tempfile.NamedTemporaryFile(suffix='.jpg') as tmp: | |
| tmp.write(uploaded_image.read()) | |
| image = cv2.imread(tmp.name) | |
| # Save the uploaded video to a temporary file | |
| with tempfile.NamedTemporaryFile(suffix='.mp4') as tmp: | |
| tmp.write(uploaded_video.read()) | |
| video = cv2.VideoCapture(tmp.name) | |
| st.header("Uploaded Image") | |
| st.image(image, caption="Uploaded Image", use_column_width=True) | |
| st.header("Uploaded Video") | |
| st.video(uploaded_video) | |
| # Perform object tracking with SIFT | |
| sift = cv2.SIFT_create() | |
| keypoints_input, descriptors_input = sift.detectAndCompute(image, None) | |
| bf = cv2.BFMatcher() | |
| occurrences = 0 | |
| occurrence_start = 0 | |
| occurrence_duration = 0 | |
| prev_matches = [] | |
| while True: | |
| ret, frame = video.read() | |
| if not ret: | |
| st.write("End of video reached.") | |
| break | |
| frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) | |
| keypoints_frame, descriptors_frame = sift.detectAndCompute(frame_gray, None) | |
| matches = bf.knnMatch(descriptors_input, descriptors_frame, k=2) | |
| good_matches = [] | |
| for m, n in matches: | |
| if m.distance < 0.75 * n.distance: | |
| good_matches.append(m) | |
| if len(good_matches) >= 6: | |
| if not prev_matches: | |
| occurrence_start = video.get(cv2.CAP_PROP_POS_MSEC) / 1000 | |
| occurrences += 1 | |
| prev_matches = good_matches | |
| occurrence_duration = (video.get(cv2.CAP_PROP_POS_MSEC) / 1000) - occurrence_start | |
| else: | |
| if prev_matches: | |
| st.write(f"Occurrence {occurrences}: Start time: {occurrence_start:.2f}s, Duration: {occurrence_duration:.2f}s") | |
| prev_matches = [] | |
| video.release() | |
| else: | |
| st.sidebar.warning("Please upload both an image and a video.") | |
| if __name__ == "__main__": | |
| main() |