同时读取视频画面 和 摄像头画面, 并实现同步处理时,出现两种情景
简而言之
同步执行时,谁的 fps 帧率低,使用谁的帧率,因为高的获取不到帧数据啊!
首先需要确定帧同步基准,如以视频帧率为基准,同步摄像头帧率与视频帧率一致
原理:
摄像头帧率没变,读取显示的时候,以摄像头帧和视频帧时间差,进行摄像头帧填充,即延用摄像头上一帧数据
代码
C++ 实现原理类似,假象帧同步,表现一致性
import cv2
import time
if __name__ == "__main__":
"""
视频和摄像头, 帧同步问题
---
背景: 同时读取视频画面 和 摄像头画面, 并实现同步处理时,出现两种情景
1) 视频 fps <= 摄像头 fps , 播放视频和读取摄像头,画面同步
2) 视频 fps > 摄像头 fps , 播放视频快, 导致读取摄像头画面时, 跟不上播放速度, 画面不同步或将视频画面阻塞为摄像头帧率
"""
# 视频
course_cap = cv2.VideoCapture("datasets/video.mp4")
course_fps = course_cap.get(cv2.CAP_PROP_FPS)
course_height = int(course_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
course_width = int(course_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 摄像头
camera_cap = cv2.VideoCapture(0)
camera_fps = camera_cap.get(cv2.CAP_PROP_FPS)
camera_height = int(camera_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
camera_width = int(camera_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 日志
print("course cap: ", course_fps, "camera_cap:", camera_fps)
# 帧同步:以视频帧率为基准,同步摄像头帧率与视频帧率一致
# 假象帧同步:摄像头帧率没变,读取显示的时候,以摄像头帧和视频帧时间差,进行摄像头帧填充,即延用摄像头上一帧数据
camera_wait_ns = 0
if course_fps > camera_fps:
# 摄像头帧率下, 需要等待时间差
camera_wait_ns = abs(
(int(1000 / course_fps) - int(1000 / camera_fps)) * 1000 * 1000
)
camera_frame_ns = 0
camera_frame = None
# 循环
while True:
# 视频帧
has_course_frame, course_frame = course_cap.read()
if not has_course_frame:
break
# 判断时间差,更新摄像头画面
frame_ns = time.perf_counter_ns() - camera_frame_ns
if frame_ns > camera_wait_ns:
# 读取摄像头画面
has_camera_frame, camera_frame = camera_cap.read()
if not has_camera_frame:
break
# 更新时间
camera_frame_ns = time.perf_counter_ns()
# 视频图像和摄像头图像处理
if camera_frame is not None:
course_frame[0:camera_height, 0:camera_width] = camera_frame
course_frame = cv2.resize(
course_frame, (int(course_height / 3), int(course_width / 3))
)
# 画面显示
cv2.imshow("test", course_frame)
cv2.waitKey(1)