【Opencv工程开发所用类】能完美嵌入目标检测、语义分割等计算机视觉任务的视频摄像头类

前言

        本文提供一个功能完备的OpenCv视频播放处理类,供大家使用。(支持,保存视频、日志打印、视频裁剪、Q键退出、是否播放,选择使用摄像头或者视频, 播放完释放资源,进度条打印,日志打印。。。


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

前言

VideoTracker.py

Camer

#using camer

Video 

#using video

# save video

# crop video  

【OUTPUT】 


VideoTracker.py

# --time**2022.8.13
# --** worker:优快云大气层煮月亮
# --** email:2642898145@qq.com
 
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)

        # 释放视频资源
        if hasattr(self, 'vdo') and self.vdo.isOpened():
            self.vdo.release()
            print("Video resource released.")

        # 释放视频写入器资源
        if hasattr(self, 'writer'):
            self.writer.release()
            print("Video writer resource released.")
 
    def run(self):
        idx_frame = 0
        all_costTime = 0
 
        while self.vdo.grab():
            idx_frame += 1

            start_iter_frame_id = int(self.count_frame * self.use_frame[0])
            end_iter_frame_id = int(self.count_frame * self.use_frame[1])
            # 展示用
            self.show_count_frames = end_iter_frame_id

            if idx_frame % self.frame_interval:
                continue
                
            if idx_frame < start_iter_frame_id:
                continue
 
            if idx_frame > end_iter_frame_id:
                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() - start if time.time() - start != 0 else 1
                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.show_count_frames , end - start, 1 / (end - start)))
                else:
                    self.print_progress_bar(idx_frame, self.show_count_frames, prefix='Progress:', suffix='Complete', length=50)
 
        logger.info("ALL_COST_TIME:{:.3f}s".format(all_costTime))

    def print_progress_bar(self, iteration, total, prefix='', suffix='', length=50, fill='█'):
        """
        Args:
        iteration (int): 当前迭代次数
        total (int): 总迭代次数
        prefix (str): 进度条前缀文本
        suffix (str): 进度条后缀文本
        length (int): 进度条长度
        fill (str): 用于填充进度条的字符
        """
        percent = ("{0:.1f}").format(100 * (iteration / float(total)))
        filled_length = int(length * iteration // total)
        bar = fill * filled_length + '-' * (length - filled_length)
        sys.stdout.write('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix))
        sys.stdout.flush()

    def pil_to_cv2(self, pil_image):
        """
        Convert a PIL Image to an OpenCV image (NumPy array).

        Args:
        pil_image (PIL.Image): The image in PIL format.

        Returns:
        numpy.ndarray: The image in OpenCV format.
        """
        # Convert the PIL image to a NumPy array
        pil_image_np = np.array(pil_image)
        # Convert RGB to BGR
        cv2_image = cv2.cvtColor(pil_image_np, cv2.COLOR_RGB2BGR)
        return cv2_image
    
    def cv2_to_pil(self, cv2_image):
        """
        Convert an OpenCV image (NumPy array) to a PIL Image.

        Args:
        cv2_image (numpy.ndarray): The image in OpenCV format.

        Returns:
        PIL.Image: The image in PIL format.
        """
        # OpenCV uses BGR by default, whereas PIL uses RGB, so we need to convert the image
        cv2_image_rgb = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
        # Convert the NumPy array to a PIL image
        pil_image = Image.fromarray(cv2_image_rgb)
        return pil_image

Camer

#using camer

from VideoCapture import VideoTracker

if __name__ == '__main__':
    # select the camer you want to use
    with VideoTracker(cam=0) as vdo_trk:
        vdo_trk.run()

Video 

#using video

from VideoCapture import VideoTracker

if __name__ == '__main__':
    # select the video you want to use
    '''
    @video_path<str> -> |视频路径
    @use_frame<list> -> |取值范围[0,1],如果设置为【0,0.5】那么意思就是只使用该视频的前半段。
    @display<bool> -> |是否播放视频。
    '''
    with VideoTracker(video_path='test.mp4',use_frame=[0, 1]) as vdo_trk:
        vdo_trk.run()

# save video

        只需要在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()

# crop video  

        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()

【OUTPUT】 

一些关于OpenCv的参数:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大气层煮月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值