从0-1轻松入门 OpenCV4
Posted Amo Xiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0-1轻松入门 OpenCV4相关的知识,希望对你有一定的参考价值。
目录
一、环境安装
该文章是基于 Python 实现,故直接使用 pip 工具进行第三方模块的安装,命令如下:
pip/pip3 install opencv-python matplotlib numpy
如果要提高下载速度,可以自己加镜像
二、图像&视频的加载与展示
2.1 如何通过OpenCV创建和显示窗口
1. 导包
import cv2 # 导入cv2包
2. 创建窗口
# namedWindow(winname, flags=None)
# 第一个参数:窗口的名称 第二个参数:窗口的属性
cv2.namedWindow('new', cv2.WINDOW_AUTOSIZE)
# resizeWindow(winname, width, height)
# winnname:窗口名称 width:宽度 height:高度
3. 显示
imshow() 方法用于显示图像,其语法格式如下:
cv2.imshow(winname, mat)
参数说明:
- winname:显示图像的窗口名称。
- mat:要显示的图像。
waitKey() 方法用于等待用户按下键盘上按键的时间。当用户按下键盘上的任意按键时,将执行 waitKey() 方法,并且获取 waitKey() 方法的返回值。其语法格式如下:
retval = cv2.waitKey(delay)
参数说明:
- retval:与被按下的按键相对应的 ASCII 码。例如,Esc 键的 ASCII 码是 27,当用户按下【Esc】键时,waitKey() 方法的返回值是 27。如果没有按键被按下,waitKey() 方法的返回值是 -1。
- delay:等待用户按下键盘上按键的时间,单位为
毫秒(ms)
。当 delay 的值为负数、0 或者为空时,表示无限等待用户按下键盘上按键的时间。
destroyAllWindows() 方法用于销毁所有正在显示图像的窗口,其语法格式如下:
cv2.destroyAllWindows()
【案例1】创建和显示窗口。
import cv2
cv2.namedWindow('new', cv2.WINDOW_AUTOSIZE)
# 0可以自动转换,这里刚开始先写0
cv2.imshow('new', 0)
key = cv2.waitKey(0)
if key == "q":
exit()
cv2.destroyAllWindows()
2.2 如何通过OpenCV加载显示图片
OpenCV 提供了用于读取图像的 imread() 方法,其语法格式如下:
image = cv2.imread(filename, flags)
参数说明:
- image:是 imread() 方法的返回值,返回的是读取到的图像。
- filename:要读取的图像的完整文件名。例如,要读取当前项目目录下 pic 文件夹中的 IU.jpeg,filename 的值为
IU.jpeg
(双引号是英文格式的)。 - flags:读取图像颜色类型的标记。当 flags 的默认值为 1 时,表示读取的是彩色图像,此时的 flags 值可以省略;当 flags 的值为 0 时,表示读取的是灰度图像(如果读取的是彩色图像,也将转换为与彩色图像对应的灰度图像)
【案例2】读取当前目录下pic文件中的IU.jpeg图片。
import cv2 # 导包
# 1.创建窗口
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
# 自己根据实际情况判断是否设置窗口大小(这里笔者不进行设置)
# 2.读取图片
# flags参数不写,默认以彩色图像进行显示 路径可以写绝对路径、相对路径
# flags=0 灰度图像显示
img = cv2.imread("./pic/IU.jpeg")
# print(img) 这里会输出部分像素值,后续会进行讲解!
# 3.显示窗口
cv2.imshow("img", img)
# 4.按q键退出
key = cv2.waitKey()
if key == "q":
exit()
# 5.销毁所有窗口
cv2.destroyAllWindows()
上述代码的运行结果如下图所示:
将上述代码中的 img = cv2.imread("./pic/IU.jpeg") 改为下面的代码:
img = cv2.imread("./pic/IU.jpeg", 0)
即可得到由 IU.jpeg 转换得到的灰度图像,如下图所示:
【案例3】将上述代码进行优化。
import cv2 # 导包
cv2.namedWindow("img", cv2.WINDOW_NORMAL) # 1.创建窗口
img = cv2.imread("./pic/IU.jpeg", 1) # 2.读取图像
cv2.imshow("img", img) # 3.显示窗口
key = cv2.waitKey() # 4.按q键退出
if key & 0xFF == ord("q"): # ord()函数取某个字符的ascii值
cv2.destroyAllWindows() # 5.销毁所有窗口
2.3 如何通过OpenCV保存文件
OpenCV 提供了用于按照指定路径保存图像的 imwrite() 方法,其语法格式如下:
cv2.imwrite(filename, img)
参数说明:
- filename:保存图像时所用的完整路径。
- img:要保存的图像
【案例4】保存图像。把当前项目下pic文件夹中的IU.jpeg 保存为IU2.png
import cv2 # 导包
cv2.namedWindow("img", cv2.WINDOW_NORMAL) # 1.创建窗口
img = cv2.imread("./pic/IU.jpeg", 1) # 2.读取图像
while True:
cv2.imshow("img", img) # 3.显示窗口
key = cv2.waitKey() # 4.按q键退出
if key & 0xFF == ord("q"): # ord()函数取某个字符的ascii值
break
elif key & 0xFF == ord("s"): # 按s键,保存
cv2.imwrite("./pic/IU2.png", img)
else:
print(key)
cv2.destroyAllWindows()
上述代码的运行结果如下图所示:
**获取图像属性:处理图像的过程中,经常需要获取图像的大小、类型等图像属性。为此,OpenCV 提供了 shape、size 和 dtype 这3个常用属性。这3个常用属性的具体含义分别如下:
- shape:如果是彩色图像,那么获取的是一个包含图像的水平像素、垂直像素、通道数的数组,即(垂直像素、水平像素、通道数);如果是灰度图像,那么获取的是一个包含图像的水平像素、垂直像素的数组,即(垂直像素,水平像素)。
- size:获取的是图像包含的像素个数,其值为
水平像素 × 垂直像素 × 通道数
。(灰度图像的通道数为1)。 - dtype:获取的是图像的数据类型。
【案例5】分别获取彩色图像和灰度图像的属性。获取当前项目下pic文件夹中的IU.jpeg的属性,再获取由IU.jpeg转换得到的灰度图像的属性。代码如下:
import cv2
image_Color = cv2.imread("./pic/IU.jpeg") # 读取IU.jpeg
print("获取彩色图像的属性:")
print("shape =", image_Color.shape) # 打印彩色图像的(垂直像素,水平像素,通道数)
print("size =", image_Color.size) # 打印彩色图像包含的像素个数
print("dtype =", image_Color.dtype) # 打印彩色图像的数据类型
image_Gray = cv2.imread("./pic/IU.jpeg", 0) # 读取与IU.jpeg(彩色图像)对应的灰度图像
print("获取灰度图像的属性:")
print("shape =", image_Gray.shape) # 打印灰度图像的(垂直像素,水平像素)
print("size =", image_Gray.size) # 打印灰度图像包含的像素个数
print("dtype =", image_Gray.dtype) # 打印灰度图像的数据类型
上述代码的运行结果如下图所示:
说明:上图代码中 (480, 720, 3)
的含义是 IU.jpeg
的垂直像素是480,水平像素是720,通道数是3;(480, 720)
的含义是由 IU.jpeg
转换得到的灰度图像的垂直像素是480,水平像素是720,通道数是1。
2.4 如何利用OpenCV从摄像头采集视频
前提:电脑要有摄像头哟!
摄像头视频指的是从摄像头中实时读取到的视频。为了读取并显示摄像头视频,OpenCV 提供了 VideoCapture 类的相关方法,这些方法包括摄像头的初始化方法、检验摄像头初始化是否成功的方法、从摄像头中读取帧的方法、关闭摄像头的方法等。说明:视频是由大量的图像构成的,把这些图像称作帧。
2.4.1 VideoCapture 类。
VideoCapture 类提供了构造方法 VideoCapture(),用于完成摄像头的初始化工作。VideoCapture() 的语法格式如下:
capture = cv2.VideoCapture(index)
参数说明:
- capture:要打开的摄像头。
- index:摄像头的设备索引。
当 index 的值为0时,表示要打开的是第1个摄像头;即表示要打开的是笔记本内置摄像头。当 index 的值为1时,表示要打开的是第2个摄像头;即表示要打开的是一个连接笔记本的外置摄像头。关键代码如下:
capture = cv2.VideoCapture(0) # 内置
capture = cv2.VideoCapture(1) # 外置
为了检验摄像头初始化是否成功,VideoCapture 类提供了 isOpened()方法。isOpened() 方法的语法格式如下:
retval = cv2.VideoCapture.isOpened()
# 简写:retval = capture.isOpened()
参数说明:
- retval:isOpened() 方法的返回值。如果摄像头初始化成功,retval 的值为 True;否则,retval 的值为 False。
摄像头初始化后,就可以从摄像头中读取帧了,为此 VideoCapture 类提供了 read() 方法。read() 方法的语法格式如下:
retval, image = cv2.VideoCapture.read()
# 可以简写为retval, image = capture.read()
参数说明:
- retval:是否读取到帧。如果读取到帧,retval 的值为 True;否则,retval 的值为 False。
- image:读取到的帧。因为帧指的是构成视频的图像,所以可以把
读取到的帧
理解为读取到的图像
。
OpenCV 在官网中特别强调,在不需要摄像头时,要关闭摄像头。为此,VideoCapture 类提供了 release() 方法。release() 方法的语法格式如下:
cv2.VideoCapture.release()
# 可以简写为capture.release()
【案例6】读取并显示摄像头视频。
import cv2 # 导包
# 1.创建窗口并设置窗口大小
cv2.namedWindow("video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("video", 640, 480)
# 2.实例化VideoCapture类 获取摄像头
capture = cv2.VideoCapture(0)
# 3.读取视频并显示窗口
while capture.isOpened(): # # 笔记本内置摄像头被打开后
retval, img = capture.read() # 读取视频帧
cv2.imshow("cv2", img) # 窗口中显示视频帧
key = cv2.waitKey(1) # 等待用户按下键盘按键的时间为1ms
if key & 0xFF == ord("q"): # 等待键盘事件如果为q,则退出
break
capture.release() # 释放摄像头资源
cv2.destroyAllWindows() # 销毁所有窗口
2.5 如何利用OpenCV从多媒体文件中读取视频帧
OpenCV 从多媒体文件中读取视频帧,只需要在 ##2.4
的基础上更改传入的参数即可,其语法格式如下:
video = cv2.VideoCapture(filename)
参数说明:
- video:要打开的视频。
- filename:打开视频的文件名。
【案例7】读取并显示视频文件。读取当前项目路径下video文件夹中名为 dance.mp4
的视频文件。代码如下:
import cv2 # 导包
# 1.创建窗口并设置窗口大小
cv2.namedWindow("video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("video", 640, 480)
# 2.实例化VideoCapture类 打开多媒体文件
video = cv2.VideoCapture("./video/dance.mp4")
# 3.读取视频并显示窗口
while video.isOpened(): # 视频文件被打开后
retval, img = video.read() # 读取视频帧
cv2.imshow("video", img) # 窗口中显示读取到的视频文件
key = cv2.waitKey(22) # 等待用户按下键盘按键的时间为22ms
if key & 0xFF == ord("q"): # 等待键盘事件如果为q,则退出
break
video.release() # 释放摄像头资源
cv2.destroyAllWindows() # 销毁所有窗口
【案例8】将视频文件由彩色视频转换为灰度视频。先将当前项目路径下video文件夹中名为 guitar.mp4
的视频文件由彩色视频转换为灰度视频,再显示转换后的灰度图像,代码如下:
import cv2 # 导包
# 1.创建窗口并设置窗口大小
cv2.namedWindow("video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("video", 640, 480)
# 2.实例化VideoCapture类 打开多媒体文件
video = cv2.VideoCapture("./video/guitar.mp4")
# 3.读取视频并显示窗口
while video.isOpened(): # 视频文件被打开后
retval, img = video.read() # 读取视频帧
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 由彩色视频转换为灰度图像
cv2.imshow("video", img_gray) # 窗口中显示读取到的视频文件
key = cv2.waitKey(22) # 等待用户按下键盘按键的时间为22ms
if key & 0xFF == ord("q"): # 等待键盘事件如果为q,则退出
break
video.release() # 释放摄像头资源
cv2.destroyAllWindows() # 销毁所有窗口
上述代码的运行结果如下图所示:
【案例9】视频的暂停播放和继续播放。读取并显示当前项目路径下 video
文件中名为 dance.mp4
的视频文件。在播放视频文件的过程中,当按下空格键时,暂停播放视频;当再次按下空格键时,继续播放视频;当按下 q
键时,关闭视频文件并销毁显示视频文件的窗口。代码如下:
import cv2 # 导包
# 1.创建窗口并设置窗口大小
cv2.namedWindow("video", cv2.WINDOW_NORMAL)
cv2.resizeWindow("video", 640, 480)
# 2.实例化VideoCapture类 打开多媒体文件
video = cv2.VideoCapture("./video/dance.mp4")
# 3.读取视频并显示窗口
while video.isOpened(): # 视频文件被打开后
retval, img = video.read() # 读取视频帧
cv2.imshow("video", img) # 窗口中显示读取到的视频文件
key = cv2.waitKey(22) # 等待用户按下键盘按键的时间为22ms
if key & 0xFF == ord("q"): # 等待键盘事件如果为q,则退出
break
elif key & 0xFF == ord(" "):
key = cv2.waitKey(0) # 无限等待用户按下键盘按键的时间,实现暂停效果
continue
video.release() # 释放摄像头资源
cv2.destroyAllWindows() # 销毁所有窗口
在实际开发中,有时需要获取视频文件的属性。为此,VideoCapture 类提供了 get() 方法。get() 方法的语法格式如下:
retval = cv2.VideoCapture.get(propId)
参数说明:
- retval:获取到与 propId 对应的属性值。
- propId:视频文件的属性值。
- VideoCapture 类提供视频文件的属性值及其含义如下表所示:
视频文件的属性值 | 含义 |
---|---|
cv2.CAP_PROP_POS_MSEC | 视频文件播放时的当前位置(单位:ms) |
cv2.CAP_PROP_POS_FRAMES | 帧的索引,从0开始 |
cv2.CAP_PROP_POS_AVI_RATIO | 视频文件的相对位置(0表示开始播放,1表示结束播放) |
cv2.CAP_PROP_FRAME_WIDTH | 视频文件的帧宽度 |
cv2.CAP_PROP_FRAME_HEIGHT | 视频文件的帧高度 |
cv2.CAP_PROP_FPS | 帧速率 |
cv2.CAP_PROP_FOURCC | 用4个字符表示的视频编码格式 |
cv2.CAP_PROP_FRAME_COUNT | 视频文件的帧数 |
cv2.CAP_PROP_FORMAT | retrieve()方法返回的Mat对象的格式 |
cv2.CAP_PROP_MODE | 指示当前捕获模式的后端专用的值 |
cv2.CAP_PROP_CONVERT_RGB | 指示是否应将图像转换为RGB |
说明:
- 视频是由大量的、连续的图像构成的,把其中的每一幅图像称作一帧。
- 帧数指的是视频文件中含有的图像总数,帧数越多,视频播放时越流畅。
- 在播放视频的过程中,把每秒显示图像的数量称作帧速率(FPS,单位:帧/s)。
- 帧宽度指的是图像在水平方向上含有的像素总数。
- 帧高度指的是图像在垂直方向上含有的像素总数。
【案例10】获取并输出视频文件的指定属性值。先获取 dance.mp4
的帧速率、帧数、帧宽度和帧高度,再把上述4个属性值输出在PyCharm的控制台上。代码如下:
import cv2
video = cv2.VideoCapture("./video/dance.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
frame_Count = video.get(cv2.CAP_PROP_FRAME_COUNT) # 获取视频文件的帧数
frame_Width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) # 获取视频文件的帧宽度
frame_Height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 获取视频文件的帧高度
# 输出获取到的属性值
print("帧速率:", fps)
print("帧数:", frame_Count)
print("帧宽度:", frame_Width)
print("帧高度:", frame_Height)
上述代码的运行结果如下图所示:
2.6 如何利用OpenCV将视频数据录制成多媒体文件
VideoWriter 类中的常用方法包括 VideoWriter 类的构造方法、write() 方法和 release() 方法。其中,VideoWriter 类的构造方法用于创建 VideoWriter 类对象,其语法格式如下:
<VideoWriter object> = cv2.VideoWriter(filename, fourcc, fps, frameSize)
参数说明:
- VideoWriter object:VideoWriter 类对象。
- filename:保存视频时的路径(含有文件名)。
- fourcc:用4个字符表示的视频编码格式。
- fps:帧速率。
- frameSize:每一帧的大小。摄像头的分辨率。
在 OpenCV 中,使用 cv2.VideoWriter_fourcc() 来确定视频编码格式。下表列出了几个常用的视频编码格式。最好使用 XVID。MJPG 会生成大尺寸的视频。X264 会生成非常小的尺寸的视频。我这里就直接使用 XVID了!
fourcc的值 | 视频编码格式 | 文件扩展名 |
---|---|---|
cv2.VideoWriter_fourcc(‘I’, ‘4’, ‘2’, ‘0’) | 未压缩的YUV颜色编码格式,兼容性好,但文件较大 | .avi |
cv2.VideoWriter_fourcc(‘P’, ‘I’, ‘M’, ‘I’) | MPEG-1编码格式 | .avi |
cv2.VideoWriter_fourcc(‘X’, ‘V’, ‘I’, ‘D’) | MPEG-4编码格式,视频文件的大小为平均值 | .avi |
cv2.VideoWriter_fourcc(‘T’, ‘H’, ‘E’, ‘O’) | Ogg Vorbis编码格式,兼容性差 | .ogv |
cv2.VideoWriter_fourcc(‘F’, ‘L’, ‘V’, ‘I’) | Flash视频编码格式 | .flv |
cv2.VideoWriter_fourcc(‘F’, ‘L’, ‘V’, ‘I’) | .mp4 |
语法格式可以写为下面这两种方式:
cv2.VideoWriter_fourcc(*'MJPG')
cv2.VideoWriter_fourcc("M", "J", "P", "G")
为了保存一段视频,除需要使用 VideoWriter 类的构造方法外,还需要使用 VideoWriter 类提供的 write() 方法。write() 方法的作用是在创建好的 VideoWriter 类对象中写入读取到的帧,其语法格式如下:
cv2.VideoWriter.write(frame) # frame:读取到的帧。
关键代码如下:
# fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
# output = cv2.VideoWriter("output.avi", fourcc, 20, (640, 480))
fourcc = cv2.VideoWriter_fourcc(* 'XVID')
output = cv2.VideoWriter("output.avi", fourcc, 20, (640, 480))
output.write(frame)
当不需要使用 VideoWriter 类对象时,需要将其释放掉。为此, VideoWriter 类提供了 release() 方法,其语法格式如下:
cv2.VideoWriter.release()
# 例如,完成保存一段视频后,需要释放VideoWriter类对象output。关键代码如下:
output.release()
【案例11】保存一段摄像头视频。
import cv2
fourcc = cv2.VideoWriter_fourcc(*'XVID') # 确定视频被保存后的编码格式
output = cv2.VideoWriter("output.avi", fourcc, 20, (1280, 720)) # 创建VideoWriter类对象
# 创建窗口
cv2.namedWindow('video', cv2.WINDOW_AUTOSIZE)
capture = cv2.VideoCapture(0) # 打开笔记本内置摄像头
while capture.isOpened(): # 笔记本内置摄像头被打开后
retval, frame = capture.read() # 从摄像头中实时读取视频
if retval is True: # 读取到摄像头视频后
cv2.imshow("video", frame) # 在窗口中显示摄像头视频
output.write(frame) # 在VideoWriter类对象中写入读取到的帧
key = cv2.waitKey(1) & 0xFF # 等待用户按下键盘按键的时间为1ms
if key == ord('q'): # 如果按下q键
break
else:
break
capture.release() # 关闭笔记本内置摄像头
output.release() # 释放VideoWriter类对象
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口
【案例12】保存一段时长为10秒的摄像头视频。
import cv2
fps = 20 # 帧速率
fourcc = cv2.VideoWriter_fourcc(*"XVID") # 确定视频被保存后的编码格式
# 创建VideoWriter类对象
output = cv2.VideoWriter("ten_Seconds.avi", fourcc, fps, (1280, 720))
# 创建窗口
cv2.namedWindow("video")
capture = cv2.VideoCapture(0) # 打开笔记本内置摄像头
frame_Num = 10 * fps # 时长为10s的摄像头视频含有的帧数
# 笔记本内置摄像头被打开且时长为10s的摄像头视频含有的帧数大于0
while capture.isOpened() and frame_Num > 0:
retval, frame = capture.read() # 从摄像头中实时读取视频
if retval: # 读取到摄像头视频后
cv2.imshow("video", frame) # 在窗口中显示摄像头视频
output.write(frame) # 在VideoWriter类对象中写入读取到的帧
key = cv2.waitKey(1) # 等待用户按下键盘按键的时间为1ms
frame_Num -= 1 # 时长为10s的摄像头视频含有的帧数减少一帧
capture.release() # 关闭笔记本内置摄像头
output.release() # 释放VideoWriter类对象
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口
【案例13】保存视频文件。编写一个程序,首先读取PyCharm当前项目路径下 video 文件夹中名为 dance.mp4
的视频文件,然后将 公司宣传.avi
视频文件保存为PyCharm 当前项目路径下的 copy.avi
。代码如下:
import cv2
video = cv2.VideoCapture("./video/dance.mp4") # 打开视频文件
fps = video.get(cv2.CAP_PROP_FPS) # 获取视频文件的帧速率
# 获取视频文件的帧大小
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(video.get(以上是关于从0-1轻松入门 OpenCV4的主要内容,如果未能解决你的问题,请参考以下文章