• OpenCV 视频处理(关于摄像头和视频文件的读取、显示、保存等等)


    1、前言

    OpenCV不仅能够处理图像,还能够处理视频

    视频是由大量的图像构成的,这些图像是以固定的时间间隔从视频中获取的。这样,就能够使用图像处理的方法对这些图像进行处理,进而达到处理视频的目的。要想处理视频,需要先对视频进行读取、显示、保存等相关操作。为此,OpenCV提供了VideoCapture类和 VideoWiter 类的相关方法。

    2、摄像头操作

    为了读取并显示摄像头视频,OpenCV 提供了 VideoCapture 类的相关方法,这些方法包括摄像头的初始化方法、检验摄像头初始化是否成功的方法、从摄像头中读取帧的方法、关闭摄像头的方法等。

    Tips :视频是由大量图像构成,这些图像称为帧

    VideoCapture 类:

    • index = 0 :表示打开第一个摄像头,对于64位笔记本,打开的就是内置摄像头
    • index = 1 :表示打开第二个摄像头,对于64位笔记本,打开的就是连接笔记本的外置摄像头

    为了检测摄像头初始化是否成功,OpenCV提供了isOpened()方法,

    如果打开摄像头正确的话,接下来就可以读取视频的每一帧了,read()方法

    OpenCV 特别强调,不需要摄像头时,一定要关闭

    2.1 读取、显示摄像头视频

    实验目的:打开笔记本内置摄像头实时读取并显示视频。当按下空格键时,关笔记本内置摄像头,销毁显示摄像头视频的窗口

    代码:

    1. import cv2
    2. capture = cv2.VideoCapture(0) # 打开笔记本内置摄像头
    3. while (capture.isOpened()): # 笔记本内置摄像头被打开后
    4. retval, image = capture.read() # 从摄像头中实时读取视频
    5. cv2.imshow("Video", image) # 在窗口中显示读取到的视频
    6. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    7. if key == 32: # 如果按下空格键
    8. break
    9. capture.release() # 关闭笔记本内置摄像头
    10. cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

    展示:

    2.2 将摄像头视频转为灰度视频

    帧就是图像,将每一帧按照数字图像处理的方式处理就可以改变视频的样式

    这里展示将视频转为灰度视频的操作

    代码:

    1. import cv2
    2. capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
    3. while (capture.isOpened()): # 笔记本内置摄像头被打开后
    4. retval, image = capture.read() # 从摄像头中实时读取视频
    5. # 把彩色视频转换为灰度视频
    6. image_Gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    7. if retval == True: # 读取到摄像头视频后
    8. cv2.imshow("Video", image) # 在窗口中显示彩色视频
    9. cv2.imshow("Video_Gray", image_Gray) # 在窗口中显示灰度视频
    10. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    11. if key == 32: # 如果按下空格键
    12. break
    13. capture.release() # 关闭笔记本内置摄像头
    14. cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

    展示:

    2.3 保存摄像头视频的某一帧图像

    代码如下:

    1. import cv2
    2. cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
    3. while (cap.isOpened()): # 笔记本内置摄像头被打开后
    4. ret, frame = cap.read() # 从摄像头中实时读取视频
    5. cv2.imshow("Video", frame) # 在窗口中显示视频
    6. k = cv2.waitKey(1) # 图像的刷新时间为1毫秒
    7. if k == 32: # 按下空格键
    8. cap.release() # 关闭笔记本内置摄像头
    9. cv2.destroyWindow("Video") # 销毁名为Video的窗口
    10. cv2.imwrite("D:/copy.png", frame) # 保存按下空格键时摄像头视频中的图像
    11. cv2.imshow('img', frame) # 显示按下空格键时摄像头视频中的图像
    12. cv2.waitKey() # 刷新图像
    13. break
    14. cv2.destroyAllWindows() # 销毁显示图像的窗口

    效果:

    2.4 读取并显示两个摄像头

    编写一个程序,在打开笔记本内置摄像头实时读取并显示视频的同时,再打开一个连接笔记本的外置摄像头。当按下空格键时,关闭笔记本内置摄像头和连接笔记本的外置摄像头,销毁显示摄像头视频的窗口。

    代码:

    1. import cv2
    2. cap_Inner = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
    3. cap_Outer = cv2.VideoCapture(1, cv2.CAP_DSHOW) # 打开一个连接笔记本的外置摄像头
    4. while (cap_Inner.isOpened() & cap_Outer.isOpened()): # 两个摄像头都被打开后
    5. retval, img_Inner = cap_Inner.read() # 从笔记本内置摄像头中实时读取视频
    6. ret, img_Outer = cap_Outer.read() # 从连接笔记本的外置摄像头中实时读取视频
    7. # 在窗口中显示笔记本内置摄像头读取到的视频
    8. cv2.imshow("Video_Inner", img_Inner)
    9. # 在窗口中显示连接笔记本的外置摄像头读取到的视频
    10. cv2.imshow("Video_Outer", img_Outer)
    11. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    12. if key == 32: # 如果按下空格键
    13. break
    14. cap_Inner.release() # 关闭笔记本内置摄像头
    15. cap_Outer.release() # 关闭连接笔记本的外置摄像头
    16. cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

    这里只有一个内置摄像头,所以代码会报错...

    3、视频文件操作

    VideoCapture 类及其方法除了能够读取并显示摄像头视频外,还能够读取并显示视频文件。当窗口根据视频文件的时长显示视频文件时,便实现了播放视频文件的效果。

    3.1 读取、显示视频文件

    代码如下:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. while (video.isOpened()): # 视频文件被打开后
    4. retval, image = video.read() # 读取视频文件
    5. # 设置“Video”窗口的宽为420,高为300
    6. cv2.namedWindow("Video", 0)
    7. cv2.resizeWindow("Video", 420, 300)
    8. if retval == True: # 读取到视频文件后
    9. cv2.imshow("Video", image) # 在窗口中显示读取到的视频文件
    10. else: # 没有读取到视频文件
    11. break
    12. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    13. if key == 27: # 如果按下Esc键
    14. break
    15. video.release() # 关闭视频文件
    16. cv2.destroyAllWindows() # 销毁显示视频文件的窗口

    展示:


    调整 waitKeyO方法中的参数值可以控制视频文件的播放速度。例如,当 cv2.waitKey(1)时,视频文件的播放速度非常快;当cv2.waitKcy(50)时,就能够减缓视频文件的播放速度。

    3.2 将视频文件转为灰度视频


    使用处理图像的相关方法,能够将摄像头视频由彩色视频转换为灰度视频。那么,使用相同的方病也能够将视频文件由彩色视频转换为灰度视频。

    代码:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. while (video.isOpened()): # 视频文件被打开后
    4. retval, img_Color = video.read() # 读取视频文件
    5. # 设置“Video”窗口的宽为420,高为300
    6. cv2.namedWindow("Gray", 0)
    7. cv2.resizeWindow("Gray", 420, 300)
    8. if retval == True: # 读取到视频文件后
    9. # 把“公司宣传.avi”由彩色视频转换为灰度视频
    10. img_Gray = cv2.cvtColor(img_Color, cv2.COLOR_BGR2GRAY)
    11. cv2.imshow("Gray", img_Gray) # 在窗口中显示读取到的视频文件
    12. else: # 没有读取到视频文件
    13. break
    14. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    15. if key == 27: # 如果按下Esc键
    16. break
    17. video.release() # 关闭视频文件
    18. cv2.destroyAllWindows() # 销毁显示视频文件的窗口

    展示:

    3.3 视频文件的暂停和播放

    编写一个程序,读取并显示 PyCharm 当前项目路径下的视频文件。在播放视频文件的过程中,当按下空格键时,暂停播放视频:当再次按下空格键时,继续播放视频;当按下Esc键时,关闭视频文件并销毁显示视频文件的窗口

    代码如下:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. while (video.isOpened()): # 视频文件被打开后
    4. retval, image = video.read() # 读取视频文件
    5. # 设置“Video”窗口的宽为420,高为300
    6. cv2.namedWindow("Video", 0)
    7. cv2.resizeWindow("Video", 420, 300)
    8. if retval == True: # 读取到视频文件后
    9. cv2.imshow("Video", image) # 在窗口中显示读取到的视频文件
    10. else: # 没有读取到视频文件
    11. break
    12. key = cv2.waitKey(50) # 窗口的图像刷新时间为50毫秒
    13. if key == 32: # 如果按下空格键
    14. cv2.waitKey(0) # 不刷新图像,实现暂停效果
    15. continue # 再按一次空格键,继续播放
    16. if key == 27: # 如果按下Esc键
    17. break
    18. video.release() # 关闭视频文件
    19. cv2.destroyAllWindows() # 销毁显示视频文件的窗口

    展示:

    3.4 获取视频文件的属性

    在实际应用中,有时需要知道视频文件的属性。VideoCapture提供了get()方法

    其中,propId 的参数如下:

    视频是由大量的、连续的图像构成的,把其中的每幅图像称作帧

    帧数指的是视频文件中含有的图像总数,帧数越多,视频播放时越流畅

    在播放视频的过程中,把每秒显示图像的数量称作帧速率(IPS,单位:帧/s)

    宽度指的是图像在水平方向上含有的像素总数、帧高度指的是图像在垂直方向上含有的像素总数

    代码:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
    4. frame_Count = video.get(cv2.CAP_PROP_FRAME_COUNT) # 获取视频文件的帧数
    5. frame_Width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) # 获取视频文件的帧宽度
    6. frame_Height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 获取视频文件的帧高度
    7. # 输出获取到的属性值
    8. print("帧速率:", fps)
    9. print("帧数:", frame_Count)
    10. print("帧宽度:", frame_Width)
    11. print("帧高度:", frame_Height)

    控制台展示:

    动态视频属性的实验:

    代码:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
    4. frame_Num = 1 # 用于记录第几幅图像(即第几帧),初始值为1(即第1幅图像)
    5. while (video.isOpened()): # 视频文件被打开后
    6. retval, frame = video.read() # 读取视频文件
    7. # 设置“Video”窗口的宽为420,高为300
    8. cv2.namedWindow("Video", 0)
    9. cv2.resizeWindow("Video", 420, 300)
    10. if retval == True: # 读取到视频文件后
    11. # 当前视频播放到第几帧
    12. cv2.putText(frame, "frame: " + str(frame_Num), (0, 100),
    13. cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)
    14. # 该帧对应着视频的第几秒
    15. cv2.putText(frame, "second: " + str(round(frame_Num / fps, 2)) + "s",
    16. (0, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 5)
    17. cv2.imshow("Video", frame) # 在窗口中显示读取到的视频文件
    18. else: # 没有读取到视频文件
    19. break
    20. key = cv2.waitKey(50) # 窗口的图像刷新时间为50毫秒
    21. frame_Num += 1 #
    22. if key == 27: # 如果按下Esc键
    23. break
    24. video.release() # 关闭视频文件
    25. cv2.destroyAllWindows() # 销毁显示视频文件的窗口

    展示:

    73 代表播放到当前视频的第 73 帧

    2.92s 代码播放到当前视频的第 2.92秒

    4、保存视频操作

    这里介绍保存摄像头和视频文件的操作

    OpenCV提供了VideoWriter类,具体如下

    在OpenCV中,使用cv2.VideoWriter_fource() 确定视频编码格式,具体如下

    例如:在Windows中,fource值为cv2.VideoWriter_fource('X','Y','I','D'),帧速率为20,帧大小为640*480。把一段视频保存在当前目录下,关键代码如下:

    *('XVID')是解引用操作,会将'XVID'解码为'X','Y','I','D'

    把视频保存的话,需要使用write()方法,

    4.1 保存一段摄像头的视频

    代码:

    1. import cv2
    2. capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
    3. fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
    4. output = cv2.VideoWriter("output.avi", fourcc, 20, (640, 480)) # 创建VideoWriter类对象
    5. while (capture.isOpened()): # 笔记本内置摄像头被打开后
    6. retval, frame = capture.read() # 从摄像头中实时读取视频
    7. if retval == True: # 读取到摄像头视频后
    8. output.write(frame) # 在VideoWriter类对象中写入读取到的帧
    9. cv2.imshow("frame", frame) # 在窗口中显示摄像头视频
    10. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    11. if key == 27: # 如果按下Esc键
    12. break
    13. capture.release() # 关闭笔记本内置摄像头
    14. output.release() # 释放VideoWriter类对象
    15. cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

    展示:

    代码可以重复运行,不过每次都会覆盖上一次的视频

    4.2 保存10s的摄像头视频

    上述的保存视频,是人为控制的,这里提供代码可以录制固定时长的视频

    代码:

    1. import cv2
    2. capture = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 打开笔记本内置摄像头
    3. fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
    4. fps = 20 # 帧速率
    5. # 创建VideoWriter类对象
    6. output = cv2.VideoWriter("ten_Seconds.avi", fourcc, fps, (640, 480))
    7. frame_Num = 10 * fps # 时长为10秒的摄像头视频含有的帧数
    8. # 笔记本内置摄像头被打开且时长为10秒的摄像头视频含有的帧数大于0
    9. while (capture.isOpened() and frame_Num > 0):
    10. retval, frame = capture.read() # 从摄像头中实时读取视频
    11. if retval == True: # 读取到摄像头视频后
    12. output.write(frame) # 在VideoWriter类对象中写入读取到的帧
    13. cv2.imshow("frame", frame) # 在窗口中显示摄像头视频
    14. key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒
    15. frame_Num -= 1 # 时长为10秒的摄像头视频含有的帧数减少一帧
    16. capture.release() # 关闭笔记本内置摄像头
    17. output.release() # 释放VideoWriter类对象
    18. cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

    展示:

    右键可以查看视频的属性:

    4.3 读取视频文件并且保存视频文件

    读取视频文件,然后将视频保存

    代码:
     

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
    4. # 获取视频文件的帧大小
    5. size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),
    6. int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    7. fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
    8. output = cv2.VideoWriter("copy.avi", fourcc, fps, size) # 创建VideoWriter类对象
    9. while (video.isOpened()): # 视频文件被打开后
    10. retval, frame = video.read() # 读取视频文件
    11. if retval == True: # 读取到视频文件后
    12. output.write(frame) # 在VideoWriter类对象中写入读取到的帧
    13. else:
    14. break
    15. print("公司宣传.avi已经保存为PyCharm当前项目路径下的copy.avi。") # 控制台输出提示信息
    16. video.release() # 关闭视频文件
    17. output.release() # 释放VideoWriter类对象

    4.4 读取视频并保存前10s的视频文件

    代码如下:

    1. import cv2
    2. video = cv2.VideoCapture("公司宣传.avi") # 打开视频文件
    3. fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
    4. # 获取视频文件的帧大小
    5. size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),
    6. int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    7. fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式
    8. output = cv2.VideoWriter("ten_Seconds.avi", fourcc, fps, size) # 创建VideoWriter类对象
    9. frame_Num = 10 * fps # 视频文件的前10秒视频含有的帧数
    10. # 视频文件被打开后且视频文件的前10秒视频含有的帧数大于0
    11. while (video.isOpened() and frame_Num > 0):
    12. retval, frame = video.read() # 读取视频文件
    13. if retval == True: # 读取到视频文件后
    14. output.write(frame) # 在VideoWriter类对象中写入读取到的帧
    15. frame_Num -= 1 # 视频文件的前10秒视频含有的帧数减少一帧
    16. # 控制台输出提示信息
    17. print("公司宣传.avi的前10s视频已经保存为PyCharm当前项目路径下的ten_Seconds.avi。")
    18. video.release() # 关闭视频文件
    19. output.release() # 释放VideoWriter类对象

    展示:

  • 相关阅读:
    【Web_自动化测试_Python3_webdriver_etree_批量下载京东图片】通过地址抓取静态网页+解析标题和链接+通过链接批量下载图片
    C语言 数组
    《QT从基础到进阶·十六》QT实现客户端和服务端的简单交互
    浅谈 CDN 加速
    [ C++ ] 抽象类 虚函数 虚函数表 -- C++多态(1)
    【最详细】最全java面试题及答案(210道)
    网络安全人才青黄不接、数字化转型迫在眉睫、你还在犹豫吗?
    Spring MVC
    Grafana----Grafana快速体验
    Xcode工程统计代码行数(Swift版)
  • 原文地址:https://blog.csdn.net/qq_44886601/article/details/136529808