一、什么是OpenCV
1、绪论
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它包含了众多关于图像处理和计算机视觉的通用算法,这些算法可以用于解决各种实际问题,比如人脸识别、物体检测、图像分割、视频分析等。OpenCV 提供了 C++、Python、Java 和 MATLAB 等多种语言的接口,其中 Python 接口由于其简洁性和易用性而特别受欢迎。
2、关键特性
①丰富的功能:
OpenCV 提供了大量的图像处理函数,包括滤波、边缘检测、形态学操作、图像变换、特征检测与匹配、相机标定与三维重建等。
②高性能:
OpenCV 是用 C++ 编写的,并进行了高度优化,因此在处理大规模图像数据时具有很高的性能。Python 接口通过调用底层的 C++ 实现来保持高效性。
③跨平台:
OpenCV 可以在多种操作系统上运行,包括 Windows、Linux、macOS 和 Android 等。
④易于使用:
OpenCV 的 Python 接口设计直观,易于学习和使用。同时,OpenCV 还提供了详细的文档和丰富的教程资源。
⑤社区支持:
OpenCV 拥有一个活跃的社区,用户可以在论坛、GitHub 和 Stack Overflow 等平台上寻求帮助和分享经验。
3、用途
①图像处理:
OpenCV 可以用于图像的滤波、去噪、增强、变换等操作,以改善图像的质量或提取有用的信息。
②物体检测与识别:
利用 OpenCV 提供的特征检测器(如 SIFT、SURF、ORB 等)和机器学习算法(如 SVM、随机森林等),可以实现物体的检测和识别。
③视频分析:
OpenCV 支持视频捕捉、处理和分析,可以用于视频跟踪、运动检测、背景减除等任务。
④人脸识别:
OpenCV 提供了多种人脸识别算法,如 Eigenfaces、Fisherfaces、LBPH(Local Binary Patterns Histograms)等,可以用于人脸检测、识别和验证。
⑤三维重建:
通过相机标定和立体视觉技术,OpenCV 可以实现三维场景的重建和测量。
⑥增强现实(AR):
OpenCV 可以与计算机图形学库结合使用,实现增强现实应用,如在真实场景中叠加虚拟对象。
4、常用函数
①imshow()
@_typing.overload
def imshow(winname: str, mat: cv2.typing.MatLike) -> None: ...
@_typing.overload
def imshow(winname: str, mat: cv2.cuda.GpuMat) -> None: ...
@_typing.overload
def imshow(winname: str, mat: UMat) -> None: ...
功能:一个窗口中显示由 cv2.imread() 或其他图像处理函数生成的图像
参数
- winname: 窗口的名字。这是一个字符串,用于标识显示图像的窗口。如果指定的窗口名不存在,OpenCV 会自动创建一个新窗口。如果窗口名已经存在,图像会在已有的窗口中显示。
- mat: 要显示的图像。这是一个包含图像数据的 NumPy 数组,通常是由 cv2.imread() 或其他图像处理函数生成的。
示例:
img = cv2.imread("flower.png")
cv2.imshow("Image Window", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
②rectangle()
@_typing.overload
def rectangle(img: cv2.typing.MatLike, pt1: cv2.typing.Point, pt2: cv2.typing.Point, color: cv2.typing.Scalar, thickness: int = ..., lineType: int = ..., shift: int = ...) -> cv2.typing.MatLike: ...
@_typing.overload
def rectangle(img: UMat, pt1: cv2.typing.Point, pt2: cv2.typing.Point, color: cv2.typing.Scalar, thickness: int = ..., lineType: int = ..., shift: int = ...) -> UMat: ...
@_typing.overload
def rectangle(img: cv2.typing.MatLike, rec: cv2.typing.Rect, color: cv2.typing.Scalar, thickness: int = ..., lineType: int = ..., shift: int = ...) -> cv2.typing.MatLike: ...
@_typing.overload
def rectangle(img: UMat, rec: cv2.typing.Rect, color: cv2.typing.Scalar, thickness: int = ..., lineType: int = ..., shift: int = ...) -> UMat: ...
功能:用于在图像上绘制矩形的函数
参数:
- img: 这是要绘制矩形的图像,它是一个包含图像数据的 NumPy 数组。
- pt1: 矩形的一个顶点坐标,通常是一个元组 (x, y),表示矩形左上角的坐标。
- pt2: 矩形的对角顶点坐标,也是一个元组 (x, y),表示矩形右下角的坐标。
- color: 矩形的颜色,通常是一个 BGR(蓝、绿、红)颜色值的三元组 (b, g, r)。注意,OpenCV 使用 BGR 而不是 RGB 颜色空间。
- thickness: 矩形边框的粗细。如果设置为 -1,则表示填充整个矩形区域。
- lineType: 线条的类型,例如 cv2.LINE_8(8-连通线),cv2.LINE_4(4-连通线),或 cv2.FILLED(填充矩形)。默认情况下,它是 cv2.LINE_8。
- shift: 点坐标的小数位数。默认值是 0。
示例:
img = cv2.imread("flower.png")
cv2.rectangle(img, (50, 50), (200, 200), (0, 255, 0), 2)
cv2.imshow("Rectangle", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
③waitKey()
def waitKey(delay: int = ...) -> int: ...
功能:用于等待用户按键事件
参数:
- delay: 等待的时间(以毫秒为单位)。如果设置为 0,则表示无限期等待,直到用户按下一个键。如果设置为一个正数,比如 1000,则表示等待 1000 毫秒(即 1 秒),如果在这段时间内用户没有按键,则继续执行后续代码。
函数返回值:
- cv2.waitKey() 返回一个整数,表示用户按下的键的 ASCII 码。如果用户在指定的等待时间内没有按下任何键,则返回 -1。
示例:
img = cv2.imread("flower.png")
cv2.imshow("Image", img)# 等待按键
key = cv2.waitKey(0)
if key == ord('q'): # 按 'q' 键退出print("Quit")
cv2.destroyAllWindows()
二、灰度化
1、绪论
灰度图:单通道图,每个像素点只存一个像素值,图像整体表现为灰色,从0-255表现为从黑到白的过程。
2、灰度化的三种方法
①加权均值法:
对于彩色图像的每个像素【每个像素包含 RGB三通道】,它会按照一定的权重去乘以每个通道的像素值,并将其相加,得到最后的值就是灰度图像中对应位置的像素值,权重的比例为: R乘以0.299,G乘以0.587,B乘以0.114。
例:
import numpy as np
import matplotlib.pyplot as pltimg = plt.imread("./flower.png")img_gray = np.zeros_like(img)# 使用加权均值法进行灰度化
for i in range(img_gray.shape[0]):for j in range(img_gray.shape[1]):img_gray[i, j, :] = (img[i, j, 0]*0.299 + img[i, j, 1]*0.587 + img[i, j, 2]*0.114)plt.subplot(121)
plt.imshow(img)plt.subplot(122)
plt.imshow(img_gray)plt.tight_layout()
plt.show()
②平均值法:
对于彩色图像的每个像素,它会将R、G、B三个通道的像素值全部加起来,然后再除以三,得到的平均值就是灰度图像中对应位置的像素值。
例:
import numpy as np
import matplotlib.pyplot as pltimg = plt.imread("./flower.png")img_gray = np.zeros_like(img)# 使用平均值法进行灰度化
for i in range(img_gray.shape[0]):for j in range(img_gray.shape[1]):img_gray[i, j, :] = (img[i, j, 0] + img[i, j, 1] + img[i, j, 2]) / 3plt.subplot(121)
plt.imshow(img)plt.subplot(122)
plt.imshow(img_gray)plt.tight_layout()
plt.show()
③最大值法:
对于彩色图像的每个像素,它会从R、G、B三个通道的值中选出最大的一个,并将其作为灰度图像中对应位置的像素值。
例:
import numpy as np
import matplotlib.pyplot as pltimg = plt.imread("./flower.png")img_gray = np.zeros_like(img)# 使用最大值法进行灰度化
for i in range(img_gray.shape[0]):for j in range(img_gray.shape[1]):img_gray[i, j, :] = max(img[i, j, 0] , img[i, j, 1] , img[i, j, 2])plt.subplot(121)
plt.imshow(img)plt.subplot(122)
plt.imshow(img_gray)plt.tight_layout()
plt.show()
3、常用函数
①imread()
@_typing.overload
def imread(filename: str, flags: int = ...) -> cv2.typing.MatLike: ...
@_typing.overload
def imread(filename: str, dst: cv2.typing.MatLike | None = ..., flags: int = ...) -> cv2.typing.MatLike: ...
@_typing.overload
def imread(filename: str, dst: UMat | None = ..., flags: int = ...) -> UMat: ...
功能:用于读取图像文件的一个函数
参数:
- filePath: 要读取的图像文件的路径。
- flags: 读取图像的方式(可选参数)。
常用值:
- cv2.IMREAD_COLOR: 读取彩色图像。图像的透明度会被忽略(默认设置)。
- cv2.IMREAD_GRAYSCALE: 以灰度模式读取图像。返回的是一个单通道图像。
- cv2.IMREAD_UNCHANGED: 包括 alpha 通道的方式读取图像。这对于读取 PNG 或 JPEG 图像中的透明度信息很有用。
例:
import cv2# 读取彩色图像
img = cv2.imread('./flower.png', cv2.IMREAD_COLOR)# 检查是否加载成功
if img is None:print("图像加载失败!")
else:print(f"图像形状: {img.shape}") # 输出图像尺寸cv2.imshow('Image', img) # 显示图像cv2.waitKey(0)cv2.destroyAllWindows()
②cvtColor()
@_typing.overload
def cvtColor(src: cv2.typing.MatLike, code: int, dst: cv2.typing.MatLike | None = ..., dstCn: int = ...) -> cv2.typing.MatLike: ...
@_typing.overload
def cvtColor(src: UMat, code: int, dst: UMat | None = ..., dstCn: int = ...) -> UMat: ...
功能:用于转换图像从一个颜色空间到另一个颜色空间
参数:
- src: 输入图像,这是一个包含图像数据的 NumPy 数组。
- code: 用于指定颜色空间转换的代码,它是一个整数标识符,表示源颜色空间和目标颜色空间之间的转换。OpenCV 提供了多种转换代码,如 cv2.COLOR_BGR2GRAY(从 BGR 转换到灰度图),cv2.COLOR_RGB2HSV(从 RGB 转换到 HSV),等等。
- dst: 输出图像,与输入图像具有相同的大小和深度。这是一个可选参数,如果不提供,函数会创建一个新的图像来存储转换结果。
- flags: 一个可选的标志,用于指定颜色转换的一些特定选项。在大多数情况下,这个参数可以省略,因为它有默认值。
函数返回值:
- dst: 转换后的图像,这是一个包含新颜色空间图像数据的 NumPy 数组。
例:
import cv2# 读取彩色图像
img = cv2.imread('./flower.png')# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 转换为 HSV 色彩空间
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)cv2.imshow('Gray Image', gray) # 显示灰度图
cv2.imshow('HSV Image', hsv) # 显示 HSV 图
cv2.waitKey(0)
cv2.destroyAllWindows()
三、二值化函数 cv2.threshold()
二值化是图像处理中的常见操作,用于将图像转化为只有两种像素值(通常是 0 和 255)的图像,常用于边缘检测、形状检测等。
1、功能
cv2.threshold() 用于将灰度图像的像素值根据设定的阈值进行二值化处理:
- 如果像素值高于阈值,则设置为最大值。
- 如果像素值低于阈值,则设置为 0。
2、参数
cv2.threshold(src, thresh, maxval, type)
- src:输入图像,必须是单通道图像(灰度图像)。
- thresh:阈值,像素值高于该阈值的部分会被设置为 maxval。
- maxval:最大值(通常为 255),像素值满足条件时设置为该值。
- type:二值化方法(标志位),常见取值:
①cv2.THRESH_BINARY:大于阈值的像素设置为 maxval,其余设置为 0。
②cv2.THRESH_BINARY_INV:小于等于阈值的像素设置为 maxval,其余设置为 0。
③cv2.THRESH_TRUNC:大于阈值的像素设置为阈值,其余保持不变。
④cv2.THRESH_TOZERO:小于等于阈值的像素设置为 0,其余保持不变。
⑤cv2.THRESH_TOZERO_INV:大于阈值的像素设置为 0,其余保持不变。
3、返回值
函数返回两个值:
- retval:实际使用的阈值(通常与 thresh 参数相同)。
- dst:二值化后的图像。
4、应用
二值化可以用于:
- 去除图像中的背景信息,只保留前景。
- 提取感兴趣的区域或形状。
- 准备数据用于轮廓检测、OCR 等任务。
5、示例代码:
import cv2# 读取原始图像
img = cv2.imread('sadp.jpg')# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 应用二值化操作
thresh = 127 # 阈值
maxval = 255 # 最大值# 各种二值化类型
_, binary = cv2.threshold(gray, thresh, maxval, cv2.THRESH_BINARY)
_, binary_inv = cv2.threshold(gray, thresh, maxval, cv2.THRESH_BINARY_INV)
_, trunc = cv2.threshold(gray, thresh, maxval, cv2.THRESH_TRUNC)
_, tozero = cv2.threshold(gray, thresh, maxval, cv2.THRESH_TOZERO)
_, tozero_inv = cv2.threshold(gray, thresh, maxval, cv2.THRESH_TOZERO_INV)# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Gray', gray)
cv2.imshow('Binary', binary)
cv2.imshow('Binary Inv', binary_inv)
cv2.imshow('Trunc', trunc)
cv2.imshow('Tozero', tozero)
cv2.imshow('Tozero Inv', tozero_inv)# 等待按键退出
cv2.waitKey(0)
cv2.destroyAllWindows()
四、自适应二值化函数
1、功能
cv2.adaptiveThreshold() 根据图像的局部特性动态计算阈值,并将图像二值化。
- 适用于光照不均或对比度变化较大的图像。
- 每个像素的阈值是根据它所在的邻域计算得出,而不是全局固定的阈值。
2、参数
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
①src:
输入图像,必须是灰度图像。
②maxValue:
最大值(通常为 255),用于将满足条件的像素设置为此值。
③adaptiveMethod:
自适应方法,用于计算局部阈值的方式:
- cv2.ADAPTIVE_THRESH_MEAN_C:像素邻域的平均值减去常量 C。
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C:像素邻域的加权平均值减去常量 C,权重是高斯窗口。
④thresholdType:
二值化类型,通常为 cv2.THRESH_BINARY 或 cv2.THRESH_BINARY_INV。
⑤blockSize:
邻域大小,用于计算阈值的区域,必须是奇数(如 3, 5, 7)。
⑥C:
常量,阈值减去此值后再比较。用于微调结果,正值会降低阈值,负值会提高阈值。
3、返回值
返回二值化后的图像,类型与输入图像相同。
4、应用
- 适用于处理光照不均匀的图像。
- 常用于图像中的文字检测和分割(OCR 前处理)。
- 对背景复杂的图像进行二值化。
五、腐蚀函数
1、功能
cv2.erode() 实现图像的腐蚀操作:
- 腐蚀的过程是使用一个结构元素在图像上滑动,对于前景像素:
①如果结构元素内的所有像素都为前景像素,则保持当前像素不变;
②如果有任何一个像素不是前景像素,则将该像素腐蚀为背景像素。
- 效果类似于“侵蚀”,使前景物体变小。
2、参数
cv2.erode(src, kernel, dst=None, anchor=None, iterations=1, borderType=None, borderValue=None)
①src:
输入图像,可以是二值图像或灰度图像。
②kernel:
- 腐蚀操作的结构元素(即卷积核)。
- 使用 cv2.getStructuringElement() 生成,或直接传入自定义的 NumPy 数组。
③dst:
输出图像,与输入图像的大小和类型相同(可选)。
④anchor:
锚点位置,默认为核的中心点。
⑤iterations:
腐蚀操作的次数,默认为 1。
⑥borderType:
边界模式,用于指定图像边界的填充方式(默认为 cv2.BORDER_CONSTANT)。
⑦borderValue:
当 borderType=BORDER_CONSTANT 时使用的边界填充值。
3、返回值
返回腐蚀处理后的图像,与输入图像大小相同。
4、应用
腐蚀操作的典型用途包括:
①去除噪点:
清理图像中的小噪点。
②分割物体:
分离连接在一起的物体。
③处理形状:
改变图像中的形状(如减少边缘的不规则性)。
六、膨胀函数
1、功能
cv2.dilate() 实现图像的膨胀操作:
①膨胀的效果:
将图像中的前景区域“扩展”。
②原理:
使用一个结构元素(kernel)在图像上滑动,卷积核覆盖的区域内只要有一个前景像素,则中心像素被设置为前景像素。
2、参数
cv2.dilate(src, kernel, dst=None, anchor=None, iterations=1, borderType=None, borderValue=None)
①src:
输入图像,可以是二值图像或灰度图像。
②kernel:
- 结构元素(卷积核),用于决定膨胀的形状和范围。
- 使用 cv2.getStructuringElement() 创建,也可以直接传入 NumPy 数组。
③dst:
输出图像,与输入图像大小和类型相同(可选)。
④anchor:
锚点位置,决定核的基准点,默认是核的中心。
⑤iterations:
膨胀操作的次数,默认为 1。
⑥borderType:
边界模式,指定图像边界的填充方式(默认为 cv2.BORDER_CONSTANT)。
⑦borderValue:
当 borderType=BORDER_CONSTANT 时使用的边界填充值。
3、返回值
返回膨胀处理后的图像,与输入图像大小相同。
4、应用
膨胀操作的常见用途包括:
①填补空洞:
将图像中的前景区域变大,填补小孔或断裂部分。
②连接断裂部分:
连接原本不连续的前景区域。
③增强目标:
扩大前景区域的尺寸,使目标更加显著。
④形态学运算:
与腐蚀结合,用于形态学的开运算和闭运算。
七、仿射变换函数
1、功能
仿射变换是一种二维图像几何变换,包括平移、旋转、缩放、剪切等操作。它保持直线和比例不变,即图像中所有的直线仍然保持直线,且平行线依然平行。
OpenCV 的 cv2.warpAffine() 函数实现了仿射变换,基于输入的 2x3 变换矩阵,将输入图像映射到输出图像。
2、参数
cv2.warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
①src:
输入图像。
②M:
仿射变换矩阵,大小为 2x3,由用户计算或通过 OpenCV 函数生成。
③dsize:
输出图像的尺寸(宽度,高度)。
④dst:
输出图像,与输入图像类型相同(可选)。
⑤flags:
插值方法:
- cv2.INTER_NEAREST:最近邻插值。
- cv2.INTER_LINEAR(默认):双线性插值。
- cv2.INTER_CUBIC:三次插值,效果更好但速度较慢。
⑥borderMode:
外部像素填充方式:
- cv2.BORDER_CONSTANT(默认):填充为常量。
- cv2.BORDER_REFLECT:边界镜像反射。
- cv2.BORDER_WRAP:边界循环。
⑦borderValue:
当 borderMode=cv2.BORDER_CONSTANT 时使用的填充值。
3、返回值
返回仿射变换后的图像。
4、应用
仿射变换在图像处理中的典型应用包括:
①旋转:
改变图像的方向。
②平移:
将图像移动到指定位置。
③缩放:
改变图像的尺寸比例。
④剪切:
改变图像的形状,使矩形变成平行四边形。
⑤图像增强:
调整图像的视角。
八、透视变换函数
1、功能
透视变换是一种几何变换,可以将二维平面上的图像映射到另一个平面,并且能够改变图像的透视关系。它与仿射变换不同,可以处理非平行的直线,使矩形映射为任意四边形或反之。
在 OpenCV 中,透视变换通过函数 cv2.warpPerspective() 实现。
2、参数
cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
①src:
输入图像。
②M:
透视变换矩阵,大小为 3x3,可以使用 cv2.getPerspectiveTransform() 或 cv2.findHomography() 生成。
③dsize:
输出图像的尺寸(宽度,高度)。
④dst:
输出图像,与输入图像类型相同(可选)。
⑤flags:
插值方法,常用值:
- cv2.INTER_NEAREST:最近邻插值。
- cv2.INTER_LINEAR(默认):双线性插值。
- cv2.INTER_CUBIC:三次插值,效果更好但速度较慢。
⑥borderMode:
边界填充方式:
- cv2.BORDER_CONSTANT(默认):填充为常量。
- cv2.BORDER_REFLECT:边界镜像反射。
- cv2.BORDER_WRAP:边界循环。
⑦borderValue:
当 borderMode=cv2.BORDER_CONSTANT 时使用的边界填充值。
3、返回值
返回透视变换后的图像。
4、应用
透视变换的典型应用包括:
①图像矫正:
例如,将拍摄的书籍、文件矫正为直视视角。
②提取局部区域:
从图像中提取四边形区域。
③视角调整:
改变图像的透视效果,模拟从不同视角观看图像。
④拼接图像:
在拼接图像中,校正视角差异。