一,简介:
OpenCV是一个开源的计算机视觉和机器学习软件库,它提供了大量用于处理图像和视频的函数。OpenCV支持多种编程语言,包括C++、Python、Java等,广泛应用于学术研究和商业产品中。
同时在深度学习时代,学习OpenCV的重要性不言而喻,它不仅能够通过图像预处理确保输入数据的质量,优化模型的训练效率和性能,还能通过数据增强技术提升模型的泛化能力,使其更好地适应多变的环境和条件。此外,掌握OpenCV为研究人员和开发者提供了实验不同数据处理方法的灵活性,促进了模型架构和训练策略的创新,从而推动深度学习领域的持续发展。因此,学习OpenCV对于构建高效、鲁棒且适用于真实场景的深度学习模型至关重要。
在这个系列文章中,我们将深入探索OpenCV这一强大的计算机视觉库,详细介绍其常用函数。从基本的图像读取与显示,到高级的图像处理技巧,我们将一步步带领大家掌握OpenCV的核心功能,助您轻松应对各种计算机视觉任务。
二,图像的基础操作:
2.1,图像的读取显示与保存
2.1.1图像的读取cv2.imread:
cv2.imread(filename,flags) 是 OpenCV 库中的一个函数,用于从文件系统中加载图像。以下是该函数的详细讲解:
参数:
● filename:这是一个字符串,代表图像文件的路径,包括文件名和扩展名(如 ‘.jpg’, ‘.png’, ‘.bmp’ 等)。
● flags:这是一个可选参数,用于指定图像的读取模式。它可以有以下几种值:
○ cv2.IMREAD_COLOR:这是默认值,它读取图像为彩色图像。如果图像文件的格式是灰度图像,它也会被转换为彩色图像(即每个像素由三个通道组成,分别是蓝色、绿色和红色)。
○ cv2.IMREAD_GRAYSCALE:这个标志将图像以灰度模式读取,即每个像素只有一个强度值,没有颜色信息。
○ cv2.IMREAD_UNCHANGED:这个标志以图像的原始位深度和通道数读取图像,包括可能的alpha通道(透明度信息)。
返回值:
● 如果图像读取成功,函数返回一个 NumPy 数组,代表图像的像素数据。
● 如果图像文件不存在或无法读取,函数将返回 None。
注意事项:
● 如果文件路径错误或文件不存在,cv2.imread() 不会抛出异常,而是返回 None。因此,在使用返回的图像数据之前,应该检查是否为 None。
● 读取的图像数据是以 BGR 格式存储的,而不是通常的 RGB 格式。
● 图像数据是一个三维数组,其中第一维是图像的高度,第二维是图像的宽度,第三维是颜色通道(灰度图像则只有两个维度)。
2.1.2图像的显示cv2.imshow与等待cv2.waitKey:
cv2.imshow() 和 cv2.waitKey() 是 OpenCV 库中用于显示图像和等待键盘事件的两个重要函数。以下是这两个函数的详细介绍:
cv2.imshow()
功能: cv2.imshow(winname,mat) 函数用于在一个窗口中显示图像。它是 OpenCV 图形用户界面功能的一部分,用于可视化图像处理的结果。
参数:
● winname:这是一个字符串,代表窗口的名称。每个显示的窗口都应该有一个唯一的名称。
● mat:这是一个图像矩阵,通常是使用 cv2.imread() 读取的图像,或者是经过某种图像处理后的结果。
注意事项:
● 在调用 cv2.imshow() 之前,确保已经有一个 OpenCV 窗口环境。
● 如果窗口名称已经存在,该函数将在该窗口中显示新的图像,覆盖之前的图像。
cv2.waitKey():
功能: cv2.waitKey(delay) 函数用于等待一个键盘事件发生。它通常与 cv2.imshow() 一起使用,以便在显示图像的窗口中等待用户的按键操作。
参数:
● delay:这是一个整数值,表示等待键盘事件的时间(毫秒)。如果 delay 是正数,函数将等待指定的毫秒数;如果 delay 是 0,它会无限期等待直到有按键事件;如果 delay 是负数,函数不会等待,立即返回。
返回值:
● retval:返回按键的 ASCII 码值,如果没有按键事件发生,则返回 -1。
注意事项:
● 如果 cv2.waitKey() 在 cv2.imshow() 之后没有被调用,显示的图像窗口可能会立即关闭,因为程序会继续执行而不会暂停。
● 为了使窗口保持打开状态,通常会在 cv2.waitKey() 后面使用一个特定的等待时间,例如 cv2.waitKey(0)。
● 如果要检测特定的按键事件,可以通过返回值与按键的 ASCII 码进行比较。
2.1.3图像保存cv2.imwrite:
retval = cv2.imwrite(filename, img) 是 OpenCV 库中的一个函数,用于将图像保存到文件系统中。以下是该函数的详细介绍:
功能: 该函数将一个图像数组保存到指定的文件路径。它可以支持多种图像格式,如 JPEG、PNG、BMP 等。
参数:
● filename:这是一个字符串,指定了要保存图像的文件路径,包括文件名和扩展名。文件扩展名决定了保存的图像格式。
● img:这是一个图像数组,通常是使用 cv2.imread() 读取的图像或者经过 OpenCV 处理后的图像数组。
返回值:
● retval:如果图像保存成功,则返回 True;如果保存失败,则返回 False。
注意事项:
● 保存图像时,确保提供的文件扩展名与图像格式相匹配。如果不匹配,OpenCV 可能无法正确保存图像。
● 如果指定的文件路径不存在,OpenCV 不会创建目录,因此需要确保目录已经存在,或者使用其他方法创建目录。
2.2,图像属性获取:
在OpenCV中,图像属性获取涉及对图像数组的基本维度和类型信息的查询,这些属性对于图像处理和理解非常重要。以下是三个主要的图像属性及其简述:
- 图像尺寸(Shape):
○ 描述:图像的尺寸属性返回一个元组,通常包含三个整数,分别代表图像的高度(行数)、宽度(列数)和颜色通道数(如果图像是彩色的)。
○ 获取方式:使用 img.shape,其中 img 是图像数组。
- 图像大小(Size):
○ 描述:图像的大小属性返回一个整数,表示图像中的总像素数。它等于图像高度乘以宽度乘以通道数。
○ 获取方式:使用 img.size。
- 图像数据类型(Data Type):
○ 描述:图像的数据类型属性返回图像数组中像素的数据类型,通常是 uint8(无符号8位整数,值范围0-255),但在某些情况下也可能是其他类型,如 float32 或 int16。
○ 获取方式:使用 img.dtype
例子:
import cv2
# 读取图像
img = cv2.imread('path_to_image.jpg')
# 检查图像是否成功读取
if img is None:
print("Error: Image could not be read. Please check the file path.")
else:
# 获取图像的尺寸(高度、宽度、通道数)
height, width, channels = img.shape
print(f"Image dimensions: Height = {height}, Width = {width}, Channels = {channels}")
# 获取图像的总像素数
total_pixels = img.size
print(f"Total number of pixels in the image: {total_pixels}")
# 获取图像的数据类型
img_dtype = img.dtype
print(f"Image data type: {img_dtype}")
2.3,图像裁剪cv2.selectROI:
cv2.selectROI(windowName, img, showCrosshair, fromCenter) 是 OpenCV 库中用于手动选择图像中感兴趣区域(Region of Interest, ROI)的函数。这个函数提供了一个简单的用户界面,允许用户通过拖动鼠标来选择一个矩形区域,该区域随后可以用于进一步的处理,如图像分割、目标跟踪或特征提取。函数介绍:
参数:
● windowName:这是一个字符串,代表显示图像的窗口名称。如果窗口名称已经存在,ROI 选择框将在这个窗口中进行;如果窗口不存在,函数会创建一个新的窗口。
● img:这是要从中选择 ROI 的图像,通常是一个二维或三维的 NumPy 数组。
● showCrosshair:这是一个布尔值,如果设置为 True(默认值),在选择 ROI 时会显示十字准星。如果设置为 False,则不显示。
● fromCenter:这是一个布尔值,如果设置为 True,用户可以通过拖动从中心开始定义矩形;如果设置为 False(默认值),则从左上角开始定义。
返回值:
● roi:返回一个元组,包含四个整数,分别代表 ROI 矩形的 x 坐标、y 坐标、宽度(width)和高度(height)。
示例:
roi = cv2.selectROI(‘Image’, img, fromCenter=False, showCrosshair=True)
注意事项:
● 在调用 cv2.selectROI() 之前,必须确保图像已经通过 cv2.imshow() 显示出来,否则ROI选择框将不会出现。
● 用户在选择 ROI 后需要点击鼠标左键并拖动来定义矩形,然后释放鼠标左键来确认选择。
● 一旦 ROI 被选择,用户可以通过按任意键来退出 ROI 选择模式,此时 cv2.selectROI() 函数会返回 ROI 的坐标和尺寸。
2.4,图像通道的拆分cv2.split:
mv = cv2.split(msrc) 是 OpenCV 库中的一个函数,用于将多通道图像分割成单独的颜色通道。具体来说,它可以将一个三通道的彩色图像(通常是 BGR 格式)分解为三个单独的灰度图像,分别代表蓝色、绿色和红色通道。
简述: cv2.split() 接受一个多通道图像数组作为输入,并返回一个包含各个单独通道图像的列表。每个通道都是一个二维数组,表示该颜色通道的灰度值。
参数:
● msrc:输入的多通道图像数组。
返回值:
● mv:一个包含多个单通道图像数组的列表,列表中的每个元素对应输入图像的一个通道。
注意事项:
● cv2.split() 在处理大型图像时可能会比较慢,因为它涉及到数据的多次复制。在某些情况下,可以使用 NumPy 的索引功能来更高效地访问特定通道。
● 使用 cv2.split() 后,需要对每个单独的通道进行操作,然后再使用 cv2.merge() 将它们重新组合成多通道图像。
示例:拆分bgr图像
b, g, r = cv2.split(img)
2.5,图像通道的合并cv2.merge:
dst = cv2.merge(mv) 是 OpenCV 库中的一个函数,用于将多个单通道图像合并成一个多通道图像。这个函数通常与 cv2.split() 函数配合使用,在需要对图像的各个颜色通道分别进行处理后再重新组合时非常有用。
简述: cv2.merge() 接受一个包含多个单通道图像数组的列表或元组作为输入,并将它们合并成一个多通道图像数组。
参数:
● mv:一个列表或元组,其中包含两个或更多个单通道图像数组。所有图像数组的尺寸必须相同。
返回值:
● dst:返回一个多通道图像数组,其通道数与输入的单通道图像数量相同。
注意事项:
● 输入的单通道图像数组必须具有相同的尺寸和数据类型。
● 如果合并的是彩色图像的通道,通常需要按照正确的顺序传递通道(例如,对于 BGR 格式的图像,应按照 [B, G, R] 的顺序传递)。
示例:
merged_img = cv2.merge([b, g, r])
三,图像的数值运算:
3.1,图像的加法运算cv2.add:
cv2.add() 是 OpenCV 库中的一个函数,用于对两个图像进行逐元素的加法运算。这个函数可以应用于灰度图像或彩色图像,并且通常用于图像处理中的亮度调整或图像融合。
result = cv2.add(src1, src2) 接受两个图像数组作为输入,并将它们对应的像素值相加,生成一个新的图像数组作为输出。如果两个输入图像的尺寸和数据类型相同,它们将被逐像素相加。如果输入图像的数据类型不同,它们会先被转换成相同的数据类型,然后再进行加法运算。
参数:
● src1:第一个输入图像数组,可以是灰度图像或彩色图像。
● src2:第二个输入图像数组,尺寸和数据类型必须与 src1 相同。
返回值:
● result:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是输入图像对应像素值之和。
注意事项:
● 当两个像素值相加的结果超过数据类型的最大值时,会发生饱和,即结果会被限制在数据类型的最大值。
● 对于彩色图像,cv2.add() 会在每个颜色通道上独立进行加法运算。
3.2,图像的加权加法cv2.addWeighted:
cv2.addWeighted() 是 OpenCV 库中的一个函数,用于对两个图像进行加权和运算。这个函数在图像处理中非常有用,尤其是在图像融合、创建图像叠加效果或进行亮度调整时。
功能: dst = cv2.addWeighted(src1, alpha, src2, beta, gamma) 通过为每个图像分配不同的权重,将两个图像的对应像素值相加。权重的概念允许用户控制每个图像对最终结果的贡献程度。
参数:
● src1:第一个输入图像数组。
● alpha:第一个图像的权重,它决定了 src1 在最终结果中的重要性。
● src2:第二个输入图像数组,尺寸和数据类型必须与 src1 相同。
● beta:第二个图像的权重,它决定了 src2 在最终结果中的重要性。
● gamma:一个常数,它将被加到加权求和的结果上,通常用于调整整体亮度。
返回值:
● dst:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是输入图像对应像素值的加权和。
计算公式:dst = src1 * alpha + src2 * beta + gamma
注意事项:
● 输入图像 src1 和 src2 必须具有相同的尺寸和数据类型。
● 权重 alpha 和 beta 应该在0到1之间,但也可以超过这个范围,取决于用户想要的效果。
● 如果 gamma 为0,则不会影响加权求和的结果。
3.3,图像位运算cv2.bitwise:
cv2.bitwise 是 OpenCV 库中的一个模块,它包含了一系列用于执行图像的逐位运算的函数。这些函数可以对图像的像素值进行位级别的操作,常用于图像的掩码处理、图像合成和特征提取等。
通过位运算操作图像的像素值,可以实现多种图像处理效果比如:cv2.bitwise_and()用于掩码处理和图像融合,创建特定条件下的视觉效果;cv2.bitwise_or()用于图像合成和遮罩操作,创建图像的叠加效果。
3.3.1图像按位与cv2.bitwise_and()
dst = cv2.bitwise_and(src1, src2 , mask)功能:对两个图像进行逐位与运算。
● 参数:
○ src1:第一个输入图像数组。
○ src2:第二个输入图像数组。
○ mask:可选的掩码数组,用于指定要执行运算的像素区域。
● 返回值:
● dst:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是通过逐位与运算得到的。
● 计算公式:dst[i, j] = src1[i, j] & src2[i, j]
3.3.2图像按位或cv2.bitwise_or
dst = cv2.bitwise_or(src1, src2, mask)函数通过逐位或运算来比较两个图像的对应像素值。如果两个图像中至少有一个像素值为非零,则结果图像中对应的像素值将被设置为非零。
参数:
● src1:第一个输入图像数组。
● src2:第二个输入图像数组,尺寸和数据类型必须与 src1 相同。
● mask:可选的掩码数组,用于指定要执行运算的像素区域。
返回值:
● dst:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是通过逐位或运算得到的。
计算公式: 对于每个像素,输出 dst 的值计算如下:
dst[i, j] = src1[i, j] | src2[i, j]
3.3.3图像按位异或cv2.bitwise_or
cv2.bitwise_xor() 是 OpenCV 库中的一个函数,用于对两个图像进行逐位异或运算。
功能: cv2.bitwise_xor() 函数通过逐位异或运算来比较两个图像的对应像素值。如果两个图像中对应的像素值相同(都是零或都是非零),则结果图像中对应的像素值将为零;如果两个像素值不同,则结果图像中对应的像素值将为非零。
dst = cv2.bitwise_xor(src1, src2, mask)
参数:
● src1:第一个输入图像数组。
● src2:第二个输入图像数组,尺寸和数据类型必须与 src1 相同
● mask:可选的掩码数组,用于指定要执行运算的像素区域。
返回值:
● dst:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是通过逐位异或运算得到的。
计算公式: 对于每个像素,输出 dst 的值计算如下:
dst[i, j] = src1[i, j] ^ src2[i, j]
3.3.4图像按位非cv2.bitwise_not
dst = cv2.bitwise_not(src) 是 OpenCV 库中的一个函数,用于对图像进行逐位非运算,即按位取反。功能: cv2.bitwise_not() 函数通过逐位取反来反转图像的像素值。对于每个像素,如果原始像素值为非零,则结果图像中对应的像素值将为零;如果原始像素值为零,则结果图像中对应的像素值将为非零。
参数:
● src:输入图像数组。
返回值:
● dst:输出图像数组,其尺寸和数据类型与输入图像相同,每个像素的值是通过逐位取反得到的。