Skip to content

Commit fa916c6

Browse files
committed
Fix frame extract
1 parent 36d1070 commit fa916c6

File tree

2 files changed

+50
-40
lines changed

2 files changed

+50
-40
lines changed

superannotate/db/projects.py

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ def _get_video_rotate_code(video_path):
286286
def _extract_frames_from_video(
287287
start_time, end_time, video_path, tempdir, limit, target_fps
288288
):
289+
chunk_size = 100
289290
video = cv2.VideoCapture(str(video_path), cv2.CAP_FFMPEG)
290291
if not video.isOpened():
291292
raise SABaseException(0, "Couldn't open video file " + str(video_path))
@@ -296,37 +297,44 @@ def _extract_frames_from_video(
296297
ratio = _get_video_fps_ration(target_fps, video, ratio)
297298
rotate_code = _get_video_rotate_code(video_path)
298299
video_name = Path(video_path).stem
299-
frame_no = 0
300300
frame_no_with_change = 1.0
301301
extracted_frame_no = 1
302302
logger.info("Extracting frames from video to %s.", tempdir.name)
303303
zero_fill_count = len(str(total_num_of_frames))
304-
extracted_frames_paths = []
305-
while len(extracted_frames_paths) < limit:
306-
success, frame = video.read()
307-
if not success:
308-
break
309-
frame_no += 1
310-
if round(frame_no_with_change) != frame_no:
311-
continue
312-
frame_no_with_change += ratio
313-
frame_time = video.get(cv2.CAP_PROP_POS_MSEC) / 1000.0
314-
if end_time and frame_time > end_time:
315-
break
316-
if frame_time < start_time:
317-
continue
318-
if rotate_code:
319-
frame = cv2.rotate(frame, rotate_code)
320-
path = str(
321-
Path(tempdir.name) / (
322-
video_name + "_" +
323-
str(extracted_frame_no).zfill(zero_fill_count) + ".jpg"
304+
for frame_no in range(0, limit, chunk_size):
305+
extracted_frames_paths = []
306+
extracted_local_frame_no = 0
307+
while extracted_frame_no < limit and extracted_local_frame_no <= chunk_size:
308+
success, frame = video.read()
309+
if not success:
310+
yield None
311+
return
312+
frame_no += 1
313+
if round(frame_no_with_change) != frame_no:
314+
continue
315+
frame_no_with_change += ratio
316+
frame_time = video.get(cv2.CAP_PROP_POS_MSEC) / 1000.0
317+
if end_time and frame_time > end_time:
318+
yield None
319+
return
320+
if frame_time < start_time:
321+
continue
322+
if rotate_code:
323+
frame = cv2.rotate(frame, rotate_code)
324+
path = str(
325+
Path(tempdir.name) / (
326+
video_name + "_" +
327+
str(extracted_frame_no).zfill(zero_fill_count) + ".jpg"
328+
)
324329
)
325-
)
326-
cv2.imwrite(path, frame)
327-
extracted_frames_paths.append(path)
328-
extracted_frame_no += 1
329-
return extracted_frames_paths
330+
cv2.imwrite(path, frame)
331+
extracted_frames_paths.append(path)
332+
extracted_frame_no += 1
333+
extracted_local_frame_no += 1
334+
if not extracted_frames_paths:
335+
yield None
336+
return
337+
yield extracted_frames_paths
330338

331339

332340
@Trackable
@@ -378,20 +386,22 @@ def upload_video_to_project(
378386
extracted_frames = _extract_frames_from_video(
379387
start_time, end_time, video_path, tempdir, limit, target_fps
380388
)
381-
logger.info(
382-
"Extracted %s frames from video. Now uploading to platform.",
383-
len(extracted_frames)
384-
)
385-
filenames = upload_images_from_folder_to_project(
386-
(project, folder),
387-
tempdir.name,
388-
extensions=["jpg"],
389-
annotation_status=annotation_status,
390-
image_quality_in_editor=image_quality_in_editor
391-
)
389+
upload_file_names = []
390+
391+
for _ in extracted_frames:
392+
filenames = upload_images_from_folder_to_project(
393+
(project, folder),
394+
tempdir.name,
395+
extensions=["jpg"],
396+
annotation_status=annotation_status,
397+
image_quality_in_editor=image_quality_in_editor
398+
)
399+
files = os.listdir(tempdir.name)
400+
for f in files:
401+
os.remove(f'{tempdir.name}/{f}')
402+
upload_file_names += [Path(f).name for f in filenames[0]]
392403

393-
filenames_base = [Path(f).name for f in filenames[0]]
394-
return filenames_base
404+
return upload_file_names
395405

396406

397407
@Trackable

tests/test_video.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ def test_video(tmpdir):
3333
for project in projects:
3434
sa.delete_project(project)
3535

36+
time.sleep(1)
3637
project = sa.create_project(PROJECT_NAME2, "test", "Vector")
37-
3838
subprocess.run(
3939
f'superannotatecli upload-videos --project "{PROJECT_NAME2}" --folder ./tests/sample_videos --target-fps 2',
4040
check=True,

0 commit comments

Comments
 (0)