Iv 'написал этот код, чтобы извлечь все кадры из видео и сохранить как изображения.
Но почему-то VideoCapture.read () возвращает false, даже если он не достиг конечного кадра.
Как я могу это исправить и прочитать все кадры?
Я пробовал ловить исключение, но оно ничего не возвращает.
Я следовал исходному коду и обнаружил, что VideoCaputre.read () вызывает VideoCapture.grab и он называется icap-> grabFrame (), но не может получить подробную информацию о icap-> grabFrame ().
python3.6.7 (по умолчанию, 22 октября 2018 г., 11:32:17)
Opencv 3.4.3
Колаборатория Google
Информация о видео
'coded_width': 4000
'coded_height': 3000
'r_frame_rate': '30000/1001'
'avg_frame_rate': '30000/1001'
import os
import ffmpeg
import json
import cv2
import sys
base_dir = './gdrive/My Drive/'
files = os.listdir(base_dir)
# only videos
mp4s =[]
mp4s = [file for file in files if 'MP4' in file ]
# get metadata
file_list = []
for video in mp4s:
video_dir = base_dir + '/' + video
video_info = ffmpeg.probe(video_dir)
time = video_info['streams'][0]['tags']['creation_time']
slice_str = time.find('T')
slice_end = time.find('.')
file_list.append({
'file_name':video,
'start_rec':time[slice_str + 1:slice_end],
'end_rec':video_info['streams'][0]['tags']['timecode'],
'duration':video_info['streams'][0]['duration'],
'nb_frames':video_info['streams'][0]['nb_frames'],
'coded_width':video_info['streams'][0]['coded_width'],
'coded_height':video_info['streams'][0]['coded_height'],
'r_frame_rate':video_info['streams'][0]['r_frame_rate'],
'avg_frame_rate':video_info['streams'][0]['avg_frame_rate']
})
#sort by recording start time
list_sorted = sorted(file_list, key=lambda x:x['start_rec'])
print(list_sorted)
#opencv extract all frames and save as png
dir_path = base_dir + '/' + 'images'
basename ='intervention'
ext = 'png'
n = 0
for dic in list_sorted:
print('start', dic['file_name'])
video_path = base_dir + '/' + dic['file_name']
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print('not opened')
sys.exit()
os.makedirs(dir_path, exist_ok=True)
base_path = os.path.join(dir_path, basename)
digit = len(str(int(cap.get(cv2.CAP_PROP_FRAME_COUNT))))
# below this code ret supposed to be true until the end frame but did't reach the end
while True:
ret, frame = cap.read()
print('ret=', ret)
print(cap.get(cv2.CAP_PROP_POS_FRAMES), '/', cap.get(cv2.CAP_PROP_FRAME_COUNT))
if ret:
cv2.imwrite('{}_{}.{}'.format(base_path, str(n).zfill(digit), ext), frame)
n += 1
else:
print('done', dic['file_name'])
cap.release()
cv2.destroyAllWindows()
break
это возвращается
start GX010223.MP4
ret = True
1,0 / 96,0
~
ret = True
96,0 / 96,0
ret = False
96,0 / 96,0
сделано GX010223.MP4
начать GX010224.MP4
ret = True
1,0 / 105,0
~
ret = True
105,0 / 105,0
ret = False
105,0 / 105,0
сделано GX010224.MP4
start GX010225.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX010225.MP4
start GX020225.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX020225.MP4
start GX030225.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX030225.MP4
start GX040225.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX040225.MP4
start GX050225.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX050225.MP4
start GX060225.MP4
ret = True
1,0 / 539,0
~
ret = True
29,0 / 539,0
ret = False
29,0 / 539,0
сделано GX060225.MP4
start GX010226.MP4
ret = True
1,0 / 282,0
~
ret = True
29,0 / 282,0
ret = False
29,0 / 282,0
сделано GX010226.MP4
start GX010227.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX010227.MP4
start GX020227.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX020227.MP4
start GX030227.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX030227.MP4
start GX040227.MP4
ret = True
1.0 / 15960.0
~
ret = True
29,0 / 15960,0
ret = False
29,0 / 15960,0
сделано GX040227.MP4
start GX050227.MP4
ret = True
1.0 / 2514.0
~
ret = True
29,0 / 2514,0
ret = False
29,0 / 2514,0
сделано GX050227.MP4
Я пытался проверить «пусто или нет» по этому коду
while True:
ret, frame = cap.read()
print('ret=', ret)
print(cap.get(cv2.CAP_PROP_POS_FRAMES), '/', cap.get(cv2.CAP_PROP_FRAME_COUNT))
cv2.imwrite('{}_{}.{}'.format(base_path, str(n).zfill(digit), ext), frame)
n += 1
if ret == False:
if frame == None:
print('done', dic['file_name'])
cap.release()
cv2.destroyAllWindows()
break
но когда cap.read () не удалось, он возвращает объект None, поэтому он не работал должным образом.