一、利用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)
在转的过程中需要注意几点,否则会出现相应的视频文件不出现,出现了但是视频文件很小且打不开,可以打开但是视频的每一帧和预想的不一样:
- 首先需要注意的是视频解码格式,我在OpenCV官网上看到就是以('M', 'J', 'P', 'G')为例(其他解码格式也可以去尝试),当然也有简单的方法,不需要一个个的试,把编码的参数设置为-1(如下代码),有的系统弹出对话框显示该系统支持的编码格式(选择其中一个就行),有的系统会把支持的编码格式输出。不过这种方法不是对所有系统都有效的,看运气咯。同时后缀名一定要是.avi格式。可以用isOpened()方法查看是否真的创建了。解码格式的种类可以在这里查看。
videoWriter = cv.VideoWriter('aa.avi', -1, 10, (1080, 640))
- 程序的最后一定要释放VideoWriter资源,否则最后的视频可能也会打不开,或者重启软件或者机器后才能打开该视频。
videoWriter.release()
- 注意创建的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
错误的画面 | 应该有的样子 |
#!/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()