Прежде всего, я хочу прокомментировать то, что я пытаюсь сделать.
У меня есть IP-камера, подключенная к моей сети ( FOSCAM 9800p ) через маршрутизатор с кабелем Ethernet, и с него я пытаюсь записать видео по протоколу RTSP. В будущем я намерен добавить небольшую обработку видео посередине с opencv, но сейчас я хочу провести тесты, чтобы просто записать это.
Основная проблема заключается в том, что камера выдает переменную частоту кадров в секунду, то есть иногда она делает это до 18, другие - до 22 и так далее. При записи видео с фиксированной скоростью кадров в секунду видео проигрывается быстрее, чем должно
Что-то странное, что когда я запускаю с opencv get (CAP_PROP_FPS), он возвращает большое значение, например 180000.0
Чтобы попытаться решить эту проблему, мы читаем фреймы и помещаем их в очередь. Из другого процесса, которым управляет timer.Event (), мы читаем их и пытаемся записывать в наше видео через равные промежутки времени, чтобы получить фиксированную частоту кадров.
Код следующий:
video_capture = cv2.VideoCapture("rtsp://"+user+":"+password+"@"+ip+":"+str(port)+"/videoMain")
if (video_capture.isOpened() == False):
print("Unable to read camera feed")
sys.exit()
frame_width = int(video_capture.get(3))
frame_height = int(video_capture.get(4))
video_writer =cv2.VideoWriter(output_filename,cv2.VideoWriter_fourcc(*'MP4V'), fps_to_save, (frame_width,frame_height))
input_buffer = queue.Queue(20)
finished = False
read_frames = 0
def readFile():
global finished
global read_frames
while not finished:
ret, frame = video_capture.read()
if not ret:
finished = True
while not finished:
try:
input_buffer.put_nowait(frame)
read_frames+=1
break
except queue.Full:
print("queue.Full")
pass
def processingFile():
global finished
written_frames = 0
repeated_frames = 0
time_per_frame_elapsed = 0.0
start_time=time.time()
ticker = threading.Event()
while True:
ticker.wait(time_per_frame-time_per_frame_elapsed)
time_per_frame_start=time.time()
try:
frame = input_buffer.get_nowait()
video_writer.write(frame)
writing_time = time.time()
if written_frames is 0:
start_time = writing_time
written_frames += 1
except queue.Empty:
if written_frames is not 0:
video_writer.write(frame)
writing_time = time.time()
written_frames += 1
repeated_frames += 1
except:
pass
total_elapsed_time = time.time() - start_time
print("total_elapsed_time:{:f}".format(total_elapsed_time))
if total_elapsed_time>time_to_save_seconds:
finished = True
ticker.clear()
print ("Playback terminated.")
break
time_per_frame_elapsed=time.time()-time_per_frame_start
print("Total readed frames:{:f}".format(read_frames))
print("Total frames repated:{:f}".format(repeated_frames))
print("Total frames writed:{:f}".format(written_frames))
tReadFile = threading.Thread(target=readFile)
tProcessingFile = threading.Thread(target=processingFile)
tReadFile.start()
tProcessingFile.start()
tProcessingFile.join()
tReadFile.join()
Результат близок к тому, что мы хотим, но иногда мы имеем значительные различия во времени. Мы проводим тесты с короткими видеороликами продолжительностью около 10 секунд и получаем 9,8 секунды записи.
Сначала это не кажется серьезной проблемой, но ошибка является кумулятивной, то есть, если мы увеличиваем время, увеличивая таким образом, чтобы при записи видео продолжительного времени у нас были более серьезные проблемы.
Мы хотели бы знать, как решить этот тип проблем с видеозаписью с камерами, которые выдают кадры с переменной скоростью. Это хорошая идея?
Что может быть причиной накопленной ошибки за раз?
От уже большое спасибо!
Приветствую всех!