本文提供一个功能完备的OpenCv视频播放处理类,供大家使用。(支持,保存视频、日志打印、视频裁剪、Q键退出、是否播放,选择使用摄像头或者视频
【Opencv工程开发所用类】VideoTracker 视频摄像头
- # --time**2022.8.13
- # --** worker:江子良
-
- import cv2
- import time
-
- import torch
- import warnings
- import numpy as np
-
- from PIL import Image
-
- from loguru import logger
-
- import os
-
- os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
-
-
- class VideoTracker(object):
- def __init__(self, cam=-1, video_path='', save_path='', use_frame=[0, -1], display=True):
- self.display = display
- self.use_frame = use_frame
- self.video_path = video_path
- self.cam = cam
- if self.cam != -1:
- print("Using webcam :" + str(self.cam))
- self.vdo = cv2.VideoCapture(self.cam)
- else:
- print("Using video :" + str(self.video_path))
- self.vdo = cv2.VideoCapture()
-
- self.save_path = save_path
- self.frame_interval = 1
- self.use_cuda = True
-
- use_cuda = self.use_cuda and torch.cuda.is_available()
- if not use_cuda:
- warnings.warn("Running in cpu mode which maybe very slow!", UserWarning)
-
- def __enter__(self):
- if self.cam != -1:
- ret, frame = self.vdo.read()
- assert ret, "Error: Camera error"
- self.im_width = frame.shape[0]
- self.im_height = frame.shape[1]
- self.count_frame = int(-1)
- else:
- assert os.path.isfile(self.video_path), "Path error"
- self.vdo.open(self.video_path)
- self.im_width = int(self.vdo.get(cv2.CAP_PROP_FRAME_WIDTH))
- self.im_height = int(self.vdo.get(cv2.CAP_PROP_FRAME_HEIGHT))
- self.count_frame = int(self.vdo.get(cv2.CAP_PROP_FRAME_COUNT))
- assert self.vdo.isOpened()
-
- if self.save_path != '':
- os.makedirs(self.save_path, exist_ok=True)
-
- # path of saved video and results
- self.save_video_path = os.path.join(self.save_path, "results.avi")
-
- # create video writer
- fourcc = cv2.VideoWriter_fourcc(*'MJPG')
- self.writer = cv2.VideoWriter(self.save_video_path, fourcc, 24, (self.im_width, self.im_height))
-
- # logging
- logger.info("Save results to {}".format(self.save_path))
-
- return self
-
- def __exit__(self, exc_type, exc_value, exc_traceback):
- if exc_type:
- print(exc_type, exc_value, exc_traceback)
-
- def run(self):
- idx_frame = 0
- all_costTime = 0
-
- while self.vdo.grab():
- idx_frame += 1
- if idx_frame % self.frame_interval:
- continue
-
- if idx_frame < self.use_frame[0]:
- continue
-
- if idx_frame > self.use_frame[1] and self.use_frame[1] != -1:
- break
-
- start = time.time()
- ref, ori_im = self.vdo.retrieve()
-
- if ref is True:
- # start your code from here
-
- # -----------end-----------
- if self.display:
- cv2.imshow("frame", ori_im)
- if cv2.waitKey(1) & 0xFF == ord('q'):
- break
-
- if self.save_path:
- self.writer.write(ori_im)
-
- # logging
- end = time.time()
- all_costTime += end - start
- if self.display:
- if self.cam != -1:
- logger.info("frame schedule:<{}/-1> ({:.2f} ms), fps: {:.03f}"
- .format(idx_frame, end - start, 1 / (end - start)))
- else:
- logger.info("frame schedule:<{}/{}> ({:.2f} ms), fps: {:.03f}"
- .format(idx_frame, self.count_frame, end - start, 1 / (end - start)))
-
- logger.info("ALL_COST_TIME:{:.3f}s".format(all_costTime))
- from VideoCapture import VideoTracker
-
- if __name__ == '__main__':
- # select the camer you want to use
- with VideoTracker(cam=0) as vdo_trk:
- vdo_trk.run()
- from VideoCapture import VideoTracker
-
- if __name__ == '__main__':
- # select the video you want to use
- with VideoTracker(video_path='test.mp4',use_frame=[0, -1]) as vdo_trk:
- vdo_trk.run()
只需要在VideoTracker中设置参数save_path,save_path是要存放保存视频的位置,如:'datasets/out_video/'
- from VideoCapture import VideoTracker
-
- if __name__ == '__main__':
- # select the video you want to use
- with VideoTracker(video_path='test.mp4',save_path='database/output/', use_frame=[0, -1]) as vdo_trk:
- vdo_trk.run()
use_frame=[0,-1],默认播放所有视频。
裁剪视频的原理非常简单,比如将use_frame=[10,100],且设置save_path,就是只处理视频[10,100]帧,并且保存视频。也就是说最后的输出视频是只有[10,100]帧的视频。
- from VideoCapture import VideoTracker
-
- if __name__ == '__main__':
- # select the video you want to use
- with VideoTracker(video_path='test.mp4',save_path='database/output/', use_frame=[10, 100]) as vdo_trk:
- vdo_trk.run()

一些关于OpenCv的参数:
