Reputation: 13
I am analysing a video frame by frame with cv2, in which I want to save the frame as 1 if the frame number is in between certain timestamps and as 0 if not. I've got two lists, one with the start times and one with the end times:
start_times = [0, 10, 15]
end_times = [2, 12, 17]
I want to save the frame as 1 for frame numbers 0,1,2 & 10,11,12 & 15,16,17 and as 0 for the others.
My code saves the correct frames as 1, but it saves unwanted frames as 0 because I'm using a for loop. See the simplified example below:
start_times = [0,10,15]
end_times = [2,12,17]
currentframe = 0
while True:
try:
for index,time in enumerate(start_times):
if start_times[index] <= currentframe <= end_times[index]:
print('save images as 1')
else:
print('save images as 0')
currentframe += 1
if currentframe == 20:
break
except IndexError:
break
Which outputs for the first frame:
save images as 1
save images as 0
save images as 0
How can I change my code so the first frame is saved only as 1?
Upvotes: 0
Views: 607
Reputation: 585
I'm not sure if I clearly understood you, but try this and tell me if it is what you want:
start_times = [0,10,15]
end_times = [2,12,17]
times = sorted(start_times + end_times)
print(times)
i = 0
while i + 1 < len(times):
k = times[i]
while k <= times[i + 1]:
if i % 2 == 0:
print('save [frame {}] as 1'.format(k))
else:
print('save [frame {}] as 0'.format(k))
k += 1
i += 1
Upvotes: 1
Reputation: 13
A friend of mine has given me the solution by using ranges:
current_frame = 0
start_times = [0, 10, 15]
end_times = [2, 12, 17]
ranges = [range(start, stop) for start, stop in zip(start_times, end_times)]
while True:
if any([current_frame in my_range for my_range in ranges]):
print('save image as 1')
else:
print('save image as 0')
...
Upvotes: 0
Reputation: 1638
I think this is what you are looking for?
while curr_frame < 20:
is_in = any(filter(lambda start_end: start_end[0] <= curr_frame <= start_end[1],
zip(start_times, end_times))))
print(f'Save image as {int(is_in)}')
curr_frame += is_in
Upvotes: 0