上一篇:Day8:Python工程化 —— 模块、包
OpenCV(Open Source Computer Vision Library) 是一个开源的计算机视觉和机器学习软件库。由一系列 C++ 类和函数构成,用于图像处理、计算机视觉领域的算法实现。其有以下优势:
从本篇文章开始,我们将开始OpenCV-Python库的学习。
不推荐在(base)
环境中安装,而应该在一个创建好的虚拟环境进行安装,以防止在一个环境中安装混乱的各种包库,引发版本冲突。下方是通过清华源的镜像进行安装的。
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
可以通过在python代码中(需要在装有虚拟环境的解释器下)执行如下代码检测是否安装成功
import cv2 as cv
print(cv.__version__)
在使用OpenCV进行图像操作需要在Python模块中先导入cv2
import cv2 as cv # 下方都用cv这个别名进行方法调用
cv.imread(filename, flags)
其中参数
filename
是要读取的图片的路径,可以是绝对路径也可以是相对路径(如果是项目的话建议使用相对路径),参数flags
决定读取的方式,可以使用整形字面量,也可以使用cv2
中定义的常量,具体对应关系和作用如下:
常量 | 数值 | 作用说明 |
---|---|---|
cv2.IMREAD_COLOR (默认) |
1 | 以彩色图方式加载图像(默认值),忽略 alpha 通道。返回 BGR 格式图像。 |
cv2.IMREAD_GRAYSCALE |
0 | 以灰度图方式加载图像,返回二维数组(单通道)。 |
cv2.IMREAD_UNCHANGED |
-1 | 原样读取图像,保留 alpha 通道(如 PNG 的透明背景),返回 BGRA。 |
该函数返回的是所读取图像的Numpy数组(
ndarray
)表示形式,具体形式跟flags
有关,若读取失败则返回None
cv.imshow(winname, mat)
其中参数
winname
代表用于显示图像的窗体的名字,mat
传入的是要显示的图像的ndarray
形式。可以结合上面的imread()
使用,因为其返回值就是图像的ndarray
表示形式。也可以自己通过Numpy的操作自己创建符合图像
要保证图像能够长时间显示并实现交互,还需要进行等待(如果不等待,代码将不断向下执行,执行完毕后将自动关闭所有窗体):
cv.waitKey(delay)
该函数将在接收到键盘输入后返回该按键字符的ASCII码值,
delay
为等待时间,单位是毫秒,当delay
为0
(或者小于0)时,将进行无线等待,直到键盘输入值。
虽然在代码执行完毕后会自动关闭所有窗体,但是还是应该显示地关闭窗体,增强代码的可控性和健壮性:
cv.destroyAllWindows()
当然,也可以通过窗体名指定关闭某个窗体:
cv2.destroyWindow(winname)
需要用到Numpy数组的 切片 操作(不同维度分别切片,用逗号隔开)
示例:
# 读取一张图像
img1 = cv.imread('img1.jpg') # 默认读取为彩色图
part = cv[200:400, 300:400, :] # 等效于part = cv[200:400, 300:400]
imread
读取的默认是三通道彩色图像(BGR
),其数组形状为(height, width, channel)
,要进行裁剪,则要在数组的 行(也就是图像的 高 )和 列(也就是图像的 宽 )上进行切片,通道 这一维不变。上述示例所裁剪的部分是第200行 ~ 399行,第300列 ~ 399列部分的图像
dst = cv2.resize(src, dsize)
src
为原图像(ndarray
形式),dsize是一个序列(优先选择tuple
),顺序是(width, height)
,注意与’ndarray‘中的(height, width, channel)
的顺序区分。该函数不会对原图像进行修改,而是返回一个新的图像(ndarray
形式)
在一系列的图像处理操作后,我们可能要将得到的结果(往往是ndarray
形式)保存为计算机中图片的形式,此时就要进行图像的 保存
cv.imwrite(filename, img)
其中
filename
是要保存图片到那个路径,写路径时还要把该图片文件的后缀也写上(.jpg
,.png
,.bmp
等),img
则是要保存的图像(ndarray
形式)
cv.line(img, pt1, pt2, color, thickness, lineType)
cv.rectangle(img, left_upper, right_lower, color, thickness, lineType)
cv.circle(img, center, radius, color, thickness, lineType)
img
表示作为背景的图像(画板),pt1
,pt2
代表绘制直线时的两个端点。left_upper
,right_lower
代表绘制矩形时的左上角和右下角坐标(坐标系的原点在左上角),radius
代表绘制圆形时的半径,color
代表绘制所用颜色,其形式为一个序列类型(通常是tuple
),thickness
代表绘制线条的粗细,为整数,如果-1
则表示将内部全部填充(也就是实心),但是直线的thickness
必须大于0
。lineType表示绘制所用线条的类型。
常见的lineType取值如下:
常量 | 数值 | 说明 |
---|---|---|
cv2.LINE_8 |
8 | 8-connected line(默认),标准抗锯齿效果,速度快 |
cv2.LINE_4 |
4 | 4-connected line,线条连接更紧密,较少使用 |
cv2.LINE_AA 或 cv2.CV_AA |
16 | Anti-aliased line,抗锯齿线条,线条边缘更平滑,绘制较慢 |
cap = cv.VideoCapture(filename)
filename
是要进行捕获的视频的路径,当filename=0
时,将从默认的摄像头捕获视频流
# 无限循环
While True:
# 读取视频流的帧
ret, frame = cap.read() # ret 是一个布尔值,表示该帧是否读取成功,可以用作视频播放结束自动退出循环
# 视频播放完后,ret值为False,跳出循环
if not ret:
break
# 读取成功后显示该帧
cv.imshow('frame', frame)
# 通过键盘交互手动退出视频帧的循环获取(cv.waitKey()返回一个32为整数, 与0xFF相与是为了取其低8位(得到ASCII码部分),以保证跨平台安全,即可判断其是否是'q')
if cv.waitKey(20) & 0xFF == ord('q'):
break
cap.release() # cap是之前所创建的VideoCapture实例
cv.destroyAllWindows()
经过本章的学习,我们对OpenCV有了初步的了解,并且对计算机中的图像有了一定的认识,在此基础上,还认识到OpenCV-Python中的图像的本质(Numpy数组),还能够通过OpenCV-Python库中的一些函数对图像进行一些简单的操作(如读取、显示、保存、裁剪、调整尺寸、绘制)、捕获视频。