一、利用numpy生成视频

import numpy as np
import cv2

def array2video(videoName, w, h):
    """
    使用numpy生成视频
    :param videoName: 
    :param w: 
    :param h: 
    :return: 
    """
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    videoWriter = cv2.VideoWriter(videoName, fourcc, 25, (w, h))
    frameCount = 0

    while True:
        img = np.ones((h, w, 3), np.uint8)*255
        cv2.putText(img, str(frameCount), (300, 300), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 3)

        cv2.imshow("frame", img)
        videoWriter.write(img)

        frameCount = frameCount + 1
        if cv2.waitKey(1) & 0xFF == 27:
            videoWriter.release()  # 关闭摄像头
            break


if __name__ == "__main__":
    array2video("mix.avi", 640, 480)

        在转的过程中需要注意几点,否则会出现相应的视频文件不出现,出现了但是视频文件很小且打不开,可以打开但是视频的每一帧和预想的不一样:

  1. 首先需要注意的是视频解码格式,我在OpenCV官网上看到就是以('M', 'J', 'P', 'G')为例(其他解码格式也可以去尝试),当然也有简单的方法,不需要一个个的试,把编码的参数设置为-1(如下代码),有的系统弹出对话框显示该系统支持的编码格式(选择其中一个就行),有的系统会把支持的编码格式输出。不过这种方法不是对所有系统都有效的,看运气咯。同时后缀名一定要是.avi格式。可以用isOpened()方法查看是否真的创建了。解码格式的种类可以在这里查看。
videoWriter = cv.VideoWriter('aa.avi', -1, 10, (1080, 640))
  1. 程序的最后一定要释放VideoWriter资源,否则最后的视频可能也会打不开,或者重启软件或者机器后才能打开该视频。
videoWriter.release()
  1. 注意创建的VideoWriter对象时,视频的宽和高一定要匹配好,否则也会导致视频文件很小且打不开(其实就是视频帧没有被写入)。注意下面的两句的宽和高位置对换:
img = np.ones((640, 1080, 3), np.uint8)*255
videoWriter = cv.VideoWriter('bb.avi', fourcc, 10, (1080, 640))

最后,如果是自己用python的numpy创建的图片,一定要使用np.uint8类型(如下),否则最后的视频文件的播放画面就会像下面一样。(如果是先将其保存成一张一张的图片,然后在每一帧的读取转换成视频,就可以不做要求这样的要求)

img = np.ones((640, 1080, 3), np.uint8)*255

opencv视频优化 opencv对视频进行处理_ide

错误的画面


opencv视频优化 opencv对视频进行处理_opencv视频优化_02

应该有的样子


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time        :2020/11/9 15:24
# @Author      :weiz
# @ProjectName :autoLabeling
# @File        :array2vide.py
# @Description :numpy生成视频
import numpy as np
import cv2
import random

def array2video(videoName, w, h, steps, radius):
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    videoWriter = cv2.VideoWriter(videoName, fourcc, 25, (w, h))
    frameCount = 0

    startX = w + 400 // 2
    endX = - (400 // 2)
    centerX = w // 2
    centerY = h // 2

    x = endX
    y = 0
    r = 0
    while True:
        img = np.ones((h, w, 3), np.uint8)
        #cv2.putText(img, str(frameCount), (300, 300), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 3)

        if x <= endX:
            x = startX
            r = radius[random.randint(0, len(radius)-1)] // 2
        else:
            x = x - steps[random.randint(0, len(steps)-1)]

        y = centerY + random.randint(-1, 3)
        cv2.circle(img, (x, y), r, (255, 255, 255), -1)

        cv2.imshow("frame", img)
        videoWriter.write(img)

        frameCount = frameCount + 1
        if cv2.waitKey(1) & 0xFF == 27:
            videoWriter.release()  # 关闭摄像头
            break

radius = [205, 210, 215, 220, 225, 230, 235, 240, 245, 255, 260, 265, 270, 275, 280, 285, 290, 295, 310, 320, 330, 340, 350, 360, 370, 380, 390]
steps = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
if __name__ == "__main__":
    array2video("mix.avi", 640, 480, steps, radius)

二、图片合成视频

import os
import cv2

def images2video(imagesPath, videoName):
    """

    :param imagesPath:
    :return:
    """
    imagesPath = os.path.abspath(imagesPath)
    imagesList = os.listdir(imagesPath)
    imagesList.sort()
    if imagesList == []:
        print("The entered address has no content!")

    fps = 24
    size = cv2.imread(os.path.abspath(os.path.join(imagesPath, imagesList[0]))).shape[:2]
    size = (size[1], size[0])
    print(size)
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    video = cv2.VideoWriter(videoName, fourcc, fps, size)

    frame = 0
    for imageName in imagesList:
        frame = frame + 1
        path = os.path.abspath(os.path.join(imagesPath, imageName))
        img = cv2.imread(path)
        video.write(img)
        if frame % 100 == 0:
            print("The %d frame has been added" % frame)

    video.release()

imagesPath = "E:\\pycharmProject\\YOLOv3\\results"  # 包含图片的文件夹
videoName = "16_detect.avi"
if __name__ == "__main__":
    images2video(imagesPath, videoName)

三、调用摄像头录制视频

# -*- coding: utf-8 -*-
# @Author     : weiz
# @Time       : 2020/4/8 上午10:08
# @FileName   : video.py
# @Software   : PyCharm
# @Description:
import cv2

def recordVideo(camID, saveName):
    """
    使用摄像头录制视频
    :param camID: 摄像头的ID
    :param saveName: 录制视频的名字
    :return:
    """
    video = cv2.VideoCapture(camID)
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    fps = video.get(cv2.CAP_PROP_FPS)                   # 帧率
    size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    out = cv2.VideoWriter(saveName, fourcc, fps, size)  # 视频存储

    while True:
        ret, img = video.read()
        if ret is False:
            out.release()
            cv2.destroyAllWindows()
            break

        cv2.imshow("frame", img)
        out.write(img)

        if cv2.waitKey(1) & 0xFF == 27:
            out.release()
            cv2.destroyAllWindows()
            break


if __name__ == "__main__":
    recordVideo(0, "123.avi")
#include <opencv2/opencv.hpp>

using namespace cv;

void recordVideo()
{
	VideoCapture cam(0);
	if (!cam.isOpened())
	{
		std::cout << "cam open failed!" << std::endl;
	}
	VideoWriter video;
	int fps = cam.get(CAP_PROP_FPS);  //获取摄像机帧率
	if (fps <= 0)fps = 25;
	video.open("out.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'),fps, Size(cam.get(CAP_PROP_FRAME_WIDTH), cam.get(CAP_PROP_FRAME_HEIGHT)));

	Mat img;
	for (;;)
	{
		cam.read(img);
		if (img.empty())break;
		imshow("cam", img);
		//写入视频文件
		video.write(img);
		if (waitKey(5) == 'q') break;
	}
	video.release();
}

 

四、视频转图片

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time        :2020/10/12 13:33
# @Author      :weiz
# @ProjectName :yoloProcessedData
# @File        :video2images.py
# @Description :将视频切分成图片
import os
import cv2
import shutil


def checkFileExist(fileName, isCreate=None):
    """
    检测当前工作目录下fileName文件是否存在,并根据isCreate是否创建
    :param fileName:文件夹名字
    :param isCreate:是否创建
    :return:不存在返回false,存在或者创建返回true
    """
    if isCreate == True:
        isCreate = True
    else:
        isCreate = False
    if os.path.exists(fileName):
        return True
    else:
        if isCreate:
            os.mkdir(fileName)
            print("the path:{} is builded!".format(fileName))
            return True
        else:
            return False


def video2image(videoPath, imagePath, gap, isClearImagePath):
    """
    将视频分割图片
    :param videoPath: 视频所在路径
    :param imagePath: 保存图片的路径
    :param gap: 每隔多少取一帧
    :param isClearImagePath: imagePath文件夹存在是否删除并重新创建
    :return: 
    """
    if not checkFileExist(videoPath):
        print("The {} is not exist!".format(videoPath))
        return

    if isClearImagePath:
        if checkFileExist(imagePath):
            shutil.rmtree(imagePath)  # 删除原来的图片库,以防混乱
            print("Old {} deleted!".format(imagePath))
        checkFileExist(imagePath, True)
    else:
        if not checkFileExist(imagePath, True):
            print("The {} is not exist!".format(imagePath))
            return

    videoNames = os.listdir(videoPath)
    for videoName in videoNames:
        name, suffix = videoName.split(".")
        imagePath_sub = imagePath + "/" + name  # imagePath的子目录
        os.mkdir(imagePath_sub)
        videoRoot = videoPath + "/" + videoName  # 视频的绝对路径
        cap = cv2.VideoCapture(videoRoot)
        frameNum = 1
        imageNumName = 0
        print(videoRoot)
        while (True):
            ret, frame = cap.read()
            if not ret:
                break
            if frameNum % gap == 0:
                # 图片的保存路径
                savePath = imagePath_sub + "/" + name + "_" + "{:0>6d}".format(imageNumName) + ".png"
                imageNumName = imageNumName + 1
                cv2.imwrite(savePath, frame)
            if frameNum % (100*gap) == 0:
                print(frameNum)
            frameNum = frameNum + 1


videoPath = "./videos"
imagePath = "./images"
gap = 10
isClearImagePath = True
if __name__ == "__main__":
    video2image(videoPath, imagePath, gap, isClearImagePath)

五、视频的横屏和竖屏转换

# eg: VSAndHS("./1.mp4", 0)
def VSAndHS(videoPath, rotation, savePath=None):
    """
    竖屏和横屏互转(Turn between vertical and horizontal screens)
    :param videoPath: 视频路径
    :param rotation: 旋转角度:1是顺时针旋转90度,0是逆时针旋转90度
    :param savePath: 保存路径
    :return:
    """
    if rotation not in [0, 1]:
        rotation = 1
    if savePath == None:
        savePath = os.path.dirname(videoPath)
    savePath = os.path.join(savePath, os.path.basename(videoPath).split('.')[-2]+"_r"+".avi")

    cap = cv2.VideoCapture(videoPath)
    ret, frame = cap.read()
    trans_img = cv2.transpose(frame)
    rotation_img = cv2.flip(trans_img, rotation)

    fourcc = cv2.VideoWriter_fourcc(*'XVID')            # 视频存储的格式
    fps = cap.get(cv2.CAP_PROP_FPS)                     # 帧率
    # 视频的宽高
    size = frame.shape[:2]                              # img.shape: 高,宽,通道
    out = cv2.VideoWriter(savePath, fourcc, fps, size)  # 视频存储
    out.write(rotation_img)

    while True:
        ret, frame = cap.read()
        if not ret:
            break
        trans_img = cv2.transpose(frame)
        rotation_img = cv2.flip(trans_img, rotation)    # 获取转化后的图片
        out.write(rotation_img)

        cv2.imshow("src", frame)
        cv2.imshow("dest", rotation_img)
        cv2.waitKey(1)

    cap.release()
    out.release()

六、多个视频合成一个视频

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time        :2021/4/9 15:33
# @Author      :weiz
# @ProjectName :pycharmProject
# @File        :videos2video.py
# @Description :多视频合成一个视频
import os
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont


def plotImage(img, chinese, bbox):
    """
    在图片中显示中文
    :param img:
    :param chinese:
    :param loc:
    :return:
    """
    # cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (255, 0, 0), 2)
    pilimg = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(pilimg)
    font = ImageFont.truetype("simhei.ttf", 15, encoding="utf-8")
    draw.text([bbox[0], bbox[1] - 15], chinese, (255, 0, 0), font=font)
    chineseImg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
    return chineseImg

def videos2video(videosPath, name, repeat=1):
    """
    多个视频转合成一个视频
    videosPath:视频路径
    repeat=1:每个视频重复次数,默认一次
    """
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    videoWriter = cv2.VideoWriter(name, fourcc, 22, (640, 360))

    videoNameList = os.listdir(videosPath)
    for videoName in videoNameList:
        videoNamePath = os.path.join(videosPath, videoName)
        for rep in list(range(repeat)):
            video = cv2.VideoCapture(videoNamePath)
            while True:
                ret, img = video.read()
                if ret is False:
                    cv2.destroyAllWindows()
                    break

                img = plotImage(img, videoName.split('.')[0], [250, 25, 300, 50])  # 用于添加中文

                cv2.imshow("frame", img)
                videoWriter.write(img)

                cv2.waitKey(1)

    videoWriter.release()



videosPath = "C:\\Users\\weiz\\Desktop\\videos"
if __name__ == "__main__":
    videos2video(videosPath, "abc.avi", 4)

七、根据按键保存图片或视频

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time        :2022/1/4 13:37
# @Author      :weiz
# @ProjectName :Sfm-python-master
# @File        :get_image_vide.py
# @Description :
import cv2
import datetime
import os


def get_image(camID):
    """
    根据按键保存图片
    :param camID:
    :return:
    """
    if not os.path.exists("./save_images"):
        os.mkdir("./save_images")

    video = cv2.VideoCapture(camID)
    while True:
        ret, img = video.read()
        if ret is False:
            print("The camera cannot be turned on!")
            cv2.destroyAllWindows()
            break

        cv2.imshow("frame", img)

        k = cv2.waitKey(1)
        if k == ord('s'):
            now_time = datetime.datetime.now()
            name = os.path.join("./save_images", str(now_time).replace(':', '-') + ".png")
            cv2.imwrite(name, img)
            print("The {} is save!".format(name))
        elif k == 27:
            cv2.destroyAllWindows()
            break


def recordVideo(camID, saveName=None):
    """
    根据开关按钮的开与关,录制视频
    :param camID: 摄像头的ID
    :param saveName: 录制视频的名字
    :return:
    """
    if saveName == None:
        now_time = datetime.datetime.now()
        saveName = str(now_time).replace(':', '-') + ".avi"

    video = cv2.VideoCapture(camID)
    fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
    fps = video.get(cv2.CAP_PROP_FPS)  # 帧率
    size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    out = cv2.VideoWriter(saveName, fourcc, fps, size)  # 视频存储

    switch_save = 0
    while True:
        ret, img = video.read()
        if ret is False:
            out.release()
            cv2.destroyAllWindows()
            break

        cv2.imshow("frame", img)
        if switch_save:
            out.write(img)

        k = cv2.waitKey(1)
        if k == ord('s'):
            switch_save = 1
        elif k == ord('e'):
            switch_save = 0
        elif k == 27:
            out.release()
            cv2.destroyAllWindows()
            break


camID = 0
def main():
    # get_image(camID)

    recordVideo(camID)


if __name__ == "__main__":
    main()