自学内容网 自学内容网

树莓派应用--AI项目实战篇来啦-4.OpenCV读取、写入和显示视频

1. 介绍

        视频是由一张一张图片组成的,所以读取视频就相当于读取很多张图片,然后将其连起来
cv2.VideoCapture可以捕获摄像头,但是针对树莓派的CSI摄像头调用方式采用了之前介绍的Picamera2 库,所以在调用的时候是有区别的,但是如果是事先准备的视频或者是 USB 摄像头使用cv2.VideoCapture初始化设备即可,如果是视频文件,直接写好视频路径就好。

2. 操作步骤

1) CSI 摄像头捕获彩色视频

        使用Picamera2库来操作CSI摄像头,但是一定要知道对应视频文件或者是USB摄像头可以直接使用OpenCV的原生态函数cv2.VideoCapture(),在后续的例程中会涉及到该函数的调用,这里还是采用Picamera2来显示摄像头画面!

# 1.载入库
import cv2

def bgr8_to_jpeg(value, quality=75):
    return bytes(cv2.imencode('.jpg', value)[1])
    
# 线程函数操作库
import threading # 线程
import ctypes
import inspect

# 1.1 创建显示控件

import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display
makerobo_image = widgets.Image(format='jpeg', width=640, height=480)
display(makerobo_image)

# 1.2 线程的结束代码

def _async_raise(tid, exctype):
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")
        
def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

# 1.3 动态显示摄像头视频

import numpy as np
import time
import ipywidgets.widgets as widgets
import libcamera
from picamera2 import Picamera2

picamera = Picamera2()
config = picamera.create_preview_configuration(main={"format": 'RGB888', "size": (640, 480)},
                                               raw={"format": "SRGGB12", "size": (1920, 1080)})
config["transform"] = libcamera.Transform(hflip=0, vflip=1)
picamera.configure(config)
picamera.start()

def Video_display():
    while True:
        frame = picamera.capture_array()
        makerobo_image.value = bgr8_to_jpeg(frame)
    # 
    cap.release()

# 1.4 开启线程

t = threading.Thread(target=Video_display)
t.setDaemon(True)
t.start()

# 1.5 结束线程

stop_thread(t)

2) 从文件中播放视频

        它与从相机捕获相同,只是用视频文件名更改摄像机索引。另外,在显示框架时,使用适当的时间延时。如果太小,则视频将非常快,而如果太大,则视频将变得很慢。正常情况下25毫秒就可以了。

def bgr8_to_jpeg(value, quality=75):
    return bytes(cv2.imencode('.jpg', value)[1])
    
import numpy as np
import cv2

import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display
face_image = widgets.Image(format='jpeg', width=640, height=480)
display(face_image)


cap = cv2.VideoCapture('./images/walking.avi')

while cap.isOpened():
    ret, frame = cap.read()
    # 如果正确读取帧,ret为True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv2.flip(frame,4)
    face_image.value = bgr8_to_jpeg(frame)

3) 从文件中播放视频

        所以我们捕捉一个视频,一帧一帧地处理,我们想要保存这个视频。对于图像,它非常简单,只需使用cv.imwrite()。这里还需要做一些工作。这次我们创建一个VideoWriter对象。我们应该指定输出文件名(例如: output.avi)。然后我们应该指定 FourCC 代码(详见下一段)。然后传递帧率的数量和帧大小。最后一个是颜色标志。如果为 True,编码器期望颜色帧,否则它与灰度帧一起工作。
        FourCC: http://en.wikipedia.org/wiki/FourCC 是用于指定视频编解码器的4字节代码。可用代码列表可在fourcc.org 中:http://www.fourcc.org/codecs.php 找到。它取决于平台。遵循编解码器对我来说效果很好。在Fedora 中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用 XVID。MJPG 会生成大尺寸的视频。X264会生成非常小的尺寸的视频)在Windows 中:DIVX(尚待测试和添加)在OSX 中:MJPG (.mp4),DIVX (.avi),X264(.mkv)。FourCC代码作为MJPG的 cv.VideoWriter_fource ('M,'J','P”,'G)or cv. VideoWriter_fourcc(*'MJPC') 传递。在从摄像机捕获的代码下面,沿垂直方向翻转每一帧并保存。

# 载入库
import cv2

def bgr8_to_jpeg(value, quality=75):
    return bytes(cv2.imencode('.jpg', value)[1])

import numpy as np
import time
import ipywidgets.widgets as widgets
import libcamera
from picamera2 import Picamera2

picamera = Picamera2()
config = picamera.create_preview_configuration(main={"format": 'RGB888', "size": (640, 480)},
                                               raw={"format": "SRGGB12", "size": (1920, 1080)})
config["transform"] = libcamera.Transform(hflip=0, vflip=1)
picamera.configure(config)
picamera.start()

import traitlets
import ipywidgets.widgets as widgets
from IPython.display import display
makerobo_image = widgets.Image(format='jpeg', width=640, height=480)
display(makerobo_image)

# 定义编解码器并创建VideoWriter对象
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while True:
    frame = picamera.capture_array()
    frame = cv2.flip(frame, 4)
    # 写翻转的框架
    out.write(frame)
    makerobo_image.value = bgr8_to_jpeg(frame)
    
# 完成工作后释放所有内容
cap.release()
out.release()


原文地址:https://blog.csdn.net/weixin_44845743/article/details/142632493

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!