distant-frames 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of distant-frames might be problematic. Click here for more details.
- {distant_frames-0.1.0 → distant_frames-0.1.2}/PKG-INFO +1 -1
- {distant_frames-0.1.0 → distant_frames-0.1.2}/distant_frames/core.py +28 -18
- {distant_frames-0.1.0 → distant_frames-0.1.2}/pyproject.toml +1 -1
- {distant_frames-0.1.0 → distant_frames-0.1.2}/uv.lock +1 -1
- {distant_frames-0.1.0 → distant_frames-0.1.2}/.github/workflows/ci.yml +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/.github/workflows/publish.yml +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/.gitignore +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/.python-version +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/CONTRIBUTING.md +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/LICENSE +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/PUBLISHING.md +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/README.md +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/debug_import.py +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/distant_frames/__init__.py +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/distant_frames/cli.py +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/extracted_frames/.gitkeep +0 -0
- {distant_frames-0.1.0 → distant_frames-0.1.2}/generate_test_video.py +0 -0
|
@@ -32,7 +32,7 @@ def calculate_similarity(frame1, frame2):
|
|
|
32
32
|
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
|
|
33
33
|
return similarity
|
|
34
34
|
|
|
35
|
-
def extract_frames(video_path, output_folder, threshold=0.
|
|
35
|
+
def extract_frames(video_path, output_folder, threshold=0.65):
|
|
36
36
|
"""Extracts distinct frames from a video file based on visual similarity.
|
|
37
37
|
|
|
38
38
|
The function samples the video at 1-second intervals. It compares the current
|
|
@@ -50,7 +50,7 @@ def extract_frames(video_path, output_folder, threshold=0.9):
|
|
|
50
50
|
threshold (float, optional): Similarity threshold (0.0 to 1.0).
|
|
51
51
|
Frames with similarity higher than this value regarding the last
|
|
52
52
|
saved frame will be dropped. Higher values mean stricter
|
|
53
|
-
deduplication (fewer frames saved). Defaults to 0.
|
|
53
|
+
deduplication (fewer frames saved). Defaults to 0.65.
|
|
54
54
|
|
|
55
55
|
Returns:
|
|
56
56
|
None
|
|
@@ -80,8 +80,9 @@ def extract_frames(video_path, output_folder, threshold=0.9):
|
|
|
80
80
|
current_frame_idx = 0
|
|
81
81
|
saved_count = 0
|
|
82
82
|
last_saved_frame = None
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
last_saved_timestamp = None
|
|
84
|
+
skip_reference_frame = None
|
|
85
|
+
skip_reference_timestamp = None
|
|
85
86
|
|
|
86
87
|
while True:
|
|
87
88
|
# Set position to the next second
|
|
@@ -98,35 +99,44 @@ def extract_frames(video_path, output_folder, threshold=0.9):
|
|
|
98
99
|
if last_saved_frame is None:
|
|
99
100
|
should_save = True
|
|
100
101
|
similarity = 0.0 # No previous frame
|
|
102
|
+
print(f"[{timestamp:.1f}s] First frame → SAVE")
|
|
101
103
|
else:
|
|
102
104
|
# Determine reference frame
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
# If we have a skip reference (from previous skip), use that
|
|
106
|
+
# Otherwise use the last saved frame
|
|
107
|
+
if skip_reference_frame is not None:
|
|
108
|
+
reference_frame = skip_reference_frame
|
|
109
|
+
ref_timestamp = skip_reference_timestamp
|
|
110
|
+
ref_label = "skip_ref"
|
|
111
|
+
else:
|
|
112
|
+
reference_frame = last_saved_frame
|
|
113
|
+
ref_timestamp = last_saved_timestamp
|
|
114
|
+
ref_label = "last"
|
|
109
115
|
|
|
110
116
|
similarity = calculate_similarity(reference_frame, frame)
|
|
117
|
+
|
|
111
118
|
if similarity < threshold:
|
|
112
119
|
should_save = True
|
|
120
|
+
print(f"[{timestamp:.1f}s] vs {ref_label}@{ref_timestamp:.1f}s | sim={similarity:.3f} → SAVE")
|
|
121
|
+
# Clear skip reference when we save
|
|
122
|
+
skip_reference_frame = None
|
|
123
|
+
skip_reference_timestamp = None
|
|
113
124
|
else:
|
|
114
|
-
print(f"
|
|
115
|
-
|
|
125
|
+
print(f"[{timestamp:.1f}s] vs {ref_label}@{ref_timestamp:.1f}s | sim={similarity:.3f} → SKIP")
|
|
126
|
+
# When we skip, set the skip reference to the last saved frame
|
|
127
|
+
# so next comparison uses this same reference
|
|
128
|
+
skip_reference_frame = last_saved_frame
|
|
129
|
+
skip_reference_timestamp = last_saved_timestamp
|
|
116
130
|
|
|
117
131
|
if should_save:
|
|
118
132
|
output_filename = os.path.join(output_folder, f"frame_{timestamp:.2f}.jpg")
|
|
119
133
|
cv2.imwrite(output_filename, frame)
|
|
120
134
|
|
|
121
|
-
# Update
|
|
122
|
-
prev_saved_frame = last_saved_frame
|
|
135
|
+
# Update last saved frame
|
|
123
136
|
last_saved_frame = frame
|
|
124
|
-
|
|
125
|
-
# Reset fallback flag because we just saved a new distinct frame
|
|
126
|
-
force_fallback_to_prev = False
|
|
137
|
+
last_saved_timestamp = timestamp
|
|
127
138
|
|
|
128
139
|
saved_count += 1
|
|
129
|
-
print(f"Saved {output_filename} (Similarity: {similarity:.4f})")
|
|
130
140
|
|
|
131
141
|
current_frame_idx += frame_interval
|
|
132
142
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|