计算机视觉应用与实践 学习笔记一

基于OpenCV的传统视觉应用

1. 图像生成

1.1 图像显示

cv2.namedWindow方法用于创建一个具有合适名称和大小的窗口,以在屏幕上显示图像和视频。默认情况下,图像以其原始大小显示,因此我们可能需要调整图像大小以使其适合我们的屏幕。

语法: cv2.namedWindow(window_name, flag)
参数

  1. window_name:将显示图像/视频的窗口的名称
  2. flag: 表示窗口大小是自动设置还是可调整
  • cv2.WINDOW_NORMAL –允许手动更改窗口大小
  • cv2.WINDOW_AUTOSIZE(Default) –自动 设置窗口大小
  • cv2.WINDOW_FULLSCREEN –将窗口大小更改为全屏

返回值:无

cv2.imshow方法在窗口中显示图像,窗口会自动适应不同图像的尺寸。

语法: cv2.imshow(window_name, img)
参数

  1. window_name:将显示图像/视频的窗口的名称
  2. 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(可选):图像显示的宽高比。可以设置为autoequal或者具体的宽高比值
  • interpolation(可选):插值方法,用于指定图像的显示方式。常用的插值方法有 nearest, bilinear, bicubic
  • alpha(可选):图像的透明度。范围从 0(完全透明)到 1(不透明)

返回值:无

1.2 图像读取

cv2.imread方法用于读取图像。

语法: cv2.imread(filename, flags)
参数

  1. filename:图像路径,找不到输出 None
  2. 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数组

注意事项:

  1. cv2.imread不支持中文路径和文件名,读取失败,但不会报错!
  2. OpenCV 中彩色图像使用 BGR 格式,而 PIL、PyQt、matplotlib 等库使用的是 RGB 格式。

拓展:

  1. 从网络读取图像
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()
  1. 读取中文路径的图像

cv2.imdecode方法可以读取带有中文的文件路径和文件名的图像

语法: cv2.imdecode(buf, flags)
参数

  1. buf:表示要加载的图像数据。可以是一个包含图像数据的numpy数组、Python字节字符串或文件对象
  2. 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.blurcv2.medianBlurcv2.GaussianBlur是OpenCV中常用的图像模糊处理函数,用于降低图像中的噪声或平滑图像的细节。它们具有不同的模糊效果和参数。

  1. cv2.blur

    cv2.blur函数使用均值滤波器对图像进行平均模糊。它接受输入图像和内核大小作为参数,并将内核中的像素平均值应用于图像的每个像素。内核大小决定了平均的范围,越大的内核会产生更强的模糊效果。

语法:cv2.blur(src, ksize[, dst[, anchor[, borderType]]])
参数

  • src: 输入图像
  • ksize:模糊核的大小,一般为正奇数。例如(3, 3)表示3x3大小的模糊核
  • dst: 输出图像,可选参数
  • anchor: 锚点位置,默认为(-1, -1),表示锚点位于核中心
  • borderType: 边界模式,默认为cv2.BORDER_DEFAULT

返回值:无

  1. cv2.medianBlur

    cv2.medianBlur函数使用中值滤波器对图像进行模糊处理。它将图像中每个像素的值替换为该像素所在邻域内的中值。中值滤波器对于去除椒盐噪声等脉冲噪声非常有效。

语法: cv2.medianBlur(src, ksize[, dst])
参数

  • src: 输入图像
  • ksize: 模糊核的大小,一般为正奇数。例如3表示3x3大小的模糊核
  • dst:输出图像,可选参数

返回值:无

  1. 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

注意:

  1. 修改了Matplotlib的全局参数后,所有的图形都会受到影响。因此,在绘制特定图形之前,可以根据需要调整这些参数,或者在特定图形的代码中重新设置参数,以避免全局参数对其他图形的影响。

  2. matplotlib.rcParams是一个字典对象,可以通过键值对的方式访问和修改参数。可以使用matplotlib.rcParams[]语法访问或修改参数。

matplotlib.pyplot.subplot方法用于创建子图。它允许在一个图形窗口内创建多个子图,并在这些子图中进行绘制。

语法:matplotlib.pyplot.subplot(nrows, ncols, index, **kwargs)
参数

  1. nrows:子图网格的行数
  2. ncols:子图网格的列数
  3. 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)
参数

  1. dtype:要转换的目标数据类型
  2. order:数组的存储顺序,默认为’K’(保持原有顺序)
  3. casting:数据转换的规则,默认为’unsafe’
  • unsafe:表示可以进行不安全的转换
  • safe:只允许转换为更宽松的类型
  • same_kind: 只允许转换为相同类型或者同一种类型的更宽松的类型
  1. subok:返回的数组是否为子类数组,默认为True
  2. copy:是否返回副本,默认为True
    返回值:返回一个Axes对象,代表当前创建的子图

astype函数常用于以下场景:

  1. 数据类型转换:将数组的数据类型转换为其他类型,如将整数数组转换为浮点数数组。
  2. 数据压缩:将数据类型由较宽松的类型转换为较严格的类型,从而减小数组的内存占用。
  3. 数据类型统一:确保多个数组具有相同的数据类型,以便进行计算。

示例:

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)
参数

  1. condition:表示条件的布尔数组或布尔表达式
  2. x:满足条件的元素将被替换为x中对应位置的元素
  3. 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()函数的一般流程如下:

  1. 创建Stitcher对象:
stitcher = cv2.Stitcher_create()
  1. 加载要拼接的图像:
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
image3 = cv2.imread('image3.jpg')
  1. 调用stitcher对象的stitch()方法拼接图像:
status, result = stitcher.stitch([image1, image2, image3])

该方法的第一个参数是一个包含待拼接图像的列表,返回值status表示拼接的状态,result是拼接后的图像。

  1. 检查拼接状态并显示结果:
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。

6. 相机运动估计

基于机器学习和深度学习的视觉应用

7. 基于SVM模型的手写数字识别

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海绵不是宝宝817

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值