【Opencv工程开发所用类】VideoTracker 视频摄像头

前言:

        普通播放视频的代码是有非常多劣势,  像这下面这个代码其实会出现非常多的问题,例如:容易内存泄漏;面对文件读取错误会导致整个程序崩盘;无法合成视频保存;无法显示当前帧数和视频总帧数等等。诶,反正就是不太好啦!


        所以我自己编写了一个可以处理异常,稳定的视频播放类,且可以读取视频、保存视频,播放当前帧,视频总帧数、Fps等等功能!

import numpy as np
import cv2

cap = capture = cv2.VideoCapture('C2.mp4')
while (cap.isOpened()):
    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    cv2.imshow('frame', gray)
    cv2.waitKey(1)

cap.release()
cv2.destroyAllWindows()

VideoTracker

.py

# --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=0, video_path='', save_path=''):
        self.cam = cam
        self.video_path = video_path
        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

            start = time.time()
            ref, ori_im = self.vdo.retrieve()

            if ref is True:

                cv2.imshow("frame", ori_im)
                cv2.waitKey(1)

                if self.save_path:
                    self.writer.write(ori_im)

                # logging
                end = time.time()
                all_costTime += end - start
                if 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))
    

How to use?

if __name__ == "__main__":
    # Using camer
    cam = VideoTracker()
    cam.run()
    # Using video
    video_path = 'test.avi'
    cam = VideoTracker(cam=-1, video_path=video_path)

你可能感兴趣的:(方便的OpenCV,python,numpy,深度学习)