文章目录
基于OpenCV的传统视觉应用
1. 图像生成
1.1 图像显示
cv2.namedWindow
方法用于创建一个具有合适名称和大小的窗口,以在屏幕上显示图像和视频。默认情况下,图像以其原始大小显示,因此我们可能需要调整图像大小以使其适合我们的屏幕。
语法: cv2.namedWindow(window_name, flag)
参数:
- window_name:将显示图像/视频的窗口的名称
- flag: 表示窗口大小是自动设置还是可调整
- cv2.WINDOW_NORMAL –允许手动更改窗口大小
- cv2.WINDOW_AUTOSIZE(Default) –自动 设置窗口大小
- cv2.WINDOW_FULLSCREEN –将窗口大小更改为全屏
返回值:无
cv2.imshow
方法在窗口中显示图像,窗口会自动适应不同图像的尺寸。
语法: cv2.imshow(window_name, img)
参数:
- window_name:将显示图像/视频的窗口的名称
- img: 图像
返回值:无
import cv2
image = cv2.imread("images/kitten.jpg")
cv2.namedWindow("window", cv2.WINDOW_NORMAL)
cv2.imshow("window", image)
print('2秒后自动退出')
cv2.waitKey(2000)
cv2.destroyAllWindows()
print('按Esc退出')
if (cv2.waitKey() == 27):
cv2.destroyAllWindows()
#等待键盘输入,若没有输入,则一直等待
print('按任意键退出')
cv2.waitKey(0)
cv2.destoryAllWindows()
在使用OpenCV时,经常需要将处理过的图片展示出来,由于OpenCV中显示图片的函数cv2.imshow()功能往往不能满足我们的需求,所以经常用Matplotlib显示图像,方便结果图片的放大、保存等操作。
拓展:
matplotlib.pyplot.imshow
函数用于显示灰度图像、彩色图像、热度图等。它可以通过设置不同的参数来调整图像的显示效果和样式。
语法:matplotlib.pyplot.imshow(X, cmap = None, norm = None, aspect = None, interpolation = None, alpha = None, …)
参数:
- X:要显示的图像数据,可以是numpy数组或者PIL图像对象
- cmap(可选):颜色映射。用于将图像数据映射到特定的颜色样式。默认值为
None
,即直接显示图像数据的原始颜色- norm(可选):归一化,用于将图像数据归一化到指定范围。常用的归一化方式有
'none'
,'normalize'
,'log'
等- aspect(可选):图像显示的宽高比。可以设置为
auto
、equal
或者具体的宽高比值- interpolation(可选):插值方法,用于指定图像的显示方式。常用的插值方法有
nearest
,bilinear
,bicubic
等- alpha(可选):图像的透明度。范围从 0(完全透明)到 1(不透明)
返回值:无
1.2 图像读取
cv2.imread
方法用于读取图像。
语法: cv2.imread(filename, flags)
参数:
- filename:图像路径,找不到输出 None
- flags: 用于指定图像的加载方式
- cv2.IMREAD_COLOR(1):始终将图像转换为 3 通道BGR彩色图像,默认方式
- cv2.IMREAD_GRAYSCALE(0):始终将图像转换为单通道灰度图像
- cv2.IMREAD_UNCHANGED(-1):按原样返回加载的图像,包括Alpha通道。这种方式可以用于加载具有Alpha通道的PNG图像,以便在后续处理过程中保留图像的透明度信息
- cv2.IMREAD_ANYDEPTH(2):在输入具有相应深度时返回16位/ 32位图像,否则将其转换为8位
- cv2.IMREAD_ANYCOLOR(4):以任何可能的颜色格式读取图像
返回值:返回一个包含加载图像数据的numpy数组
注意事项:
cv2.imread
不支持中文路径和文件名,读取失败,但不会报错!- OpenCV 中彩色图像使用 BGR 格式,而 PIL、PyQt、matplotlib 等库使用的是 RGB 格式。
拓展:
- 从网络读取图像
import numpy as np
import urllib
import cv2
url = 'http://www.pyimagesearch.com/wp-content/uploads/2015/01/google_logo.png'
resp = urllib.urlopen(url)
image = np.asarray(bytearray(resp.read()), dtype = "uint8")
cv2.imshow('URL2Image',image)
cv2.waitKey()
- 读取中文路径的图像
cv2.imdecode
方法可以读取带有中文的文件路径和文件名的图像
语法: cv2.imdecode(buf, flags)
参数:
- buf:表示要加载的图像数据。可以是一个包含图像数据的numpy数组、Python字节字符串或文件对象
- flags: 用于指定图像的加载方式
- cv2.IMREAD_COLOR(1):以RGB模式加载图像
- cv2.IMREAD_GRAYSCALE(0):以灰度模式加载图像
- cv2.IMREAD_UNCHANGED(-1):按原样返回加载的图像,包括Alpha通道
返回值:返回一个包含加载图像数据的numpy数组
arr = np.fromfile(filename, dtype = np.uint8)
img = cv2.imdecode(arr, 1)
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
cv2.imshow('URL2Image',image)
cv2.waitKey()
2. 图像处理
2.1 图像模糊
cv2.blur
,cv2.medianBlur
和cv2.GaussianBlur
是OpenCV中常用的图像模糊处理函数,用于降低图像中的噪声或平滑图像的细节。它们具有不同的模糊效果和参数。
-
cv2.blur
cv2.blur
函数使用均值滤波器对图像进行平均模糊。它接受输入图像和内核大小作为参数,并将内核中的像素平均值应用于图像的每个像素。内核大小决定了平均的范围,越大的内核会产生更强的模糊效果。
语法:cv2.blur(src, ksize[, dst[, anchor[, borderType]]])
参数:
- src: 输入图像
- ksize:模糊核的大小,一般为正奇数。例如(3, 3)表示3x3大小的模糊核
- dst: 输出图像,可选参数
- anchor: 锚点位置,默认为(-1, -1),表示锚点位于核中心
- borderType: 边界模式,默认为cv2.BORDER_DEFAULT
返回值:无
-
cv2.medianBlur
cv2.medianBlur
函数使用中值滤波器对图像进行模糊处理。它将图像中每个像素的值替换为该像素所在邻域内的中值。中值滤波器对于去除椒盐噪声等脉冲噪声非常有效。
语法: cv2.medianBlur(src, ksize[, dst])
参数:
- src: 输入图像
- ksize: 模糊核的大小,一般为正奇数。例如3表示3x3大小的模糊核
- dst:输出图像,可选参数
返回值:无
-
cv2.GaussianBlur
cv2.GaussianBlur
函数使用高斯滤波器对图像进行模糊处理。高斯滤波器使用权重矩阵计算图像中每个像素的新值,以降低高频噪声。它可以通过ksize
参数设置内核大小和sigmaX
参数设置像素点高斯核标准差。
语法:cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])
参数:
- src: 输入图像
- ksize:模糊核的大小,一般为正奇数。例如(3, 3)表示3x3大小的模糊核
- sigma:X方向的高斯核标准差
- dst: 输出图像,可选参数
- sigmaY:Y方向的高斯核标准差,可选参数,默认为0
- borderType: 边界模式,默认为cv2.BORDER_DEFAULT
返回值:无
这些图像模糊函数都可以用于图像处理中的不同应用场景,具体使用哪个函数取决于图像处理的需求以及所需的模糊效果。
import cv2
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 正常显示中文
mpl.rcParams['axes.unicode_minus'] = False # 正常显示负号
# 均值模糊
img = cv2.imread("picture/housePepperSaltNoise.png", 0) # 读取灰度图
dst = cv2.blur(
img, # 输入图像
(5, 5) # 内核大小
)
# 图像显示
plt.subplot(1, 2, 1)
plt.imshow(img, 'gray')
plt.title('noise')
plt.subplot(1, 2, 2)
plt.imshow(dst, 'gray')
plt.title('blur')
plt.show()
# 中值模糊
img = cv2.imread("picture/housePepperSaltNoise.png", 0) # 读取灰度图
dst = cv2.medianBlur(
img, # 输入图像
(5) # 内核大小
)
# 图像显示
plt.subplot(1, 2, 1)
plt.imshow(img, 'gray')
plt.title('noise')
plt.subplot(1, 2, 2)
plt.imshow(dst, 'gray')
plt.title('medianBlur')
plt.show()
# 高斯模糊
img = cv2.imread("picture/houseGaussNoise.png", 0) # 读取灰度图
dst = cv2.GaussianBlur(
img, # 输入图像
(5, 5), # 内核大小
0 # 高斯核标准差
)
# 图像显示
plt.subplot(1, 2, 1)
plt.imshow(img, 'gray')
plt.title("noise")
plt.subplot(1, 2, 2)
plt.imshow(dst, 'gray')
plt.title("GaussianBlur")
plt.show()
拓展:
matplotlib是Matplotlib库中的一个全局参数配置对象,它允许用户以编程方式设置Matplotlib图形的默认参数。通过调整这些参数,可以自定义图形的外观和行为,以满足特定需求。
使用matplotlib.rcParams可以设置各种参数,如图形的默认字体、字体大小、线条颜色、线宽、图像尺寸等。通过修改这些参数,可以在绘制图形时全局地控制其样式。
常见的应用例子包括:
- 设置默认字体和字体大小:
matplotlib.rcParams['font.family'] = 'Arial'
、matplotlib.rcParams['font.size'] = 12
- 设置图像尺寸:
matplotlib.rcParams['figure.figsize'] = (8, 6)
- 设置线条颜色和线宽:
matplotlib.rcParams['lines.color'] = 'blue'
、matplotlib.rcParams['lines.linewidth'] = 2
注意:
-
修改了Matplotlib的全局参数后,所有的图形都会受到影响。因此,在绘制特定图形之前,可以根据需要调整这些参数,或者在特定图形的代码中重新设置参数,以避免全局参数对其他图形的影响。
-
matplotlib.rcParams
是一个字典对象,可以通过键值对的方式访问和修改参数。可以使用matplotlib.rcParams[]
语法访问或修改参数。
matplotlib.pyplot.subplot
方法用于创建子图。它允许在一个图形窗口内创建多个子图,并在这些子图中进行绘制。
语法:matplotlib.pyplot.subplot(nrows, ncols, index, **kwargs)
参数:
- nrows:子图网格的行数
- ncols:子图网格的列数
- index:当前子图的位置,图形窗口中子图的排列顺序是从左到右、从上到下的
返回值:返回一个Axes对象,代表当前创建的子图
常见的使用方式包括:
import matplotlib.pyplot as plt
# 创建一个2行2列的子图网格,并激活第一个子图
plt.subplot(2, 2, 1)
plt.plot(x1, y1)
plt.title('Plot 1')
# 激活第二个子图,绘制柱状图
plt.subplot(2, 2, 2)
plt.bar(x2, y2)
plt.title('Plot 2')
# 激活第三个子图,绘制散点图
plt.subplot(2, 2, 3)
plt.scatter(x3, y3)
plt.title('Plot 3')
# 激活第四个子图,绘制饼图
plt.subplot(2, 2, 4)
plt.pie(sizes, labels=labels)
plt.title('Plot 4')
plt.tight_layout() # 自动调整子图的布局
plt.show() # 显示图形窗口
2.2 图像锐化
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['Simhei'] # 正常显示中文
mpl.rcParams['axes.unicode_minus'] = False # 正常显示负号
# 读取灰度图
moon = cv.imread("picture/moon.jpg", 0)
print(moon.dtype)
moon_copy = np.copy(moon)
moon_float = moon_copy.astype("float") # 修改图像类型
print(moon_float.dtype)
# 计算梯度图
row, column = moon.shape
gradient = np.zeros((row, column))
for x in range(row - 1):
for y in range(column - 1):
gx = abs(moon_float[x + 1, y] - moon_float[x, y]) # 通过相邻像素相减计算图像梯度
gy = abs(moon_float[x, y + 1] - moon_float[x, y]) # 通过相邻像素相减计算图像梯度
gradient[x, y] = gx + gy
# 叠加灰度图与梯度图得到锐化图
sharp = moon_float + gradient
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp)) # 将小于0的像素设置为0,将大于255的像素设置为255
# 修改图像类型
gradient = gradient.astype("uint8")
sharp = sharp.astype("uint8")
# 显示图像
plt.subplot(1, 3, 1)
plt.imshow(moon, "gray")
plt.title("灰度图")
plt.subplot(1, 3, 2)
plt.imshow(gradient, "gray")
plt.title("梯度图")
plt.subplot(1, 3, 3)
plt.imshow(sharp, "gray")
plt.title("锐化图")
plt.show()
拓展:
在Py库中,astype
方法用于将数组的数据类型转换为指定的数据类型。它返回一个新的数组,新数组的数据类型由用户指定。
语法:numpy.ndarray.astype(dtype, order = ‘K’, casting = ‘unsafe’, subok = True, copy = True)
参数:
- dtype:要转换的目标数据类型
- order:数组的存储顺序,默认为’K’(保持原有顺序)
- casting:数据转换的规则,默认为’unsafe’
- unsafe:表示可以进行不安全的转换
- safe:只允许转换为更宽松的类型
- same_kind: 只允许转换为相同类型或者同一种类型的更宽松的类型
- subok:返回的数组是否为子类数组,默认为True
- copy:是否返回副本,默认为True
返回值:返回一个Axes对象,代表当前创建的子图
astype
函数常用于以下场景:
- 数据类型转换:将数组的数据类型转换为其他类型,如将整数数组转换为浮点数数组。
- 数据压缩:将数据类型由较宽松的类型转换为较严格的类型,从而减小数组的内存占用。
- 数据类型统一:确保多个数组具有相同的数据类型,以便进行计算。
示例:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr.dtype) # 输出:int64
arr_float = arr.astype(float)
print(arr_float) # 输出:[1. 2. 3. 4. 5.]
print(arr_float.dtype) # 输出:float64
arr_int32 = arr.astype(np.int32)
print(arr_int32) # 输出:[1 2 3 4 5]
print(arr_int32.dtype) # 输出:int32
numpy.where
是一个用于根据给定的条件选择元素的函数。它可以在数组或矩阵中根据给定的条件返回一个新数组或矩阵,其中满足条件的元素被替换为指定的值。
语法:numpy.where(condition, x, y)
参数:
- condition:表示条件的布尔数组或布尔表达式
- x:满足条件的元素将被替换为x中对应位置的元素
- y:不满足条件的元素将被替换为y中对应位置的元素
返回值:根据条件替换后的新数组或矩阵
示例:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
new_arr = np.where(arr > 3, arr, 0)
print(new_arr)
输出:
[0 0 0 4 5]
在上述示例中,我们创建了一个长度为5的数组arr
。然后,我们使用np.where
函数根据条件arr > 3
对数组进行处理。对于满足条件的元素(大于3),我们将它们替换为原来的元素值;对于不满足条件的元素,我们将它们替换为0。最后,我们打印了新的数组new_arr
,结果是[0, 0, 0, 4, 5]
。
3. 图像特征检测
3.1 边缘编辑和增强
cv2.Canny
是 OpenCV 库中的一个边缘检测函数,用于检测图像中的边缘。它基于 Canny 边缘检测算法,通过检测图像中的强度梯度来定位图像边缘。
通过调整阈值和其他可选参数,可以控制 Canny 算法的边缘检测结果。一般来说,较低的阈值会导致更多的边缘被检测到,而较高的阈值会导致较少的边缘被检测到。
语法:cv2.Canny(image, threshold1, threshold2, apertureSize = None, L2gradient = None)
参数:
- image:输入的图像,必须是单通道灰度图像
- threshold1:低阈值,边缘强度低于该值的像素点被认为是非边缘点。
- threshold2:高阈值,边缘强度高于该值的像素点被认为是边缘点。
- apertureSize(可选):Sobel算子的孔径大小,默认为3,可以设置为3、5、7等,必须是奇数
- L2gradient(可选):指定计算梯度幅值的方法,如果为 True,则采用更精确的 L 2 L_2 L2范数方法,默认值为 False
返回值:检测到的边缘图像,为单通道灰度图像
注意:
如果像素点的梯度灰度值在threshold1和threshold2之间,则需要判断当前像素点是否与某个确定的边缘像素点相连,如果相连则认为是边缘点,不相连则被抛弃
3.2 图像轮廓检测
cv2.threshold是OpenCV中用于图像阈值化的函数,用于将灰度图像转为二值图像。它的语法如下:
retval, threshold_image = cv2.threshold(src, thresh, maxval, type [, dst])
参数:
- src:输入的灰度图像,即要进行阈值化的图像。
- thresh:阈值,用于进行像素分类的阈值。
- maxval:最大值,指定当像素值高于或低于阈值时所赋予的像素值。
- type:阈值化的类型,指定如何对像素进行分类。包括cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、cv2.THRESH_TRUNC、cv2.THRESH_TOZERO和cv2.THRESH_TOZERO_INV等。
- dst:可选参数,输出的二值图像。
返回值:
- retval:最终使用的阈值。
- threshold_image:输出的二值图像。
cv2.threshold函数根据阈值将像素分为两个类别,大于阈值的像素赋予maxval,小于阈值的像素赋予0(或其他指定的值)。根据不同的阈值类型,可以实现不同的二值化效果。
一般情况下,可以先使用cv2.cvtColor函数将图像转换为灰度图像,然后再使用cv2.threshold进行阈值化处理。具体的阈值选择需要根据图像的特点和需求进行调整。
cv.findContours是OpenCV中的一个函数,用于在二值图像中查找轮廓。它的语法如下:
contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
参数:
- image:输入的二值图像,需要是单通道、二值化的图像,通常是通过阈值化等操作得到的。
- mode:轮廓的检索模式,指定轮廓的层级结构和检索方式。常用的模式有cv2.RETR_EXTERNAL、cv2.RETR_LIST、cv2.RETR_TREE等。
- method:轮廓的逼近方法,指定轮廓的表示方式。常用的方法有cv2.CHAIN_APPROX_SIMPLE、cv2.CHAIN_APPROX_NONE等。
- contours:可选参数,用于存储检测到的轮廓。
- hierarchy:可选参数,用于存储轮廓之间的层级关系。
- offset:可选参数,每个轮廓的偏移量。
返回值:
- contours:检测到的轮廓,存储为一个列表,每个轮廓由一系列点构成。
- hierarchy:轮廓之间的层级关系,存储为一个列表,可以用于分析轮廓的嵌套关系。
cv2.findContours函数会在给定的二值图像中查找并提取出轮廓。提取出的轮廓存储在contours中,而每个轮廓由一系列的点构成,可以遍历contours获取每个轮廓的点集。由于图像中可能存在多个轮廓,因此contours是一个存储了多个轮廓的列表。
根据需求不同,可以选择不同的轮廓检索模式和逼近方法。可以通过分析轮廓之间的层级关系,进行进一步的处理和分析。
cv2.drawContours是OpenCV中的一个函数,用于在图像上绘制轮廓。它的语法如下:
image = cv2.drawContours(image, contours, contourIdx, color, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]])
参数:
- image:要绘制轮廓的图像。
- contours:轮廓列表,包含要绘制的轮廓。
- contourIdx:要绘制的轮廓的索引。可以通过遍历contours列表来依次绘制每个轮廓。
- color:指定绘制轮廓的颜色,可以使用BGR格式表示颜色。
- thickness:指定绘制轮廓的线条宽度。
- lineType:可选参数,指定绘制轮廓的线条类型,默认为8连线。可以使用cv2.LINE_8、cv2.LINE_4、cv2.LINE_AA等表示。
- hierarchy:轮廓之间的层级关系,可以通过cv2.findContours函数获取。
- maxLevel:可选参数,指定要绘制的轮廓的最大层级。
- offset:可选参数,每个轮廓的偏移量。
返回值:
- image:绘制了轮廓的图像。
cv2.drawContours函数可以根据给定的轮廓和参数,在图像上绘制轮廓线条。通过遍历contours列表,可以逐个绘制每个轮廓。可以根据需要指定绘制轮廓的颜色、线条宽度和线条类型等参数。
注意:在调用cv2.drawContours函数之前,需要先创建要绘制轮廓的图像,可以使用cv2.imread函数读取图像文件,或者使用numpy创建一个空白图像。
3.3 图像角点和线条检测
cv2.cornerHarris是OpenCV库中的一个函数,用于检测图像中的角点。它使用Harris角点检测算法来识别图像中的角点,并返回一个角点响应图像。
语法:
dst = cv2.cornerHarris(src, blockSize, ksize, k)
参数解释:
- src:输入的灰度图像,应为单通道、8位或32位浮点图像。
- blockSize:角点检测中考虑的邻域大小。
- ksize:Sobel求导中使用的Sobel算子的孔径大小。一般为3。
- k:角点响应函数中的自由参数,一般取0.04到0.06之间的值。
返回值:
- dst:形状与输入图像相同的浮点型角点响应图像。
使用cv2.cornerHarris函数,可以实现在图像中找到角点的功能。角点检测可以应用于各种计算机视觉任务,如特征提取、目标检测和跟踪等。
4. 图像特征匹配
cv2.ORB_create是OpenCV库中的一个函数,用于创建ORB(Oriented FAST and Rotated BRIEF)特征检测器和描述符。
语法:
orb = cv2.ORB_create(nfeatures, scaleFactor, nlevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize, fastThreshold)
参数解释:
- nfeatures:要检测的特征点数量,默认为500。
- scaleFactor:用于构建图像金字塔的尺度因子,默认为1.2。
- nlevels:图像金字塔的层数,默认为8。
- edgeThreshold:边缘阈值,较高的阈值可过滤掉边缘特征点,默认为31。
- firstLevel:金字塔的起始层级,默认为0。
- WTA_K:WTA描述符生成的默认数量,默认为2。
- scoreType:计算角点响应函数类型,默认为cv2.ORB_HARRIS_SCORE。
- patchSize:计算角点响应函数时使用的窗口大小,默认为31。
- fastThreshold:快速角点检测阈值,默认为20。
返回值:
- orb:ORB特征检测器对象。
通过cv2.ORB_create函数创建ORB特征检测器后,可以使用它来检测和描述图像中的特征点,进而应用于诸如特征匹配、目标跟踪和图像拼接等计算机视觉任务中。
ORB(Oriented FAST and Rotated BRIEF)是一种用于计算机视觉中图像特征检测和描述的算法。它结合了FAST(Features from Accelerated Segment Test)关键点检测器和BRIEF(Binary Robust Independent Elementary Features)描述符,具有速度快、稳健性强的特点。
ORB算法的关键技术是FAST关键点检测器和BRIEF特征描述符的结合。FAST是一种高效的角点检测算法,能够快速定位图像中的角点。而BRIEF是一种二进制特征描述符,能够用一组二进制值来描述关键点的局部特征。
ORB算法的优点是既具有FAST算法的高速性能,又具备BRIEF算法的简洁和稳健性。它不仅能够检测图像中的关键点,还能够生成特征描述符,用于进行特征匹配、目标跟踪、图像拼接等计算机视觉任务。
由于ORB算法的设计考虑了实时性和鲁棒性,因此在许多应用中得到了广泛使用,特别是在移动机器人、自主导航和增强现实等领域。它在处理速度和性能之间取得了一定的平衡。
cv.ORB_create().detectAndCompute是OpenCV库中ORB特征检测器和描述符的常用方法,用于在图像中检测并计算ORB特征。
语法:
keypoints, descriptors = cv2.ORB_create().detectAndCompute(image, mask)
参数解释:
- image:输入的灰度图像,应为单通道、8位灰度图像。
- mask:可选参数,指定要进行特征检测的区域。
返回值:
- keypoints:检测到的关键点,为一个包含特征点位置和其他附加信息的列表。
- descriptors:每个关键点对应的特征描述符,为一个NumPy数组。
使用cv2.ORB_create().detectAndCompute方法,可以在给定图像中检测ORB特征,并计算每个关键点的特征描述符。检测到的关键点可以用于特征匹配、目标跟踪和图像拼接等计算机视觉任务。特征描述符表示每个关键点周围区域的局部特征,可用于计算特征点的相似度与匹配度。
cv.BFMatcher是OpenCV库中的一个类,用于执行基于暴力匹配算法(Brute-Force Matching)的特征点匹配。它可以在给定的特征描述符之间计算最佳匹配。
创建BFMatcher对象的语法:
bf = cv2.BFMatcher(normType, crossCheck)
参数解释:
- normType:用于计算特征距离的规范化类型,常用的有cv2.NORM_L2或cv2.NORM_HAMMING。
- crossCheck:布尔类型参数,指定是否执行交叉检查。如果为True,则仅匹配A中的特征点到B中的特征点,并验证反向匹配。默认为False。
使用BFMatcher对象进行特征点匹配的语法:
matches = bf.match(descriptors1, descriptors2)
参数解释:
- descriptors1和descriptors2:要匹配的两组特征描述符。
返回值:
- matches:特征点匹配结果,为一个列表,列表中的每个元素都是一个包含特征点索引和匹配距离的对象。
BFMatcher类可以用于特征点匹配,例如在图像中找到相似的特征点以进行目标识别、图像配准和特征匹配等任务。它在计算机视觉中是一种简单而有效的方法,可以基于描述符之间的距离度量进行特征点匹配。
cv2.drawMatches函数是OpenCV中用于绘制特征点匹配结果的函数。它可以将两幅图像的特征点和它们的匹配线绘制在一起,以便可视化特征点的匹配情况。
该函数的语法如下:
drawMatches(img1, keypoints1, img2, keypoints2, matches, outputImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]])
参数说明:
- img1: 第一幅图像。
- keypoints1: 第一幅图像的特征点。
- img2: 第二幅图像。
- keypoints2: 第二幅图像的特征点。
- matches: 特征点的匹配结果。
- outputImg: 输出图像。
- matchColor (可选): 匹配线的颜色,默认为红色。
- singlePointColor (可选): 单个特征点的颜色,默认为白色。
- matchesMask (可选): 掩码,用于指定绘制哪些匹配线,默认为None。
- flags (可选): 可选的标志参数。
绘制出的匹配结果图像将会包含连线连接两幅图像中匹配的特征点。匹配线的颜色可以通过 matchColor 参数进行自定义,单个特征点的颜色可以通过 singlePointColor 参数进行自定义。
注意:图像、特征点和匹配结果需要事先准备好。
示例用法:
import cv2
# 读取图像和特征点
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
kp1, des1 = detector.detectAndCompute(img1, None)
kp2, des2 = detector.detectAndCompute(img2, None)
# 特征匹配
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
# 绘制匹配结果
output_img = cv2.drawMatches(img1, kp1, img2, kp2, matches, None, flags=2)
# 显示图像
cv2.imshow('Matches', output_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上示例中,我们通过ORB特征检测器和BFMatcher进行了特征点的匹配,然后使用cv2.drawMatches函数绘制了匹配结果图像,最后将图像显示出来。
5. 图像对齐与拼接
5.1 全景图像拼接
cv2.Stitcher_create()是OpenCV中用于创建图像拼接对象的函数。它返回一个用于拼接图像的Stitcher对象。
拼接图像是将多个重叠或相邻的图像合并成一个大图像的过程。cv2.Stitcher_create()函数可以根据输入的图像自动进行特征匹配、图像校正和融合等操作,从而实现高质量的图像拼接。
使用cv2.Stitcher_create()函数的一般流程如下:
- 创建Stitcher对象:
stitcher = cv2.Stitcher_create()
- 加载要拼接的图像:
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
image3 = cv2.imread('image3.jpg')
- 调用stitcher对象的stitch()方法拼接图像:
status, result = stitcher.stitch([image1, image2, image3])
该方法的第一个参数是一个包含待拼接图像的列表,返回值status表示拼接的状态,result是拼接后的图像。
- 检查拼接状态并显示结果:
if status == cv2.Stitcher_OK:
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("Stitching failed!")
在上述流程中,首先创建一个Stitcher对象,然后加载要拼接的图像,接着调用stitch()方法进行图像拼接。最后,根据拼接状态判断是否成功,并显示拼接结果。
需要注意的是,cv2.Stitcher_create()函数返回的是OpenCV的Stitcher对象,要确保OpenCV版本支持该函数。
cv2.copyMakeBorder是OpenCV中的一个函数,用于创建一个带有边界的图像副本。
该函数的语法如下:
dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst, value])
参数说明:
- src:输入的原始图像。
- top:上方边界的大小(单位:像素)。
- bottom:下方边界的大小(单位:像素)。
- left:左侧边界的大小(单位:像素)。
- right:右侧边界的大小(单位:像素)。
- borderType:边界类型,可以是cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE、cv2.BORDER_REFLECT、cv2.BORDER_REFLECT_101等。
- dst (可选):可选的输出图像。
- value (可选):可选的边界值。
cv2.copyMakeBorder函数可以在输入图像的四个边界上添加指定大小的边界。边界的大小通过top、bottom、left和right参数指定。边界类型通过borderType参数进行选择,例如使用cv2.BORDER_CONSTANT可以指定固定的边界值。可选的输出图像和边界值可以通过dst和value参数进行指定。
函数返回一个新的图像副本,其中包含添加了边界的原始图像。
示例用法:
import cv2
# 读取图像
image = cv2.imread('image.jpg')
# 添加边界
border_image = cv2.copyMakeBorder(image, top=10, bottom=10, left=10, right=10, borderType=cv2.BORDER_CONSTANT, value=[0, 255, 0])
# 显示原始图像和添加边界后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Image with Border', border_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上示例中,我们读取了一副图像,然后使用cv2.copyMakeBorder函数在图像的上、下、左、右四个边界上添加了10像素大小的绿色边界,并显示了原始图像和添加边界后的图像。
cv2.contourArea是OpenCV中用于计算轮廓区域面积的函数。它可以计算给定轮廓的封闭区域的面积。
该函数的语法如下:
area = cv2.contourArea(contour)
参数说明:
- contour: 输入的轮廓,可以是在图像中检测到的边缘轮廓。
- area: 返回计算出的轮廓区域面积。
cv2.contourArea函数会根据轮廓的形状计算出封闭区域的面积,返回一个浮点数表示面积大小,单位为像素的平方。
示例用法:
import cv2
# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray, 100, 200)
# 查找轮廓
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 计算并打印轮廓区域面积
for contour in contours:
area = cv2.contourArea(contour)
print("Contour Area:", area)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
# 显示图像
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上示例中,我们首先读取图像并将其转换为灰度图像。然后使用Canny边缘检测算法进行边缘检测。接下来使用findContours函数查找轮廓,并通过循环计算每个轮廓的区域面积并打印出来。最后,我们使用drawContours函数将轮廓绘制到原始图像上并显示出来。
cv.erode函数是OpenCV中图像腐蚀操作。它通过定义的结元素对输入图进行局部区域的小值操作,从而现图像腐蚀效果。
语法如:
cv2.erode(src, kernel[, dst[, anchor iterations[, borderType[, borderValue]]]]])
参数说明:
- src:输入图像,可以是灰度图像或彩色图像,数据类型为uint8。
- kernel:腐蚀操作的结构元素,可以通过函数cv2.getStructuringElement来创建,也可以自行定义,通常为一个正方形或矩形区域。
- dst:输出图像,与原始图像具有相同的大小和数据类型,可选参数。
- anchor:锚点位置,默认为(-1,-1),表示结构元素的中心位置。
- iterations:腐蚀操作的迭代次数,默认为1。
- borderType:边界类型,默认为cv2.BORDER_CONSTANT。
- borderValue:边界值,默认为0。
腐蚀操作会通过将每个像素的值与结构元素的值进行比较,如果存在至少一个该像素周围的像素值不等于0,则将该像素设置为0。这样就可以实现图像中边缘部分的缩小和连接细化的效果,常用于图像的前景提取和图像处理预处理等应用。
cv.subtract函数是OpenCV中图像相减操作的函数。它可以用于两个图像之间的像素级别减法运算,得到两个图像之间的差异。
语法如下:
cv2.subtract(src1, src2[, dst[, mask[, dtype]]])
参数说明:
- src1:第一个输入图像,数据类型为uint8或float32。
- src2:第二个输入图像,数据类型必须与src1相同。
- dst:输出图像,与输入图像具有相同的大小和数据类型,可选参数。
- mask:可选的掩码图像,仅计算指定区域的像素差异。
- dtype:输出图像的数据类型,可选参数,默认为-1,表示与输入图像的数据类型相同。
cv2.subtract函数会对应位置上的像素值进行减法运算,得到两个图像对应像素的差值。注意,如果输入图像的数据类型是uint8,则相减结果可能会溢出,所以建议将输出图像的数据类型设置为更高的数据类型,如uint16或float32。
拓展:
cv2.copyMakeBorder是OpenCV中的一个函数,用于创建一个带有边界的图像副本。
该函数的语法如下:
dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, dst, value])
参数说明:
- src:输入的原始图像。
- top:上方边界的大小(单位:像素)。
- bottom:下方边界的大小(单位:像素)。
- left:左侧边界的大小(单位:像素)。
- right:右侧边界的大小(单位:像素)。
- borderType:边界类型,可以是cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE、cv2.BORDER_REFLECT、cv2.BORDER_REFLECT_101等。
- dst (可选):可选的输出图像。
- value (可选):可选的边界值。
cv2.copyMakeBorder函数可以在输入图像的四个边界上添加指定大小的边界。边界的大小通过top、bottom、left和right参数指定。边界类型通过borderType参数进行选择,例如使用cv2.BORDER_CONSTANT可以指定固定的边界值。可选的输出图像和边界值可以通过dst和value参数进行指定。
函数返回一个新的图像副本,其中包含添加了边界的原始图像。
示例用法:
import cv2
# 读取图像
image = cv2.imread('image.jpg')
# 添加边界
border_image = cv2.copyMakeBorder(image, top=10, bottom=10, left=10, right=10, borderType=cv2.BORDER_CONSTANT, value=[0, 255, 0])
# 显示原始图像和添加边界后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Image with Border', border_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上示例中,我们读取了一副图像,然后使用cv2.copyMakeBorder函数在图像的上、下、左、右四个边界上添加了10像素大小的绿色边界,并显示了原始图像和添加边界后的图像。
cv2.contourArea是OpenCV中用于计算轮廓区域面积的函数。它可以计算给定轮廓的封闭区域的面积。
该函数的语法如下:
area = cv2.contourArea(contour)
参数说明:
- contour: 输入的轮廓,可以是在图像中检测到的边缘轮廓。
- area: 返回计算出的轮廓区域面积。
cv2.contourArea函数会根据轮廓的形状计算出封闭区域的面积,返回一个浮点数表示面积大小,单位为像素的平方。
示例用法:
import cv2
# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 进行边缘检测
edges = cv2.Canny(gray, 100, 200)
# 查找轮廓
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 计算并打印轮廓区域面积
for contour in contours:
area = cv2.contourArea(contour)
print("Contour Area:", area)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
# 显示图像
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上示例中,我们首先读取图像并将其转换为灰度图像。然后使用Canny边缘检测算法进行边缘检测。接下来使用findContours函数查找轮廓,并通过循环计算每个轮廓的区域面积并打印出来。最后,我们使用drawContours函数将轮廓绘制到原始图像上并显示出来。
cv.erode函数是OpenCV中图像腐蚀操作。它通过定义的结元素对输入图进行局部区域的小值操作,从而现图像腐蚀效果。
语法如:
cv2.erode(src, kernel[, dst[, anchor iterations[, borderType[, borderValue]]]]])
参数说明:
- src:输入图像,可以是灰度图像或彩色图像,数据类型为uint8。
- kernel:腐蚀操作的结构元素,可以通过函数cv2.getStructuringElement来创建,也可以自行定义,通常为一个正方形或矩形区域。
- dst:输出图像,与原始图像具有相同的大小和数据类型,可选参数。
- anchor:锚点位置,默认为(-1,-1),表示结构元素的中心位置。
- iterations:腐蚀操作的迭代次数,默认为1。
- borderType:边界类型,默认为cv2.BORDER_CONSTANT。
- borderValue:边界值,默认为0。
腐蚀操作会通过将每个像素的值与结构元素的值进行比较,如果存在至少一个该像素周围的像素值不等于0,则将该像素设置为0。这样就可以实现图像中边缘部分的缩小和连接细化的效果,常用于图像的前景提取和图像处理预处理等应用。
cv.subtract函数是OpenCV中图像相减操作的函数。它可以用于两个图像之间的像素级别减法运算,得到两个图像之间的差异。
语法如下:
cv2.subtract(src1, src2[, dst[, mask[, dtype]]])
参数说明:
- src1:第一个输入图像,数据类型为uint8或float32。
- src2:第二个输入图像,数据类型必须与src1相同。
- dst:输出图像,与输入图像具有相同的大小和数据类型,可选参数。
- mask:可选的掩码图像,仅计算指定区域的像素差异。
- dtype:输出图像的数据类型,可选参数,默认为-1,表示与输入图像的数据类型相同。
cv2.subtract函数会对应位置上的像素值进行减法运算,得到两个图像对应像素的差值。注意,如果输入图像的数据类型是uint8,则相减结果可能会溢出,所以建议将输出图像的数据类型设置为更高的数据类型,如uint16或float32。