本系列专栏写作方式

本系列专栏写作将采用首创的问答式写作形式,快速让你学习到 OpenCV 的初级、中级、高级知识。

2. OpenCV 中摄像头捕获与视频处理

OpenCV 除了应用在图像处理领域外,还会应用到视频处理领域,接下来我们就将学习到,如何通过Python OpenCV 对摄像头捕获或者视频文件进行处理。

视频文件将从三个方向入手,分别是读取文件,显示视频,保存视频。

本文将为你核心解决以下2个函数:cv2.VideoCapture 与 cv2.VideoWrite,基于这2个函数,会衍生出其它相关函数,具体参照下文。

在 OpenCV 中操作摄像头相关注意事项和解决方案

摄像头相较于视频,差异在一个是实时图像,一个是既定内容。如果想要捕获到视频,用到的是cv2.VideoCapture 函数,该函数的第一个参数是设备的索引号,如果你使用的是笔记本电脑,默认一般是0,表示的内置摄像头,如果链接了外置,可以修改该数字即可。

最简单的测试代码如下:

import cv2
import numpy as npcap = cv2.VideoCapture(0)while True:ret, frame = cap.read()# 转变成灰度图gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow("frame", gray)if cv2.waitKey() & 0xFF == ord("x"):break# 关闭摄像
cap.release()
cv2.destroyAllWindows()

该代码在运行时,如果你电脑未安装摄像头或者驱动异常,都会导致报错,例如下述BUG

error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

该问题虽然报错出现在 cv2.cvtColor函数,但是原因是 frame 为空,即cap.read()读取失败导致的。

这里在实际编码过程中,需要增加一个判断,cap.read() 函数会返回一个状态布尔值,如果读取到数据,返回真,否则返回假,测试如下代码(下述代码的停止,需要按键盘上的CTRL+C ):

import cv2
import numpy as npcap = cv2.VideoCapture(0)while True:ret, frame = cap.read()print(ret)# 关闭摄像
cap.release()
cv2.destroyAllWindows()

测试完毕之后,我们修改本文一开始的代码,让其更加健壮。

while True:ret, frame = cap.read()if ret:# 转变成灰度图gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow("frame", gray)# pass ...

这里存在一个常见,但是及容易被忽视的问题,就是很多时候,我们并不知道电脑上有没有摄像头,或者摄像头的设备号,该如何进行操作

你可以按照下述代码进行检测:

import cv2
import numpy as npfor cn_num in range(0, 5):cap = cv2.VideoCapture(cn_num)if cap.isOpened():break

以上代码运行的原理是,按照顺序依次打开设备 0~5,当发现摄像头被成功打开,返回跳出。

上述代码还提及了一个新的函数 cap.isOpened,该函数用来检测摄像头是否初始化(能被打开),初始化成功返回 True。

在 OpenCV 中操作视频文件相关注意事项和解决方案

其实操作视频文件与操作摄像头操作基本一致,唯一修改的就是cv2.VideoCapture 函数设备号即可。

这里将设备号修改为视频文件路径。

接下来,我们先看一段代码,认识基本用法。

import numpy as np
import cv2cap = cv2.VideoCapture('test.mp4')while cap.isOpened():ret, frame = cap.read()# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imshow('frame', frame)if cv2.waitKey(25) & 0xFF == 27:breakcap.release()
cv2.destroyAllWindows()

其中最需要注意的一个地方,不是 cv2.VideoCapture(‘test.mp4’) 函数读取文件,而是 cv2.waitKey(25),这个地方需要设置好对应的视频,如果数值特别小,例如 1,视频就会快速播放,设置太高播放又会变慢,一般建议设置为 25

当然,上述代码注释的部分,如果取消,就会变成一个灰度视频。

甚至可以直接将视频进行翻转,用到函数为:cv2.flip(frame, 0),

import numpy as np
import cv2 cap = cv2.VideoCapture('test.mp4')while cap.isOpened():ret, frame = cap.read()if ret == True:frame = cv2.flip(frame, 0)cv2.imshow('frame', frame)if cv2.waitKey(25) & 0xFF == 27:breakcap.release()
cv2.destroyAllWindows()

上述代码运行如下:

接下来我们用视频来学习一下一些操作属性的方法。

cv2.VideoCapture.get(propId) 可以访问视频的某些功能,其中 propId 是一个从0到18的数字,每个数字表示视频的属性。

取值清单如下(该清单只作为查询参考使用):

  • 0 - cv2.CAP_PROP_POS_MSEC: 视频文件的当前位置(ms);
  • 1 - cv2.CAP_PROP_POS_FRAMES:从0开始索引帧,帧位置;
  • 2 - cv2.CAP_PROP_POS_AVI_RATIO:视频文件的相对位置(0表示开始,1表示结束);
  • 3 - cv2.CAP_PROP_FRAME_WIDTH:视频流的帧宽度;
  • 4 - cv2.CAP_PROP_FRAME_HEIGHT: 视频流的帧高度;
  • 5 - cv2.CAP_PROP_FPS:帧率;
  • 6 - cv2.CAP_PROP_FOURCC : 编解码器四字符代码;
  • 7 - cv2.CAP_PROP_FRAME_COUNT :视频文件的帧数;
  • 8 - cv2.CAP_PROP_FORMAT:retrieve()返回的Mat对象的格式;
  • 9 - cv2.CAP_PROP_MODE :后端专用的值,指示当前捕获模式;
  • 10 - cv2.CAP_PROP_BRIGHTNESS :图像的亮度,仅适用于支持的相机;
  • 11 - cv2.CAP_PROP_CONTRAST :图像对比度,仅适用于相机;
  • 12 - cv2.CAP_PROP_SATURATION:图像饱和度,仅适用于相机;
  • 13 - cv2.CAP_PROP_HUE:图像色调,仅适用于相机;
  • 14 - cv2.CAP_PROP_GAIN:图像增益,仅适用于支持的相机;
  • 15 - cv2.CAP_PROP_EXPOSURE:曝光,仅适用于支持的相机;
  • 16 - cv2.CAP_PROP_CONVERT_RGB:布尔标志,指示是否应将图像转换为RGB;
  • 17 - cv2.CAP_PROP_WHITE_BALANCE:目前不支持;
  • 18 - cv2.CAP_PROP_RECTIFICATION:立体摄像机的整流标志。

有了上述清单,可以获取视频较多的属性值了,例如获取宽度与高度。

cap = cv.VideoCapture('test.mp4')
print("宽度:%s,高度:%s" % (cap.get(3), cap.get(4)))

有 get 方法,对应的就存在 set 函数,函数原型如下:

cap.set(propId,value) # 进行修改,value 是修改后的值

但这个地方要注意下,上面 set 函数只对采集摄像头有用,如果读取的是视频文件,上述内容就不在起作用了。

如果你还是希望实现修改视频文件的窗口大小,那可以使用下述方案。

cv2.namedWindow("frame", 0)
cv2.resizeWindow("frame", 800,300)

如果想希望查看视频播放的当前位置、帧率、帧数,可以直接使用下述代码。

time = cap.get(cv2.CAP_PROP_POS_MSEC)
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)

当然,使用属性值也可以。

time = cap.get(0)
fps = cap.get(5)
total_frames = cap.get(7)

在 OpenCV 中捕获视频并保存

图片的保存使用函数 cv2.imwrite即可实现,但视频保存,需要与cv2.VideoCapture对应着,创建一个 VideoWriter对象,而且还需要确定文件的名称,视频 FourCC 编码,频率,帧大小,isColor标签,该标签如果为 True 则保存彩色图,否则是灰度图。

首先对 FourCC 进行一下说明,该编码是一个4字节码,表示的是视频编码格式。

例如对于 MJPG,它有两种写法。

注意这是 OpenCV 3 写法,网上现在大多数博客都是 OpenCV 2 写法。

cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
cv2.VideoWriter_fourcc(*'MJPG')

常见编码说明:

  • MJPG编码器编码的视频非常大;
  • X264 编码器编码的视频很小;
  • XVID编码器优先选择,质量较高且体积较小。

cv2.VideoWriter函数原型如下:

cv2.VideoWriter( filename, fourcc, fps, frameSize[, isColor] )

相关参数:

  • filename:视频保存文件名称;
  • fourcc:视频编解码器的4字节代码;
  • fps:帧率;
  • frameSize:帧大小;
  • isColor:如果为True,则视频为彩色,否则为灰度视频,默认为True。

测试代码如下,代码之后跟相关问题的说明。

import numpy as np
import cv2cap = cv2.VideoCapture("test.mp4")width = int(cap.get(3))
height = int(cap.get(4))
fps = cap.get(5)# FourCC 编码是 XVID
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter("test1.avi", fourcc, fps, (width, height))while 1:ret, frame = cap.read()if frame is None:breakelse:# 对每一帧都进行处理# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)out.write(frame)cv2.imshow("video", frame)k = cv2.waitKey(25) & 0xFF if k == 27:breakcap.release()
out.release()
cv2.destroyAllWindows()

在调用函数 cv2.VideoWriter("test1.avi", fourcc, fps, (width, height)) 的时候,注意需要 (width, height) 必须是整数,需要强制转换一下。

其中 20 是 fps ,如果想保存成灰度视频,按照下述代码修改即可。

out = cv2.VideoWriter("test1.avi", fourcc, fps, (width, height),False)
# ......
# 注意在读取每一帧的时候,都要转换成灰度图
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# ......

如果在编码时出现如下错误,注意是 frameSize 参数设置的问题

VideoWriter() missing required argument 'frameSize' (pos 5)

对应的代码位置按照如下修改即可

out = cv2.VideoWriter("test1.avi", fourcc, fps, (int(width), int(height)))

下一个常见的问题是,如果不是读取视频文件,直接采集的摄像头数据,使用 fps = cap.get(5) 是无法获取到具体的 fps 值的,此时只能进行手动设定。

该值的设定需要依据自己电脑的配置,一般设置为10~20即可。

本文章橡皮擦原为 ebaina 社区写作,现补发到CSDN频道。

番外2. OpenCV 中摄像头捕获与视频处理与常见问题解决方案相关推荐

  1. 基于opencv在摄像头ubuntu根据视频获取

     基于opencv在摄像头ubuntu根据视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译执行步骤 安装编译opencv-2.3  參考h ...

  2. OpenCV中的光流及视频特征点追踪

    OpenCV中的光流及视频特征点追踪 1. 效果图 2. 原理 2.1 什么是光流?光流追踪的前提.原理 2.2 光流的应用 2.3 光流的2种方法 3. 源码 3.2 稀疏光流追踪 3.2 优化版稀 ...

  3. C++/Qt 使用OpenCV打开摄像头,旋转视频,计算fps

    C++/Qt 使用OpenCV打开摄像头,旋转视频,计算fps 设置摄像头参数 不要随意修改,同时也不一样会修改成功,需要根据实际摄像头的参数选择设置 /*设置摄像头参数 不要随意修改capture. ...

  4. python读取视频流做人脸识别_基于OpenCV和Keras实现人脸识别系列——二、使用OpenCV通过摄像头捕获实时视频并探测人脸、准备人脸数据...

    基于OpenCV和Keras实现人脸识别系列手记: 项目完整代码参见Github仓库. 本篇是上面这一系列手记的第二篇. 在Opencv初接触,图片的基本操作这篇手记中,我介绍了一些图片的基本操作,而 ...

  5. python调用摄像头录制视频_Python OpenCV使用摄像头捕获视频

    我们知道,OpenCV是一款强大的跨平台的计算机视觉库,使用它能完成我们对于图像和视频处理的很多功能,今天,我们使用OpenCV来捕获计算机摄像头的视频. 使用OpenCV捕获摄像头视频 我们知道,视 ...

  6. python使用opencv调取摄像头捕获图片或视频通用模板

    之前一直不清楚opencv调用摄像头的具体方法,于是参考b站视频写了个通用模板,以后可以根据需要自行调整.视频链接 先定义图片和视频的保存路径 img_path = './img_video/test ...

  7. 使用opencv调用摄像头然后录制视频和保存文件

    用 OpenCV 开发经常用到摄像头,从 Camera获取图像后用OpenCV的算法进行处理,但是一般我们处理完图像之后,还需要将视频保存下来,比如保存成avi.mp4等格式.怎么保存呢?其实Open ...

  8. opencv打开摄像头、录制视频

    目录 一.参考: 1.运行代码:Opencv2.4学习::摄像头读取&&视频写入: 1.opencv读取视频,摄像头,保存视频代码 (2012-10-18 21:25:26) 1.Op ...

  9. 委外采购业务中发生的赔偿,扣减加工费的解决方案

    在委外采购业务中,根据与委托加工商的协议,在发生质量问题发其它条款内规定的情况时,可能会发生由加工商赔偿的业务,一般赔偿的常见做法是用赔款冲减加工费,甚至在扣完所有加工费后,仍需要加工商额外支付赔款的 ...

  10. unity android视频录制sdk,Unity中保存EveryPlay录制视频到本地的解决方案

    五月 14.2018. 0 Comment 在Unity中使用EveryPlay录制视频时,有如下问题: 1. EveryPlay API(截止到现在,之后Final Version可能会增加)不支持 ...

最新文章

  1. python数据模型的意义_Python 数据模型
  2. JBOSS只能本机localhost和127.0.0.1能访问的解决
  3. CentOS Linux解决Device eth0 does not seem to be present 但是没有发现eth1
  4. 元计算:IT巨头的金钱收割机,核武器
  5. SAP- MM 委外加工(Subconctracting)流程
  6. 鸿蒙系统sp3什么意思,怎么看电脑系统是哪个版本的?例如SP2 SP3?
  7. P4781-[模板]拉格朗日插值
  8. MySQL主从延时这么长,怎么优化?
  9. 小数变百分数_小数除法三要“点”
  10. python : class定义中的:__dict__,__setattr__,__getattribute__,__getattr__,
  11. 卸载office 2003出现pro11.msi
  12. 银联的支付创新产业基地将落户安徽合肥 投资达80亿
  13. 如何在码学堂组织练习、考试、竞赛?
  14. 远程桌面连接只有2个会话活动
  15. Win10 - 彻底禁用Cortana的方法
  16. python协程怎么做数据同步_Python 中的进程、线程、协程、同步、异步、回调
  17. 手机端上传照片实现 压缩、拖放、缩放、裁剪、合成拼图等功能
  18. Qt中Q_NULLPTR的作用
  19. RocketMQ-01
  20. SkeyeARS全景AR增强监视系统助力林业部门打造森林防火视频监控网

热门文章

  1. 腾讯云uniapp云直播和即时通信插件接入流程
  2. 城市数据大脑:小汽车儿堵成翔?NONONO!
  3. CSS基础教程 -- 媒体查询屏幕适配
  4. 【魔兽世界插件】魔兽世界插件实战笔记从入门到放弃的心理历程 第五节 窗体文字材质设置
  5. 计算机毕业设计之 疫情防控志愿者管理系统
  6. [Python] 贡献度分析
  7. 匿名发送邮件python_邮箱伪造之搭建匿名SMTP服务器
  8. 屏蔽计算机电缆套什么定额,DJYPVP4*2*1.0计算机屏蔽电缆-DJYVP分屏蔽计算机电缆...
  9. 新浪微博分享遇到的心酸的问题
  10. mysql oracle minus_Oracle Minus关键字