2024-09-01
OpenCV
00

目录

读取具体哪一帧
等待按钮
写入解码方式与文件格式对应
全部代码

读取具体哪一帧

这个方法可以获取某一帧:

python
while True: cap.set(cv2.CAP_PROP_POS_FRAMES, current_frame) ret, frame = cap.read() if not ret: break

等待按钮

这个方法可以显示当前帧,然后等待你的按钮:

python
# 显示当前帧 cv2.imshow('Video Frame', frame) # 等待按键输入 key = cv2.waitKey(0) # 使用较短的等待时间以确保视频正常播放 if key == 27: # ESC break elif key == ord('q'): # Q 键(往回跳一帧) if current_frame > 0: current_frame -= 1 elif key == ord('w'): # W 键(往前播放一帧) if current_frame < len(json_data) - 1: current_frame += 1

这个标志打开可以让你存储一个mp4视频:

FLAG_SAVE_VIDEOS = False

写入解码方式与文件格式对应

不同的视频文件格式通常需要使用不同的编解码器,因此你需要根据你要创建的视频文件格式来选择合适的四字符编码标识。以下是一些常见的视频文件格式和相应的四字符编码标识示例:

  1. H.264 编码(通常用于.mp4文件):

    python
    fourcc = cv2.VideoWriter_fourcc(*'H264')
  2. XVID 编码(通常用于.avi文件):

    python
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
  3. MJPG 编码(通常用于.avi文件,适用于每帧图像质量高的场景):

    python
    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
  4. DIVX 编码(通常用于.avi文件):

    python
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
  5. VP8 编码(通常用于.webm文件):

    python
    fourcc = cv2.VideoWriter_fourcc(*'VP80')
  6. VP9 编码(通常用于.webm文件):

    python
    fourcc = cv2.VideoWriter_fourcc(*'VP90')

这些是一些常见的视频文件格式和相应的四字符编码标识示例。根据你的需求和所使用的视频文件格式,选择适合的编码标识以确保视频文件可以正确编码和解码。不同的视频编辑软件和播放器也支持不同的编解码器,因此你可能需要根据最终使用情况进行调整。

全部代码

python
import logging import time import cv2 import json # 读取JSON文件 with open('../inoutdir/long.json', 'r') as f: json_data = json.load(f) # 打开视频文件 cap = cv2.VideoCapture('../inoutdir/long.mp4') current_frame = 0 # 配置日志记录 logging.basicConfig(level=logging.INFO, format='%(asctime)s [Frame %(frame)d / %(frame_all)d] %(message)s') logger = logging.getLogger() FLAG_SAVE_VIDEOS = False if FLAG_SAVE_VIDEOS: output_file = '../output/long_draw.mp4' fourcc = cv2.VideoWriter_fourcc(*'mp4v') frame_width = int(cap.get(3)) frame_height = int(cap.get(4)) out = cv2.VideoWriter(output_file, fourcc, 30, (frame_width, frame_height)) # 初始化时间统计 start_time = time.time() total_frames = len(json_data) while True: cap.set(cv2.CAP_PROP_POS_FRAMES, current_frame) ret, frame = cap.read() if not ret: break # 记录时间戳 frame_timestamp = time.time() # 从JSON中获取当前帧的检测结果 if current_frame < len(json_data): detections = json_data[current_frame]['dets'] # 在每个检测上绘制边界框 for det in detections: x1, y1, x2, y2, score, class_id = det color = (0, 255, 0) # 绿色边界框 label = f'{int(class_id)},{score:.2f}' cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), color, 2) # 计算文本位置以确保在框内 text_x = int(x1) text_y = int(y1) - 10 if text_y - 10 < 0: text_y = int(y1) + 20 # 如果文本位置超出了帧的上边界,则将其放在边界框的下方 cv2.putText(frame, label, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) if FLAG_SAVE_VIDEOS: out.write(frame) # 将当前帧写入输出视频 current_frame += 1 else: # 显示当前帧 cv2.imshow('Video Frame', frame) # 等待按键输入 key = cv2.waitKey(0) # 使用较短的等待时间以确保视频正常播放 if key == 27: # ESC break elif key == ord('q'): # Q 键(往回跳一帧) if current_frame > 0: current_frame -= 1 elif key == ord('w'): # W 键(往前播放一帧) if current_frame < len(json_data) - 1: current_frame += 1 # 计算每一帧消耗的时间并记录到日志中 frame_processing_time = time.time() - frame_timestamp logger.info(f'Frame processed in {frame_processing_time:.4f} seconds',extra={'frame': current_frame, 'frame_all': total_frames}) # 计算总共消耗的时间 total_processing_time = time.time() - start_time average_frame_time = total_processing_time / total_frames if total_frames > 0 else 0 print(total_processing_time) print(average_frame_time) # 释放视频文件、关闭窗口和输出视频文件 cap.release() if FLAG_SAVE_VIDEOS: out.release() cv2.destroyAllWindows()
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!