我需要從一個視頻中獲取一些連續幀組。這些組都是由相同數量的幀組成的,它們是連續的,所以像:
[10, 11, 12, 13, 14, 15],
[32, 33, 34, 35, 36, 37],
[123, 124, 125, 126, 127, 128]
這只是一個例子,就我而言,我事先并不知道索引的范圍,它們是在代碼執行期間提供的!
每次我必須提取給定范圍內的幀時,我都嘗試使用(例如,如建議的here )此代碼
video_capture = cv2.VideoCapture(video_path)
for frame_id in frames_range:
video_capture.set(cv2.CAP_PROP_POS_FRAMES, frame_ind)
success, image = video_capture.read()
if not success:
logging.warning(f"Error reading frame {frame_id}", frame_ind)
# do something with frames
但這不起作用,我通常總是得到視頻的前 N ??幀(N 是范圍的長度,在我的示例中為 6)。
我讀到 video_capture.set 在某些情況下可能由于視頻壓縮而失敗,事實上,在使用這種方法讀取某些視頻幀時我遇到了一些錯誤。
另一種簡單的方法是每次逐幀瀏覽視頻,然后選擇我需要的:
def get_required_frames(frames_range: list, video_cap) -> list:
frames = []
frame_counter = 0
while True:
ret, frame = video_cap.read()
if not ret:
return []
# collect frames in selected range
if frame_counter in frames_range:
frames.append(frame)
# after selected range, stop loop
if frame_counter > frames_range[-1]:
break
frame_counter = 1
return frames
# every time I get the required range, I call this function
frames = get_required_frames(frames_range, cv2.VideoCapture(video_path))
# do something with frames
第二種方法作業正常,但有點慢,因為我必須從第 0 幀開始瀏覽整個視頻,直到每次都達到當前幀范圍(有些視頻可能很長)。考慮到幀范圍總是連續的,有沒有辦法讓視頻......“掛起”,這樣至少我可以從前一個幀范圍中使用的最后一個位置重新開始?
uj5u.com熱心網友回復:
我不確定這是否是在簡化本文代碼時創建的錯字,但這似乎是錯誤的:
for frame_id in frames_range:
video_capture.set(cv2.CAP_PROP_POS_FRAMES, frame_ind)
您從“frames_range”獲取“frame_id”,但隨后將 video_capture 的索引設定為“frame_ind”。
如果這不是問題,那么是的,你是對的 - 通過 'CAP_PROP_POS_FRAMES' 設定幀索引不一定可靠。在回答您的問題時,如果您可以讓 video_capture '掛起',答案是肯定的。您應該能夠執行以下操作:
cap = cv2.VideoCapture(video_path)
frames = get_required_frames(frames_range, cap)
當你再次閱讀“cap”時,它應該是你離開它的地方。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/510781.html
標籤:Pythonopencv
