目录
提取和插入颜色通道 (extractChannel 和 insertChannel)
缩放、计算绝对值并转换为8位 (convertScaleAbs)
快速非局部均值去噪 (fastNlMeansDenoising)
彩色图像的快速非局部均值去噪 (fastNlMeansDenoisingColored)
笛卡尔坐标与极坐标转换 (cartToPolar 和 polarToCart)
获取结构元素 (getStructuringElement)
均值漂移滤波 (pyrMeanShiftFiltering)
计算连通组件并返回统计信息 (connectedComponentsWithStats)
检测并绘制轮廓 (findContours 和 drawContours)
计算轮廓的周长和面积 (arcLength 和 contourArea)
计算包围轮廓的最小矩形和最小圆 (minAreaRect 和 minEnclosingCircle)
测试点与轮廓的相对位置 (pointPolygonTest)
从图像中提取矩形区域的子像素精度补偿 (getRectSubPix)
获取最优的DFT大小 (getOptimalDFTSize)
仿射变换 (warpAffine 和 getAffineTransform)
透视变换 (warpPerspective 和 getPerspectiveTransform)
极坐标变换 (warpPolar 和 linearPolar)
将输入图像加权累加到累加图像中 (accumulateWeighted)
将输入图像的平方累加到累加图像中 (accumulateSquare)
将两个输入图像的乘积累加到累加图像中 (accumulateProduct)
将数据从主成分空间反投影回原空间 (backProject)
朴素贝叶斯分类器(NormalBayesClassifier)
棋盘格角点检测 (findChessboardCorners)
一、图像文件
图像文件 | |||
---|---|---|---|
imread | imwrite | imshow | VideoCapture |
读取图像文件 | 写入图像文件 | 显示图像 | 捕获视频 |
1. imread
:读取图像文件
作用:从文件读取图像并存储在一个矩阵(数组)中。
使用场景:当需要从磁盘加载图像进行处理或分析时。
样例代码:
import cv2
# 从文件读取图像
image = cv2.imread('path_to_image.jpg')
# 检查图像是否读取成功
if image is None:
print("图像读取失败")
else:
print("图像读取成功")
2. imwrite
:写入图像文件
作用:将图像矩阵(数组)写入到文件。
使用场景:当需要保存处理后的图像到磁盘时。
样例代码:
import cv2
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 处理图像(例如,转换为灰度图像)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 将处理后的图像写入文件
cv2.imwrite('path_to_save_image.jpg', gray_image)
3. imshow
:显示图像
作用:在窗口中显示图像。
使用场景:当需要在屏幕上查看图像或处理结果时。
样例代码:
import cv2
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 显示图像
cv2.imshow('Image', image)
# 等待按键按下
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
4. VideoCapture
:捕获视频
作用:从摄像头或视频文件中捕获视频流。
使用场景:当需要从摄像头获取实时视频流或从文件中读取视频进行处理时。
样例代码:
import cv2
# 打开摄像头(参数0表示第一个摄像头)
cap = cv2.VideoCapture(0)
# 检查摄像头是否打开成功
if not cap.isOpened():
print("无法打开摄像头")
else:
while True:
# 逐帧捕获
ret, frame = cap.read()
# 如果读取成功
if ret:
# 显示帧
cv2.imshow('Video', frame)
# 按下 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()
二、创建Mat
在OpenCV中,Mat
对象是一个强大的矩阵类型,用于表示图像和矩阵数据。下面是一些常用的构造函数和方法,用于创建和操作Mat
对象。
创建Mat的构造函数 | ||
zeros | ones | eye |
创建一个所有元素为零的矩阵 | 创建一个所有元素为一的矩阵 | 创建一个单位矩阵(对角线元素为一,其他元素为零) |
操作函数 | ||
colRange | rowRange | Range |
获取指定列范围的子矩阵 | 获取指定行范围的子矩阵 | 表示一个范围 |
1、创建Mat
对象
创建一个所有元素为零的矩阵
import cv2
import numpy as np
# 创建一个3x3的零矩阵
zero_matrix = np.zeros((3, 3), dtype=np.uint8)
print("Zero Matrix:\n", zero_matrix)
创建一个所有元素为一的矩阵
# 创建一个3x3的全一矩阵
one_matrix = np.ones((3, 3), dtype=np.uint8)
print("One Matrix:\n", one_matrix)
创建一个单位矩阵
# 创建一个3x3的单位矩阵
eye_matrix = np.eye(3, dtype=np.uint8)
print("Eye Matrix:\n", eye_matrix)
使用OpenCV中的函数和方法来创建和操作Mat
对象。可以根据需要组合这些方法来实现复杂的图像和矩阵操作任务。
2、操作Mat
对象
获取指定列范围的子矩阵
# 创建一个4x4的随机矩阵
matrix = np.random.randint(0, 256, (4, 4), dtype=np.uint8)
print("Original Matrix:\n", matrix)
# 获取第1到第3列(不包括第3列)的子矩阵
col_sub_matrix = matrix[:, 1:3]
print("Column Range Matrix:\n", col_sub_matrix)
获取指定行范围的子矩阵
# 获取第1到第3行(不包括第3行)的子矩阵
row_sub_matrix = matrix[1:3, :]
print("Row Range Matrix:\n", row_sub_matrix)
表示一个范围(在此例中用于创建子矩阵)
# 表示从第1到第3列(不包括第3列)的范围
col_range = slice(1, 3)
print("Column Range:\n", matrix[:, col_range])
# 表示从第1到第3行(不包括第3行)的范围
row_range = slice(1, 3)
print("Row Range:\n", matrix[row_range, :])
三、矩阵算术运算
在OpenCV中,Mat
对象支持基本的算术运算,这些运算可以用来对矩阵进行加法、减法、乘法和除法操作。下面分别介绍这些操作符的重载及其使用示例。
矩阵算术运算 | |||
+ (加法) | - (减法) | * (乘法) | / (除法) |
对两个矩阵进行元素逐个相加 | 对两个矩阵进行元素逐个相减 | 对两个矩阵进行元素逐个相乘 | 对两个矩阵进行元素逐个相除 |
矩阵加法
import cv2
import numpy as np
# 创建两个矩阵
matrix1 = np.array([[1, 2], [3, 4]], dtype=np.uint8)
matrix2 = np.array([[5, 6], [7, 8]], dtype=np.uint8)
# 矩阵加法
result_add = cv2.add(matrix1, matrix2)
print("Addition Result:\n", result_add)
矩阵减法
# 矩阵减法
result_sub = cv2.subtract(matrix1, matrix2)
print("Subtraction Result:\n", result_sub)
矩阵乘法
# 矩阵乘法(逐元素相乘)
result_mul = cv2.multiply(matrix1, matrix2)
print("Multiplication Result:\n", result_mul)
矩阵除法
# 矩阵除法(逐元素相除)
result_div = cv2.divide(matrix1, matrix2)
print("Division Result:\n", result_div)
通过这些示例代码,可以看到如何使用OpenCV中的操作符重载来对Mat
对象进行基本的算术运算。这些运算在图像处理和矩阵计算中非常常用,可以用于各种图像增强、滤波和特征提取任务。
四、数学运算
在OpenCV中,Mat
对象提供了丰富的数学运算功能,可以方便地对矩阵进行各种统计和算术运算。下面介绍一些常用的数学运算函数及其使用示例。
数学运算 | ||
mean | meanStdDev | sum |
计算矩阵的均值 | 计算矩阵的均值和标准差 | 计算矩阵元素的和 |
minMaxLoc | countNonZero | norm |
找到矩阵中的最小值和最大值及其位置 | 计算矩阵中非零元素的个数 | 计算矩阵的范数(如L2范数) |
计算均值 (mean
)
import cv2
import numpy as np
# 创建一个矩阵
matrix = np.array([[1, 2], [3, 4]], dtype=np.uint8)
# 计算矩阵的均值
mean_val = cv2.mean(matrix)
print("Mean Value:", mean_val)
计算均值和标准差 (meanStdDev
)
# 计算矩阵的均值和标准差
mean_val, stddev_val = cv2.meanStdDev(matrix)
print("Mean Value:", mean_val)
print("Standard Deviation:", stddev_val)
计算元素和 (sum
)
# 计算矩阵元素的和
sum_val = cv2.sumElems(matrix)
print("Sum of Elements:", sum_val)
找到最小值和最大值及其位置 (minMaxLoc
)
# 找到矩阵中的最小值和最大值及其位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(matrix)
print("Minimum Value:", min_val, "at", min_loc)
print("Maximum Value:", max_val, "at", max_loc)
计算非零元素的个数 (countNonZero
)
# 计算矩阵中非零元素的个数
nonzero_count = cv2.countNonZero(matrix)
print("Number of Non-Zero Elements:", nonzero_count)
计算矩阵的范数 (norm
)
# 计算矩阵的L2范数
norm_val = cv2.norm(matrix, cv2.NORM_L2)
print("L2 Norm of the Matrix:", norm_val)
通过这些示例代码,可以了解如何使用OpenCV中的这些数学运算函数来对Mat
对象进行各种统计和算术运算。这些函数在图像处理、特征提取和数据分析中非常有用。
五、矩阵计算函数
在OpenCV中,Mat
对象提供了丰富的矩阵计算功能,这些功能可以用于图像处理、机器学习、计算机视觉等领域。下面是一些常用的矩阵计算函数及其使用示例。
矩阵计算函数 | ||||
normalize | transpose | invert | flip | rotate |
归一化矩阵 | 转置矩阵 | 求矩阵的逆 | 翻转矩阵 | 旋转矩阵 |
determinant | trace | eigen | calcCovarMatrix | solve |
求矩阵的行列式 | 求矩阵的迹 | 求矩阵的特征值和特征向量 | 计算协方差矩阵 | 求解线性方程组 |
solveCubic | solvePoly | SVDcompute | max | min |
求解三次方程 | 求解多项式方程 | 奇异值分解 | 求矩阵元素的最大值 | 求矩阵元素的最小值 |
compare | repeat | PSNR | cross | dot |
比较矩阵 | 重复矩阵 | 峰值信噪比 | 向量的叉乘 | 向量的点乘 |
归一化矩阵 (normalize
)
import cv2
import numpy as np
# 创建一个矩阵
matrix = np.array([[1, 2], [3, 4]], dtype=np.float32)
# 归一化矩阵
normalized_matrix = cv2.normalize(matrix, None, 0, 1, cv2.NORM_MINMAX)
print("Normalized Matrix:\n", normalized_matrix)
转置矩阵 (transpose
)
# 转置矩阵
transposed_matrix = cv2.transpose(matrix)
print("Transposed Matrix:\n", transposed_matrix)
求矩阵的逆 (invert
)
# 创建一个可逆矩阵
invertible_matrix = np.array([[1, 2], [3, 4]], dtype=np.float32)
# 求矩阵的逆
inverse_matrix = cv2.invert(invertible_matrix)[1]
print("Inverse Matrix:\n", inverse_matrix)
翻转矩阵 (flip
)
# 翻转矩阵(沿Y轴翻转)
flipped_matrix = cv2.flip(matrix, 1)
print("Flipped Matrix:\n", flipped_matrix)
旋转矩阵 (rotate
)
# 翻转矩阵(沿Y轴翻转)
flipped_matrix = cv2.flip(matrix, 1)
print("Flipped Matrix:\n", flipped_matrix)
求矩阵的行列式 (determinant
)
# 求矩阵的行列式
determinant_val = cv2.determinant(invertible_matrix)
print("Determinant Value:", determinant_val)
求矩阵的迹 (trace
)
# 求矩阵的迹
trace_val = cv2.trace(matrix)[0]
print("Trace Value:", trace_val)
求矩阵的特征值和特征向量 (eigen
)
# 求矩阵的特征值和特征向量
eig_vals, eig_vecs = cv2.eigen(invertible_matrix)
print("Eigenvalues:\n", eig_vals)
print("Eigenvectors:\n", eig_vecs)
这些示例展示了如何使用OpenCV中的矩阵计算函数来处理Mat
对象。根据具体的应用需求,可以组合这些函数来实现复杂的矩阵运算和图像处理任务。
六、代数运算
在OpenCV中,代数运算函数用于对矩阵进行基本的代数运算。这些函数可以方便地实现加法、减法、乘法、除法等操作。下面介绍这些代数运算函数及其使用示例。
代数运算函数 | |||
add | subtract | multiply | divide |
矩阵加法 | 矩阵减法 | 矩阵乘法(逐元素相乘) | 矩阵除法(逐元素相除) |
absdiff | scaleAdd | addWeighted | |
计算两个矩阵的绝对差 | 按比例放大并相加 | 按权重相加 |
矩阵加法 (add
)
import cv2
import numpy as np
# 创建两个矩阵
matrix1 = np.array([[1, 2], [3, 4]], dtype=np.uint8)
matrix2 = np.array([[5, 6], [7, 8]], dtype=np.uint8)
# 矩阵加法
result_add = cv2.add(matrix1, matrix2)
print("Addition Result:\n", result_add)
矩阵减法 (subtract
)
import cv2
import numpy as np
# 创建两个矩阵
matrix1 = np.array([[1, 2], [3, 4]], dtype=np.uint8)
matrix2 = np.array([[5, 6], [7, 8]], dtype=np.uint8)
# 矩阵加法
result_add = cv2.add(matrix1, matrix2)
print("Addition Result:\n", result_add)
矩阵乘法 (multiply
)
# 矩阵乘法(逐元素相乘)
result_mul = cv2.multiply(matrix1, matrix2)
print("Multiplication Result:\n", result_mul)
矩阵除法 (divide
)
# 矩阵除法(逐元素相除)
result_div = cv2.divide(matrix1, matrix2)
print("Division Result:\n", result_div)
计算绝对差 (absdiff
)
# 计算两个矩阵的绝对差
result_absdiff = cv2.absdiff(matrix1, matrix2)
print("Absolute Difference Result:\n", result_absdiff)
按比例放大并相加 (scaleAdd
)
# 按比例放大并相加
scale = 2.5
result_scaleAdd = cv2.scaleAdd(matrix1, scale, matrix2)
print("Scale Add Result:\n", result_scaleAdd)
按权重相加 (addWeighted
)
# 按权重相加
alpha = 0.7
beta = 0.3
gamma = 0 # 可选偏移量
result_addWeighted = cv2.addWeighted(matrix1, alpha, matrix2, beta, gamma)
print("Weighted Addition Result:\n", result_addWeighted)
这些示例展示了如何使用OpenCV中的代数运算函数来对Mat
对象进行各种基本的代数运算。根据具体的应用需求,可以组合这些函数来实现复杂的图像处理和矩阵计算任务。
七、逻辑运算
在OpenCV中,逻辑运算函数用于对图像或矩阵进行像素级的逻辑操作。这些操作包括与(AND)、或(OR)、非(NOT)、异或(XOR)等。下面是这些逻辑运算函数的介绍及其使用示例。
逻辑运算函数 | |||
bitwise_and | bitwise_or | bitwise_not | bitwise_xor |
对两个矩阵进行按位与操作 | 对两个矩阵进行按位或操作 | 对矩阵进行按位取反操作 | 对两个矩阵进行按位异或操作 |
按位与操作 (bitwise_and
)
import cv2
import numpy as np
# 创建两个矩阵
matrix1 = np.array([[1, 2], [3, 4]], dtype=np.uint8)
matrix2 = np.array([[5, 6], [7, 8]], dtype=np.uint8)
# 按位与操作
result_and = cv2.bitwise_and(matrix1, matrix2)
print("Bitwise AND Result:\n", result_and)
按位或操作 (bitwise_or
)
# 按位或操作
result_or = cv2.bitwise_or(matrix1, matrix2)
print("Bitwise OR Result:\n", result_or)
按位取反操作 (bitwise_not
)
# 按位取反操作
result_not = cv2.bitwise_not(matrix1)
print("Bitwise NOT Result:\n", result_not)
按位异或操作 (bitwise_xor
)
# 按位异或操作
result_xor = cv2.bitwise_xor(matrix1, matrix2)
print("Bitwise XOR Result:\n", result_xor)
这些示例展示了如何使用OpenCV中的逻辑运算函数来对Mat
对象进行各种按位逻辑操作。这些操作在图像处理和计算机视觉中非常有用,特别是在掩模操作、图像合成和图像增强等应用中。根据具体的需求,可以灵活组合这些函数来实现复杂的图像处理任务。
八、图像拼接
在OpenCV中,图像拼接是指将多幅图像合并成一幅图像的过程。OpenCV提供了几种常用的函数和类来实现图像拼接。下面介绍这些拼接相关的函数及其使用示例。
图像拼接函数 | ||
hconcat | vconcat | Stitcher |
水平拼接图像 | 垂直拼接图像 | 全景图像拼接类 |
水平拼接图像 (hconcat
)
import cv2
import numpy as np
# 创建两个示例图像
image1 = np.full((100, 200, 3), 255, dtype=np.uint8) # 白色图像
image2 = np.full((100, 200, 3), 0, dtype=np.uint8) # 黑色图像
# 水平拼接图像
result_hconcat = cv2.hconcat([image1, image2])
cv2.imshow('Horizontal Concatenation', result_hconcat)
cv2.waitKey(0)
cv2.destroyAllWindows()
垂直拼接图像 (vconcat
)
# 垂直拼接图像
result_vconcat = cv2.vconcat([image1, image2])
cv2.imshow('Vertical Concatenation', result_vconcat)
cv2.waitKey(0)
cv2.destroyAllWindows()
全景图像拼接 (Stitcher
)
# 读取待拼接的图像
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
# 创建Stitcher对象并进行拼接
stitcher = cv2.Stitcher_create()
status, stitched = stitcher.stitch([image1, image2])
if status == cv2.Stitcher_OK:
cv2.imshow('Stitched Image', stitched)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("拼接失败")
这些示例展示了如何使用OpenCV中的拼接函数来实现图像的水平拼接、垂直拼接以及全景图像拼接。这些函数和类在图像处理、计算机视觉以及图像分析中非常有用,可以根据具体需求灵活应用。
九、颜色通道及数据格式
在OpenCV中,颜色通道及数据格式的转换和操作是图像处理的重要部分。下面介绍这些相关的函数及其使用示例。
颜色通道及数据格式 | |||
cvtColor | convertTo | split | merge |
转换图像的颜色空间 | 转换图像的数据类型 | 分离图像的颜色通道 | 合并图像的颜色通道 |
extractChannel | insertChannel | applyColorMap | |
提取单个颜色通道 | 插入单个颜色通道 | 应用颜色映射 |
转换图像的颜色空间 (cvtColor
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image', gray_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
转换图像的数据类型 (convertTo
)
# 转换数据类型为float32
float_image = np.float32(image)
converted_image = float_image / 255.0
cv2.imshow('Converted Image', converted_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
分离和合并颜色通道 (split
和 merge
)
# 分离颜色通道
b, g, r = cv2.split(image)
# 合并颜色通道
merged_image = cv2.merge([b, g, r])
cv2.imshow('Merged Image', merged_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
提取和插入颜色通道 (extractChannel
和 insertChannel
)
# 提取蓝色通道
blue_channel = cv2.extractChannel(image, 0)
cv2.imshow('Blue Channel', blue_channel)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 插入通道
new_image = cv2.insertChannel(blue_channel, image, 1)
cv2.imshow('Image with Inserted Channel', new_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
应用颜色映射 (applyColorMap
)
# 应用颜色映射
color_mapped_image = cv2.applyColorMap(gray_image, cv2.COLORMAP_JET)
cv2.imshow('Color Mapped Image', color_mapped_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的函数来处理图像的颜色通道和数据格式。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理任务。
十、图像复制函数
在OpenCV中,图像复制是基本的操作,可以通过 clone
和 copyTo
函数来实现。下面介绍这些函数及其使用示例。
图像复制函数 | |
clone | copyTo |
创建一个图像的深拷贝 | 将图像数据复制到另一个矩阵,可以选择性地使用掩码 |
使用 clone
进行深拷贝
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 使用 clone 进行深拷贝
cloned_image = image.clone()
# 显示原图和拷贝图
cv2.imshow('Original Image', image)
cv2.imshow('Cloned Image', cloned_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
使用 copyTo
进行复制
# 创建一个与原图像相同大小的空图像
copy_image = np.zeros_like(image)
# 直接复制图像
image.copyTo(copy_image)
# 显示原图和拷贝图
cv2.imshow('Original Image', image)
cv2.imshow('Copy Image', copy_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
使用 copyTo
和掩码进行复制
# 创建一个掩码
mask = np.zeros(image.shape[:2], dtype=np.uint8)
mask[50:150, 50:150] = 255 # 在掩码上定义一个区域
# 复制图像中的特定区域
masked_copy = np.zeros_like(image)
image.copyTo(masked_copy, mask=mask)
# 显示原图、掩码和掩码复制图
cv2.imshow('Original Image', image)
cv2.imshow('Mask', mask)
cv2.imshow('Masked Copy Image', masked_copy)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的 clone
和 copyTo
函数来复制图像。根据具体的需求,可以选择直接复制整个图像或使用掩码复制特定区域的图像数据。这些操作在图像处理、图像增强和计算机视觉应用中非常有用。
十一、图像变化与增强
在OpenCV中,图像变换与增强是图像处理的重要组成部分。下面介绍一些常用的图像变换与增强函数及其使用示例。
图像变换与增强函数 | ||||
convertScaleAbs | log | exp | pow | sqrt |
缩放、计算绝对值并转换为8位 | 计算每个元素的自然对数 | 计算每个元素的指数 | 计算每个元素的幂 | 计算每个元素的平方根 |
equalizeHist | CLAHE | detailEnhance | illuminationChange | |
直方图均衡化 | 自适应直方图均衡化(对比度受限的自适应直方图均衡化) | 细节增强 | 改变光照条件 |
缩放、计算绝对值并转换为8位 (convertScaleAbs
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 缩放、计算绝对值并转换为8位
scaled_image = cv2.convertScaleAbs(image, alpha=1.5, beta=0)
cv2.imshow('Scaled Image', scaled_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
计算自然对数 (log
)
# 计算每个元素的自然对数
log_image = cv2.log(np.float32(image) + 1) # 加1防止对数的负无穷
cv2.imshow('Log Image', cv2.convertScaleAbs(log_image))
cv2.waitKey(0)
cv2.destroyAllWindows()
计算指数 (exp
)
# 计算每个元素的指数
exp_image = cv2.exp(np.float32(image))
cv2.imshow('Exp Image', cv2.convertScaleAbs(exp_image))
cv2.waitKey(0)
cv2.destroyAllWindows()
计算幂 (pow
)
# 计算每个元素的幂
pow_image = cv2.pow(np.float32(image), 2)
cv2.imshow('Pow Image', cv2.convertScaleAbs(pow_image))
cv2.waitKey(0)
cv2.destroyAllWindows()
计算平方根 (sqrt
)
# 计算每个元素的平方根
sqrt_image = cv2.sqrt(np.float32(image))
cv2.imshow('Sqrt Image', cv2.convertScaleAbs(sqrt_image))
cv2.waitKey(0)
cv2.destroyAllWindows()
直方图均衡化 (equalizeHist
)
# 直方图均衡化
equalized_image = cv2.equalizeHist(image)
cv2.imshow('Equalized Image', equalized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
自适应直方图均衡化 (CLAHE
)
# 创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 应用CLAHE
clahe_image = clahe.apply(image)
cv2.imshow('CLAHE Image', clahe_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
细节增强 (detailEnhance
)
# 细节增强
detail_image = cv2.detailEnhance(image)
cv2.imshow('Detail Enhanced Image', detail_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
改变光照条件 (illuminationChange
)
# 改变光照条件
illum_image = cv2.illuminationChange(image, mask=np.ones(image.shape, dtype=np.uint8), alpha=0.5, beta=2)
cv2.imshow('Illumination Changed Image', illum_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的图像变换与增强函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理和增强任务。
十二、图像平滑滤波
在OpenCV中,图像平滑滤波(或称为图像去噪)是一种非常常见的操作,通常用于去除图像中的噪声,使图像变得更加平滑。OpenCV提供了多种滤波函数,下面介绍这些滤波函数及其使用示例。
图像平滑滤波函数 | ||||
blur | boxFilter | sqBoxFilter | medianBlur | GaussianBlur |
均值滤波 | 方框滤波 | 平方方框滤波 | 中值滤波 | 高斯滤波 |
bilateralFilter | filter2D | sepFilter2D | edgePreservingFilter | fastNlMeansDenoising |
双边滤波 | 自定义滤波器 | 分离滤波器 | 边缘保留滤波 | 快速非局部均值去噪 |
fastNlMeansDenoisingColored | textureFlattening | getGaussianKernel | ||
彩色图像的快速非局部均值去噪 | 纹理平滑 | 获取高斯核 |
均值滤波 (blur
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 均值滤波
blurred_image = cv2.blur(image, (5, 5))
cv2.imshow('Blurred Image', blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
方框滤波 (boxFilter
)
# 方框滤波
box_filtered_image = cv2.boxFilter(image, -1, (5, 5))
cv2.imshow('Box Filtered Image', box_filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
中值滤波 (medianBlur
)
# 中值滤波
median_blurred_image = cv2.medianBlur(image, 5)
cv2.imshow('Median Blurred Image', median_blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
高斯滤波 (GaussianBlur
)
# 高斯滤波
gaussian_blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
cv2.imshow('Gaussian Blurred Image', gaussian_blurred_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
双边滤波 (bilateralFilter
)
# 双边滤波
bilateral_filtered_image = cv2.bilateralFilter(image, 9, 75, 75)
cv2.imshow('Bilateral Filtered Image', bilateral_filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
自定义滤波器 (filter2D
)
# 自定义滤波器
kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
custom_filtered_image = cv2.filter2D(image, -1, kernel)
cv2.imshow('Custom Filtered Image', custom_filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
边缘保留滤波 (edgePreservingFilter
)
# 边缘保留滤波
edge_preserved_image = cv2.edgePreservingFilter(image, flags=1, sigma_s=60, sigma_r=0.4)
cv2.imshow('Edge Preserved Image', edge_preserved_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
快速非局部均值去噪 (fastNlMeansDenoising
)
# 快速非局部均值去噪
denoised_image = cv2.fastNlMeansDenoising(image, None, 30, 7, 21)
cv2.imshow('Denoised Image', denoised_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
彩色图像的快速非局部均值去噪 (fastNlMeansDenoisingColored
)
# 彩色图像的快速非局部均值去噪
denoised_colored_image = cv2.fastNlMeansDenoisingColored(image, None, 30, 30, 7, 21)
cv2.imshow('Denoised Colored Image', denoised_colored_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
获取高斯核 (getGaussianKernel
)
# 获取高斯核
gaussian_kernel = cv2.getGaussianKernel(5, 1.5)
print("Gaussian Kernel:\n", gaussian_kernel)
这些示例展示了如何使用OpenCV中的各种平滑滤波函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像平滑和去噪任务。
十三、锐化与边缘检测
在OpenCV中,锐化与边缘检测是图像处理的重要任务之一,用于检测图像中的边缘和细节。下面介绍一些常用的锐化与边缘检测函数及其使用示例。
锐化与边缘检测函数 | |||
Sobel | Scharr | Laplacian | spatialGradient |
Sobel算子,用于计算图像的梯度 | Scharr算子,Sobel算子的增强版本 | Laplacian算子,用于计算图像的拉普拉斯 | 计算图像的空间梯度 |
Canny | getGaborKernel | cartToPolar | polarToCart |
Canny边缘检测器 | 获取Gabor核 | 将笛卡尔坐标转换为极坐标 | 将极坐标转换为笛卡尔坐标 |
Sobel算子 (Sobel
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 使用Sobel算子检测边缘
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
sobel_combined = cv2.magnitude(sobel_x, sobel_y)
cv2.imshow('Sobel X', sobel_x)
cv2.imshow('Sobel Y', sobel_y)
cv2.imshow('Sobel Combined', sobel_combined)
cv2.waitKey(0)
cv2.destroyAllWindows()
Scharr算子 (Scharr
)
# 使用Scharr算子检测边缘
scharr_x = cv2.Scharr(image, cv2.CV_64F, 1, 0)
scharr_y = cv2.Scharr(image, cv2.CV_64F, 0, 1)
scharr_combined = cv2.magnitude(scharr_x, scharr_y)
cv2.imshow('Scharr X', scharr_x)
cv2.imshow('Scharr Y', scharr_y)
cv2.imshow('Scharr Combined', scharr_combined)
cv2.waitKey(0)
cv2.destroyAllWindows()
Laplacian算子 (Laplacian
)
# 使用Laplacian算子检测边缘
laplacian = cv2.Laplacian(image, cv2.CV_64F)
cv2.imshow('Laplacian', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
Canny边缘检测器 (Canny
)
# 使用Canny边缘检测器
canny_edges = cv2.Canny(image, 100, 200)
cv2.imshow('Canny Edges', canny_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
获取Gabor核 (getGaborKernel
)
# 获取Gabor核
gabor_kernel = cv2.getGaborKernel((21, 21), 5, np.pi/4, 10, 0.5, 0, ktype=cv2.CV_32F)
filtered_image = cv2.filter2D(image, cv2.CV_8UC3, gabor_kernel)
cv2.imshow('Gabor Kernel', gabor_kernel)
cv2.imshow('Filtered Image', filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
笛卡尔坐标与极坐标转换 (cartToPolar
和 polarToCart
)
# 计算图像的梯度
grad_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
# 将梯度从笛卡尔坐标转换为极坐标
magnitude, angle = cv2.cartToPolar(grad_x, grad_y)
# 将梯度从极坐标转换为笛卡尔坐标
x, y = cv2.polarToCart(magnitude, angle)
cv2.imshow('Magnitude', magnitude)
cv2.imshow('Angle', angle)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的各种锐化与边缘检测函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像锐化和边缘检测任务。
十四、数学形态学
在OpenCV中,数学形态学是图像处理的重要工具,用于图像的形态变换。常见的操作包括膨胀、腐蚀、开运算、闭运算等。下面介绍这些相关函数及其使用示例。
数学形态学函数 | |||
getStructuringElement | dilate | erode | morphologyEx |
获取结构元素(核) | 膨胀操作 | 腐蚀操作 | 高级形态学变换(开运算、闭运算等) |
获取结构元素 (getStructuringElement
)
import cv2
import numpy as np
# 获取一个3x3的矩形结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
print("Structuring Element:\n", kernel)
膨胀操作 (dilate
)
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 获取结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# 进行膨胀操作
dilated_image = cv2.dilate(image, kernel)
cv2.imshow('Dilated Image', dilated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
腐蚀操作 (erode
)
# 进行腐蚀操作
eroded_image = cv2.erode(image, kernel)
cv2.imshow('Eroded Image', eroded_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
高级形态学变换 (morphologyEx
)
# 开运算(先腐蚀后膨胀)
opened_image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
cv2.imshow('Opened Image', opened_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 闭运算(先膨胀后腐蚀)
closed_image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Closed Image', closed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 梯度运算(膨胀减去腐蚀)
gradient_image = cv2.morphologyEx(image, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('Gradient Image', gradient_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 顶帽运算(原图像减去开运算)
tophat_image = cv2.morphologyEx(image, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('Top Hat Image', tophat_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 黑帽运算(闭运算减去原图像)
blackhat_image = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('Black Hat Image', blackhat_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的数学形态学函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像形态变换和处理任务。
十五、图像分割
在OpenCV中,图像分割是将图像分割成不同区域或对象的过程,常用于对象检测、识别和图像分析。下面介绍一些常用的图像分割函数及其使用示例。
图像分割函数 | ||||
threshold | adaptiveThreshold | inRange | watershed | floodFill |
简单阈值分割 | 自适应阈值分割 | 颜色范围分割 | 分水岭算法 | 泛洪填充 |
grabCut | distanceTransform | MSER | pyrMeanShiftFiltering | |
GrabCut算法 | 距离变换 | 最大稳定极值区域检测 | 均值漂移滤波 |
简单阈值分割 (threshold
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 应用简单阈值分割
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('Binary Image', binary_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
自适应阈值分割 (adaptiveThreshold
)
# 应用自适应阈值分割
adaptive_thresh = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
cv2.imshow('Adaptive Threshold Image', adaptive_thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
颜色范围分割 (inRange
)
# 读取彩色图像
color_image = cv2.imread('path_to_image.jpg')
# 定义颜色范围
lower_bound = np.array([0, 120, 70])
upper_bound = np.array([10, 255, 255])
# 转换到HSV颜色空间
hsv_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2HSV)
# 应用颜色范围分割
mask = cv2.inRange(hsv_image, lower_bound, upper_bound)
cv2.imshow('Mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
分水岭算法 (watershed
)
# 读取图像并转换为灰度图
gray = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 确定背景区域
kernel = np.ones((3, 3), np.uint8)
sure_bg = cv2.dilate(binary, kernel, iterations=3)
# 确定前景区域
dist_transform = cv2.distanceTransform(binary, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)
# 确定未知区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
# 标记连通组件
_, markers = cv2.connectedComponents(sure_fg)
# 为确保背景为1,增加1
markers = markers + 1
# 将未知区域标记为0
markers[unknown == 255] = 0
# 应用分水岭算法
markers = cv2.watershed(color_image, markers)
color_image[markers == -1] = [0, 0, 255]
cv2.imshow('Watershed', color_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
泛洪填充 (floodFill
)
# 应用泛洪填充
flood_filled = color_image.copy()
h, w = flood_filled.shape[:2]
mask = np.zeros((h + 2, w + 2), np.uint8)
cv2.floodFill(flood_filled, mask, (0, 0), (255, 0, 0))
cv2.imshow('Flood Fill', flood_filled)
cv2.waitKey(0)
cv2.destroyAllWindows()
GrabCut算法 (grabCut
)
# 初始化掩码
mask = np.zeros(color_image.shape[:2], np.uint8)
# 定义矩形
rect = (50, 50, 450, 290)
# 定义模型
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
# 应用GrabCut算法
cv2.grabCut(color_image, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
grabcut_image = color_image * mask2[:, :, np.newaxis]
cv2.imshow('GrabCut', grabcut_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
距离变换 (distanceTransform
)
# 应用距离变换
dist_transform = cv2.distanceTransform(binary, cv2.DIST_L2, 5)
cv2.imshow('Distance Transform', dist_transform)
cv2.waitKey(0)
cv2.destroyAllWindows()
最大稳定极值区域检测 (MSER
)
# 创建MSER对象
mser = cv2.MSER_create()
# 检测MSER区域
regions, _ = mser.detectRegions(gray)
# 绘制检测到的区域
output = color_image.copy()
for p in regions:
hull = cv2.convexHull(p.reshape(-1, 1, 2))
cv2.polylines(output, [hull], 1, (0, 255, 0))
cv2.imshow('MSER', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
均值漂移滤波 (pyrMeanShiftFiltering
)
# 应用均值漂移滤波
mean_shift_image = cv2.pyrMeanShiftFiltering(color_image, 21, 51)
cv2.imshow('Mean Shift Filtering', mean_shift_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的各种图像分割函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像分割任务。
十六、连通域
在OpenCV中,连通域分析是图像处理中的一个重要步骤,用于检测和标记图像中的连通区域。主要有两个函数:connectedComponents
和 connectedComponentsWithStats
。下面介绍这些函数及其使用示例。
连通域分析函数 | |
connectedComponents | connectedComponentsWithStats |
计算连通组件 | 计算连通组件并返回统计信息 |
计算连通组件 (connectedComponents
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 应用阈值处理
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 计算连通组件
num_labels, labels = cv2.connectedComponents(binary_image)
# 显示结果
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# 转换到BGR颜色空间
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
# 设置背景为黑色
labeled_img[label_hue == 0] = 0
cv2.imshow('Connected Components', labeled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
计算连通组件并返回统计信息 (connectedComponentsWithStats
)
# 计算连通组件及统计信息
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_image)
# 输出每个连通组件的统计信息
for i in range(num_labels):
print(f"Component {i}:")
print(f" Bounding box: {stats[i, cv2.CC_STAT_LEFT]}, {stats[i, cv2.CC_STAT_TOP]}, "
f"{stats[i, cv2.CC_STAT_WIDTH]}, {stats[i, cv2.CC_STAT_HEIGHT]}")
print(f" Area: {stats[i, cv2.CC_STAT_AREA]}")
print(f" Centroid: {centroids[i]}")
# 显示结果
label_hue = np.uint8(179 * labels / np.max(labels))
blank_ch = 255 * np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
# 转换到BGR颜色空间
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
# 设置背景为黑色
labeled_img[label_hue == 0] = 0
cv2.imshow('Connected Components with Stats', labeled_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
connectedComponents
:此函数返回连通组件的数量和每个像素所属的标签。connectedComponentsWithStats
:此函数除了返回标签外,还返回每个连通组件的统计信息(如边界框、面积)和重心。
这些示例展示了如何使用OpenCV中的连通域分析函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的连通域检测和分析任务。
十七、图像轮廓
在OpenCV中,图像轮廓检测是图像处理和分析中的一个重要步骤。下面介绍一些常用的图像轮廓检测和处理函数及其使用示例。
图像轮廓 | |||
findContours | drawContours | arcLength | contourArea |
检测图像中的轮廓 | 绘制图像中的轮廓 | 计算轮廓的周长 | 计算轮廓的面积 |
minAreaRect | boundingRect | minEnclosingCircle | minEnclosingTriangle |
找到面积最小的旋转矩形 | 计算包围轮廓的矩形 | 计算包围轮廓的最小圆 | 计算包围轮廓的最小三角形 |
approxPolyDP | convexHull | convexityDefects | fitLine |
使用多边形逼近曲线或轮廓 | 计算轮廓的凸包 | 计算轮廓的凸缺陷 | 用一条直线拟合轮廓 |
fitEllipse | fitEllipseAMS | fitEllipseDirect | fillPoly |
用一个椭圆拟合轮廓 | 用AMS方法拟合椭圆 | 用直接方法拟合椭圆 | 填充多边形 |
fillConvexPoly | pointPolygonTest | isContourConvex | intersectConvexConvex |
填充凸多边形 | 测试点与轮廓的相对位置 | 测试轮廓是否是凸的 | 计算两个凸多边形的交集 |
检测并绘制轮廓 (findContours
和 drawContours
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用阈值处理
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 检测轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
cv2.imshow('Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
计算轮廓的周长和面积 (arcLength
和 contourArea
)
for contour in contours:
perimeter = cv2.arcLength(contour, True)
area = cv2.contourArea(contour)
print(f"Perimeter: {perimeter}, Area: {area}")
计算包围轮廓的最小矩形和最小圆 (minAreaRect
和 minEnclosingCircle
)
for contour in contours:
# 最小旋转矩形
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
# 最小包围圆
(x, y), radius = cv2.minEnclosingCircle(contour)
center = (int(x), int(y))
radius = int(radius)
cv2.circle(image, center, radius, (255, 0, 0), 2)
cv2.imshow('Min Area Rect and Enclosing Circle', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
多边形逼近 (approxPolyDP
)
for contour in contours:
epsilon = 0.02 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
cv2.drawContours(image, [approx], -1, (0, 255, 255), 2)
cv2.imshow('Approx Poly DP', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
计算轮廓的凸包 (convexHull
)
for contour in contours:
hull = cv2.convexHull(contour)
cv2.drawContours(image, [hull], -1, (255, 255, 0), 2)
cv2.imshow('Convex Hull', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
用椭圆拟合轮廓 (fitEllipse
)
for contour in contours:
if len(contour) >= 5: # 拟合椭圆要求至少有5个点
ellipse = cv2.fitEllipse(contour)
cv2.ellipse(image, ellipse, (0, 255, 255), 2)
cv2.imshow('Fit Ellipse', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
测试点与轮廓的相对位置 (pointPolygonTest
)
point = (50, 50)
for contour in contours:
dist = cv2.pointPolygonTest(contour, point, True)
print(f"Distance from point {point} to contour: {dist}")
这些示例展示了如何使用OpenCV中的各种轮廓检测和处理函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像轮廓检测和分析任务。
十八、图像大小
在OpenCV中,调整图像大小是一个常见的操作,主要通过以下几个函数实现:pyrDown
、pyrUp
、resize
、reduce
和 reshape
。下面介绍这些函数及其使用示例。
图像大小调整函数 | ||||
pyrDown | pyrUp | resize | reduce | reshape |
降低图像分辨率(降采样) | 提高图像分辨率(升采样) | 调整图像大小 | 沿某个轴缩小图像 | 改变图像的形状 |
降采样 (pyrDown
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 降采样
pyr_down_image = cv2.pyrDown(image)
cv2.imshow('PyrDown Image', pyr_down_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
升采样 (pyrUp
)
# 升采样
pyr_up_image = cv2.pyrUp(image)
cv2.imshow('PyrUp Image', pyr_up_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
调整图像大小 (resize
)
# 调整图像大小
resized_image = cv2.resize(image, (300, 300)) # 指定新的宽和高
cv2.imshow('Resized Image', resized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 按比例缩放
resized_image_aspect = cv2.resize(image, None, fx=0.5, fy=0.5) # 宽和高分别缩小一半
cv2.imshow('Resized Image with Aspect Ratio', resized_image_aspect)
cv2.waitKey(0)
cv2.destroyAllWindows()
沿某个轴缩小图像 (reduce
)
# 沿列方向缩小图像(求和)
reduced_image = cv2.reduce(image, dim=1, rtype=cv2.REDUCE_SUM)
cv2.imshow('Reduced Image', reduced_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
改变图像的形状 (reshape
)
# 改变图像的形状
reshaped_image = image.reshape((-1, 3)) # 改为一行三通道的图像
print("Reshaped Image Shape:", reshaped_image.shape)
这些示例展示了如何使用OpenCV中的各种函数来调整图像的大小和形状。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理任务。
十九、模板匹配
在OpenCV中,模板匹配是图像处理和计算机视觉中的一种重要技术,用于在大图像中找到与模板图像匹配的区域。下面介绍一些常用的模板匹配函数及其使用示例。
模板匹配函数 | ||
getRectSubPix | matchTemplate | matchShapes |
从图像中提取矩形区域的子像素精度补偿 | 在图像中搜索和匹配模板 | 比较两个形状(轮廓)的相似度 |
从图像中提取矩形区域的子像素精度补偿 (getRectSubPix
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 定义中心和大小
center = (50, 50)
patch_size = (100, 100)
# 提取矩形区域
patch = cv2.getRectSubPix(image, patch_size, center)
cv2.imshow('Original Image', image)
cv2.imshow('Extracted Patch', patch)
cv2.waitKey(0)
cv2.destroyAllWindows()
在图像中搜索和匹配模板 (matchTemplate
)
# 读取图像和模板
image = cv2.imread('path_to_image.jpg', 0)
template = cv2.imread('path_to_template.jpg', 0)
# 进行模板匹配
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
# 获取最佳匹配位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# 绘制匹配结果
top_left = max_loc
h, w = template.shape
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(image, top_left, bottom_right, 255, 2)
cv2.imshow('Template Matched', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
比较两个形状(轮廓)的相似度 (matchShapes
)
# 读取图像并转换为灰度图
image1 = cv2.imread('path_to_image1.jpg', 0)
image2 = cv2.imread('path_to_image2.jpg', 0)
# 阈值化
_, binary1 = cv2.threshold(image1, 127, 255, cv2.THRESH_BINARY)
_, binary2 = cv2.threshold(image2, 127, 255, cv2.THRESH_BINARY)
# 提取轮廓
contours1, _ = cv2.findContours(binary1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours2, _ = cv2.findContours(binary2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 计算相似度
if contours1 and contours2:
similarity = cv2.matchShapes(contours1[0], contours2[0], cv2.CONTOURS_MATCH_I1, 0.0)
print(f'Shape similarity: {similarity}')
解释
getRectSubPix
:从图像中提取矩形区域的子像素精度补偿,适用于需要高精度提取的场景。matchTemplate
:在大图像中搜索和匹配模板,返回一个相似度图,可以进一步处理以找到最佳匹配位置。matchShapes
:比较两个形状(轮廓)的相似度,返回一个相似度值,值越小表示形状越相似。
这些示例展示了如何使用OpenCV中的各种模板匹配函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的模板匹配任务。
二十、图像矩
在OpenCV中,图像矩是图像的一个重要特征,用于描述图像的形状和分布。常用的图像矩函数包括 moments
和 HuMoments
。下面介绍这些函数及其使用示例。
图像矩函数 | |
moments | HuMoments |
计算图像或轮廓的矩 | 计算图像或轮廓的Hu不变矩 |
计算图像或轮廓的矩 (moments
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 应用阈值处理
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 计算轮廓
contours, _ = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 计算第一个轮廓的矩
if contours:
moments = cv2.moments(contours[0])
print("Moments:", moments)
计算图像或轮廓的Hu不变矩 (HuMoments
)
# 计算第一个轮廓的矩
if contours:
moments = cv2.moments(contours[0])
# 计算Hu不变矩
hu_moments = cv2.HuMoments(moments).flatten()
print("Hu Moments:", hu_moments)
解释
moments
:计算图像或轮廓的矩,返回一个包含多种矩(如零阶矩、一阶矩、二阶矩等)的字典。这些矩可以用来计算图像的质心、面积、惯性矩等。HuMoments
:根据普通矩计算Hu不变矩,返回7个不变矩。这些不变矩对图像的缩放、旋转和镜像变换保持不变,是一种强有力的形状特征。
使用示例
下面是一个综合的示例,展示了如何使用moments
和HuMoments
来计算图像或轮廓的矩和不变矩。
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 应用阈值处理
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
# 计算轮廓
contours, _ = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 计算第一个轮廓的矩和Hu不变矩
if contours:
contour = contours[0]
# 计算矩
moments = cv2.moments(contour)
print("Moments:", moments)
# 计算质心
cX = int(moments["m10"] / moments["m00"])
cY = int(moments["m01"] / moments["m00"])
print("Centroid:", (cX, cY))
# 计算Hu不变矩
hu_moments = cv2.HuMoments(moments).flatten()
print("Hu Moments:", hu_moments)
# 在图像上绘制轮廓和质心
image_color = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(image_color, [contour], -1, (0, 255, 0), 2)
cv2.circle(image_color, (cX, cY), 5, (0, 0, 255), -1)
cv2.imshow("Contour with Centroid", image_color)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的图像矩函数来处理图像,根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像特征提取和分析任务。
二一、查找表变换
在OpenCV中,查找表(LUT,Look-Up Table)变换是一种高效的像素值映射方法,用于对图像进行各种非线性变换。通过预先定义一个查找表,可以快速地将输入图像的像素值转换为输出图像的像素值。OpenCV提供了LUT
函数来实现这一功能。
查找表变换函数 | |
LUT | 使用查找表对图像进行变换 |
使用查找表对图像进行变换 (LUT
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 定义一个查找表,将像素值变换为其平方根的结果
lut = np.array([np.sqrt(i) * 16 for i in range(256)], dtype=np.uint8)
# 应用查找表变换
result_image = cv2.LUT(image, lut)
# 显示原图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('LUT Transformed Image', result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
- 定义查找表:在这个示例中,我们定义了一个查找表
lut
,将每个像素值映射到其平方根乘以16的值。np.sqrt(i) * 16
用于计算像素值的平方根并放大以增加对比度。 - 应用查找表变换:使用
cv2.LUT
函数将查找表应用于图像。这将图像中的每个像素值替换为查找表中对应的值。
实际应用
查找表变换在图像处理中的应用非常广泛,常用于以下场景:
- 伽马校正:调整图像的亮度和对比度。
- 颜色映射:将灰度图像映射到伪彩色图像。
- 非线性增强:对图像进行对数变换、指数变换等非线性增强。
伽马校正的示例
# 伽马校正的查找表
gamma = 2.2
lut = np.array([((i / 255.0) ** gamma) * 255 for i in range(256)], dtype=np.uint8)
# 应用查找表变换
gamma_corrected_image = cv2.LUT(image, lut)
# 显示伽马校正后的图像
cv2.imshow('Gamma Corrected Image', gamma_corrected_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在这个示例中,我们定义了一个用于伽马校正的查找表lut
,并将其应用于图像以实现伽马校正效果。
通过这些示例,可以看到如何使用OpenCV中的LUT
函数来实现各种查找表变换。根据具体的应用需求,可以灵活定义查找表并应用于图像处理任务。
二二、图像积分
在OpenCV中,图像积分是计算图像中某一矩形区域内所有像素值的总和。积分图像(也称为积分图)是一种加速某些图像处理操作的技术,如快速计算图像块的和。OpenCV提供了integral
函数来计算积分图像。
图像积分函数 | |
integral | 计算积分图像 |
计算图像的积分图像 (integral
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 计算积分图像
integral_image = cv2.integral(image)
# 显示原图像和积分图像
cv2.imshow('Original Image', image)
cv2.imshow('Integral Image', integral_image.astype(np.uint8)) # 显示时转换为uint8类型
cv2.waitKey(0)
cv2.destroyAllWindows()
# 打印积分图像
print("Integral Image:\n", integral_image)
解释
integral
函数:计算积分图像。积分图像中的每个元素表示原图像中从(0,0)到该位置的矩形区域内所有像素值的总和。- 显示积分图像:为了显示积分图像,我们将其转换为
uint8
类型,但要注意,积分图像中的值通常会大于255,所以在显示时会有信息损失。实际应用时,不需要进行这种转换。
应用场景
积分图像在许多图像处理任务中非常有用,特别是在需要快速计算图像块和的场景。以下是一些常见的应用场景:
- 快速图像块和计算:在任意大小的矩形区域内快速计算像素值的总和。
- 特征提取:如Haar特征提取。
- 图像滤波:如快速均值滤波。
快速计算图像块和的示例
假设我们需要计算图像中一个矩形区域的和,使用积分图像可以大大加速这一过程。
# 定义矩形区域的左上角和右下角坐标
top_left = (10, 10)
bottom_right = (50, 50)
# 使用积分图像计算矩形区域的和
sum_rect = (integral_image[bottom_right[1], bottom_right[0]] -
integral_image[top_left[1] - 1, bottom_right[0]] -
integral_image[bottom_right[1], top_left[0] - 1] +
integral_image[top_left[1] - 1, top_left[0] - 1])
print("Sum of the rectangle:", sum_rect)
在这个示例中,通过使用积分图像,我们可以在常数时间内计算任意矩形区域内的像素值和,而不需要遍历整个区域。
通过这些示例,可以看到如何使用OpenCV中的integral
函数来计算积分图像,并使用积分图像进行快速图像处理操作。根据具体的应用需求,可以灵活运用积分图像来实现高效的图像处理任务。
二三、图像边界处理
在OpenCV中,边界处理是图像处理中的一个重要步骤。通过添加边界,可以解决图像卷积和滤波过程中出现的边界效应问题。OpenCV提供了一个函数 copyMakeBorder
来实现图像边界的添加。
图像边界处理函数 | |
copyMakeBorder | 在图像周围添加边界 |
使用 copyMakeBorder
添加图像边界
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 设置边界大小
top, bottom, left, right = 10, 10, 10, 10
# 添加边界
bordered_image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[255, 0, 0])
# 显示原图像和添加边界后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Bordered Image', bordered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
copyMakeBorder
函数:在图像的四周添加边界。该函数的参数如下:src
:输入图像。top
:顶边界的大小。bottom
:底边界的大小。left
:左边界的大小。right
:右边界的大小。borderType
:边界类型,可以是以下几种:cv2.BORDER_CONSTANT
:常量边界,填充指定的常量值。cv2.BORDER_REFLECT
:反射边界,边界元素被镜像反射。cv2.BORDER_REFLECT_101
:反射边界,但不重复边界元素。cv2.BORDER_REPLICATE
:复制边界,边界元素被复制。cv2.BORDER_WRAP
:环绕边界,边界元素被环绕。
value
:在使用cv2.BORDER_CONSTANT
时,填充的常量值。
边界类型示例
下面是一些不同边界类型的示例代码:
# 常量边界
constant_border = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[255, 0, 0])
# 反射边界
reflect_border = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_REFLECT)
# 反射边界101
reflect_101_border = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_REFLECT_101)
# 复制边界
replicate_border = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_REPLICATE)
# 环绕边界
wrap_border = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_WRAP)
# 显示不同类型的边界处理效果
cv2.imshow('Constant Border', constant_border)
cv2.imshow('Reflect Border', reflect_border)
cv2.imshow('Reflect 101 Border', reflect_101_border)
cv2.imshow('Replicate Border', replicate_border)
cv2.imshow('Wrap Border', wrap_border)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的copyMakeBorder
函数来添加不同类型的边界。根据具体的应用需求,可以选择合适的边界类型来实现图像处理任务中的边界处理。
二四、图像修复
在OpenCV中,图像修复(Inpainting)是一种用来恢复损坏图像或去除图像中不需要部分的技术。OpenCV提供了inpaint
函数来实现这一功能。这个函数可以根据图像中周围的像素来填补缺失或受损的区域,从而使图像恢复原貌。
图像修复函数 | |
inpaint | 对图像进行修复 |
使用 inpaint
进行图像修复
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 创建掩码,白色表示需要修复的区域
mask = np.zeros(image.shape[:2], dtype=np.uint8)
mask[100:150, 100:150] = 255 # 这是一个示例区域
# 使用Navier-Stokes算法进行图像修复
restored_image_ns = cv2.inpaint(image, mask, 3, cv2.INPAINT_NS)
# 使用Telea算法进行图像修复
restored_image_telea = cv2.inpaint(image, mask, 3, cv2.INPAINT_TELEA)
# 显示原图像、掩码和修复后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Mask', mask)
cv2.imshow('Restored Image (Navier-Stokes)', restored_image_ns)
cv2.imshow('Restored Image (Telea)', restored_image_telea)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
- 创建掩码:首先,我们创建一个与图像大小相同的掩码,其中白色(255)表示需要修复的区域,黑色(0)表示不需要修复的区域。
inpaint
函数:使用cv2.inpaint
函数对图像进行修复,该函数有四个参数:src
:输入图像。inpaintMask
:掩码图像,指定需要修复的区域。inpaintRadius
:修复的半径。flags
:修复算法,可以选择cv2.INPAINT_NS
(Navier-Stokes算法)或cv2.INPAINT_TELEA
(Telea算法)。
实际应用
图像修复在实际中有广泛的应用场景,包括去除图像中的水印、修复老照片中的破损部分、去除图像中的不需要对象等。
去除图像中的水印示例
# 读取图像和创建掩码
image = cv2.imread('path_to_image_with_watermark.jpg')
mask = cv2.imread('path_to_watermark_mask.jpg', cv2.IMREAD_GRAYSCALE)
# 使用Telea算法进行图像修复
restored_image = cv2.inpaint(image, mask, 3, cv2.INPAINT_TELEA)
# 显示原图像、掩码和修复后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Mask', mask)
cv2.imshow('Restored Image', restored_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过这些示例,可以看到如何使用OpenCV中的inpaint
函数来进行图像修复。根据具体的应用需求,可以选择合适的修复算法来实现图像的恢复和处理。
二五、霍夫变换
在OpenCV中,霍夫变换是一种常用的图像处理技术,用于检测图像中的几何形状,如直线和圆。OpenCV提供了三个主要的霍夫变换函数:HoughLines
、HoughLinesP
和 HoughCircles
。下面介绍这些函数及其使用示例。
霍夫变换函数 | ||
HoughLines | HoughLinesP | HoughCircles |
检测图像中的直线 | 检测图像中的直线段 | 检测图像中的圆 |
检测图像中的直线 (HoughLines
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用Canny边缘检测
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
# 使用HoughLines检测直线
lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
# 绘制检测到的直线
if lines is not None:
for rho, theta in lines[:, 0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))
cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.imshow('Hough Lines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
检测图像中的直线段 (HoughLinesP
)
# 使用HoughLinesP检测直线段
lines_p = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10)
# 绘制检测到的直线段
if lines_p is not None:
for x1, y1, x2, y2 in lines_p[:, 0]:
cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imshow('Hough Lines P', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
检测图像中的圆 (HoughCircles
)
# 使用HoughCircles检测圆
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1, minDist=20, param1=50, param2=30, minRadius=0, maxRadius=0)
# 绘制检测到的圆
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
# 绘制圆的外圆
cv2.circle(image, (i[0], i[1]), i[2], (255, 0, 0), 2)
# 绘制圆心
cv2.circle(image, (i[0], i[1]), 2, (0, 255, 0), 3)
cv2.imshow('Hough Circles', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
-
HoughLines
函数:用于检测图像中的直线。该函数的参数如下:image
:输入图像(边缘检测后的二值图像)。rho
:距离分辨率(像素)。theta
:角度分辨率(弧度)。threshold
:累加平面的阈值,只有高于该阈值的直线才会被检测出来。
-
HoughLinesP
函数:用于检测图像中的直线段。该函数的参数如下:minLineLength
:最小直线长度,短于此长度的直线段会被忽略。maxLineGap
:允许的最大间隔,一条直线上的点间隔不超过此值时,会被看作一条直线。
-
HoughCircles
函数:用于检测图像中的圆。该函数的参数如下:dp
:累加器分辨率与图像分辨率的反比。minDist
:检测到的圆心之间的最小距离。param1
:传递给Canny边缘检测算子的高阈值。param2
:圆心检测的累加器阈值。
通过这些示例,可以看到如何使用OpenCV中的霍夫变换函数来检测图像中的几何形状。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像检测任务。
二六、傅里叶变化
在OpenCV中,傅里叶变换是一种重要的图像处理技术,用于频域分析。OpenCV提供了几个主要的傅里叶变换相关函数:getOptimalDFTSize
、dft
和 idft
。下面介绍这些函数及其使用示例。
傅里叶变换函数 | ||
getOptimalDFTSize | dft | idft |
获取最优的DFT(离散傅里叶变换)大小 | 执行离散傅里叶变换 | 执行离散傅里叶逆变换 |
获取最优的DFT大小 (getOptimalDFTSize
)
import cv2
import numpy as np
# 获取最优的DFT大小
rows, cols = 480, 640 # 假设图像大小
optimal_rows = cv2.getOptimalDFTSize(rows)
optimal_cols = cv2.getOptimalDFTSize(cols)
print(f"Original size: ({rows}, {cols})")
print(f"Optimal DFT size: ({optimal_rows}, {optimal_cols})")
执行离散傅里叶变换 (dft
) 和 逆变换 (idft
)
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
rows, cols = image.shape
# 获取最优的DFT大小
optimal_rows = cv2.getOptimalDFTSize(rows)
optimal_cols = cv2.getOptimalDFTSize(cols)
# 扩展图像到最佳大小
padded_image = cv2.copyMakeBorder(image, 0, optimal_rows - rows, 0, optimal_cols - cols, cv2.BORDER_CONSTANT, value=0)
# 执行DFT
dft_image = cv2.dft(np.float32(padded_image), flags=cv2.DFT_COMPLEX_OUTPUT)
# 移动频谱
dft_shift = np.fft.fftshift(dft_image)
# 计算幅度谱
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
# 显示幅度谱
cv2.imshow('Magnitude Spectrum', magnitude_spectrum)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 执行逆DFT
idft_shift = np.fft.ifftshift(dft_shift)
idft_image = cv2.idft(idft_shift)
idft_image = cv2.magnitude(idft_image[:, :, 0], idft_image[:, :, 1])
# 显示逆变换后的图像
cv2.imshow('Inverse DFT Image', idft_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
getOptimalDFTSize
函数:返回一个最优大小,适合进行快速傅里叶变换(FFT),提高计算效率。图像的行和列会被扩展到这些最优大小。dft
函数:对输入图像进行离散傅里叶变换,返回频域表示。参数flags=cv2.DFT_COMPLEX_OUTPUT
指示输出为复数形式。idft
函数:对频域表示进行逆变换,返回时域图像。
实际应用
傅里叶变换在图像处理中有广泛的应用,包括图像滤波、压缩和特征提取等。
图像滤波示例
在频域中,可以通过对频谱进行处理来实现图像滤波,例如高通滤波和低通滤波。
# 创建低通滤波器
crow, ccol = optimal_rows // 2 , optimal_cols // 2
mask = np.zeros((optimal_rows, optimal_cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# 应用低通滤波器
fshift = dft_shift * mask
# 计算滤波后的幅度谱
fshift_magnitude_spectrum = 20 * np.log(cv2.magnitude(fshift[:, :, 0], fshift[:, :, 1]))
# 显示滤波后的幅度谱
cv2.imshow('Filtered Magnitude Spectrum', fshift_magnitude_spectrum)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 执行逆DFT
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
# 显示滤波后的图像
cv2.imshow('Filtered Image', img_back)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过这些示例,可以看到如何使用OpenCV中的傅里叶变换函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理任务。
二七、离散余弦变换
在OpenCV中,离散余弦变换(DCT)和其逆变换(IDCT)是常用于图像压缩和处理的技术。DCT将图像数据从时域转换到频域,而IDCT则是将数据从频域转换回时域。OpenCV提供了两个主要函数:dct
和 idct
。
离散余弦变换函数 | |
dct | idct |
执行离散余弦变换 | 执行离散余弦逆变换 |
执行离散余弦变换 (dct
) 和逆变换 (idct
)
import cv2
import numpy as np
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 将图像转换为浮点型
image_float = np.float32(image) / 255.0
# 执行离散余弦变换
dct_image = cv2.dct(image_float)
# 显示DCT变换后的图像
cv2.imshow('DCT Image', dct_image)
cv2.waitKey(0)
# 执行离散余弦逆变换
idct_image = cv2.idct(dct_image)
# 将结果转换回0-255范围的图像
idct_image = np.uint8(idct_image * 255)
# 显示逆变换后的图像
cv2.imshow('IDCT Image', idct_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
dct
函数:对输入图像进行离散余弦变换。该函数将图像数据从时域转换到频域,通常用于压缩算法,如JPEG压缩。idct
函数:对频域数据进行逆变换,恢复到时域。
实际应用
离散余弦变换在图像压缩中有广泛的应用。例如,在JPEG压缩中,图像被分割成8x8的块,并对每个块执行DCT变换,然后进行量化处理。
JPEG压缩示例(简化版)
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
h, w = image.shape
# 将图像转换为浮点型
image_float = np.float32(image) / 255.0
# 分块处理(8x8)
block_size = 8
dct_blocks = np.zeros_like(image_float)
# 执行DCT变换
for i in range(0, h, block_size):
for j in range(0, w, block_size):
block = image_float[i:i+block_size, j:j+block_size]
dct_block = cv2.dct(block)
dct_blocks[i:i+block_size, j:j+block_size] = dct_block
# 显示DCT变换后的图像
cv2.imshow('DCT Blocks', dct_blocks)
cv2.waitKey(0)
# 执行逆DCT变换
idct_blocks = np.zeros_like(dct_blocks)
for i in range(0, h, block_size):
for j in range(0, w, block_size):
block = dct_blocks[i:i+block_size, j:j+block_size]
idct_block = cv2.idct(block)
idct_blocks[i:i+block_size, j:j+block_size] = idct_block
# 将结果转换回0-255范围的图像
idct_image = np.uint8(idct_blocks * 255)
# 显示逆变换后的图像
cv2.imshow('IDCT Blocks', idct_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过这些示例,可以看到如何使用OpenCV中的DCT和IDCT函数来进行离散余弦变换及其逆变换。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理和压缩任务。
二八、图像几何变换
在OpenCV中,几何变换是图像处理中的基本操作,包括旋转、缩放、平移、透视变换等。下面介绍一些常用的几何变换函数及其使用示例。
图像几何变换函数 | ||||
logPolar | warpPolar | linearPolar | getAffineTransform | warpAffine |
对图像进行对数极坐标变换 | 对图像进行极坐标变换 | 对图像进行线性极坐标变换 | 计算仿射变换矩阵 | 对图像进行仿射变换 |
invertAffineTransform | getPerspectiveTransform | warpPerspective | getRotationMatrix2D | |
计算仿射变换矩阵的逆矩阵 | 计算透视变换矩阵 | 对图像进行透视变换 | 计算二维旋转矩阵 |
仿射变换 (warpAffine
和 getAffineTransform
)
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg')
# 获取图像尺寸
rows, cols, ch = image.shape
# 定义三个点及其对应变换后的点
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
# 计算仿射变换矩阵
M = cv2.getAffineTransform(pts1, pts2)
# 对图像进行仿射变换
dst = cv2.warpAffine(image, M, (cols, rows))
cv2.imshow('Affine Transform', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
透视变换 (warpPerspective
和 getPerspectiveTransform
)
# 定义四个点及其对应变换后的点
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
# 计算透视变换矩阵
M = cv2.getPerspectiveTransform(pts1, pts2)
# 对图像进行透视变换
dst = cv2.warpPerspective(image, M, (300, 300))
cv2.imshow('Perspective Transform', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
旋转变换 (getRotationMatrix2D
)
# 定义旋转中心、角度和缩放因子
center = (cols // 2, rows // 2)
angle = 45
scale = 1.0
# 计算旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, scale)
# 对图像进行旋转变换
rotated = cv2.warpAffine(image, M, (cols, rows))
cv2.imshow('Rotated Image', rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()
极坐标变换 (warpPolar
和 linearPolar
)
# 极坐标变换
polar_image = cv2.warpPolar(image, (cols, rows), (cols//2, rows//2), max(cols, rows) // 2, cv2.WARP_FILL_OUTLIERS)
# 对数极坐标变换
log_polar_image = cv2.logPolar(image, (cols//2, rows//2), 40, cv2.WARP_FILL_OUTLIERS)
cv2.imshow('Polar Transform', polar_image)
cv2.imshow('Log Polar Transform', log_polar_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这些示例展示了如何使用OpenCV中的几何变换函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理任务。
二九、图像累加
在OpenCV中,图像累加是一个重要的操作,通常用于视频处理、背景建模和图像融合等任务。OpenCV提供了多种累加操作的函数,包括accumulate
、accumulateWeighted
、accumulateSquare
和 accumulateProduct
。下面介绍这些函数及其使用示例。
图像累加函数 | |||
accumulate | accumulateWeighted | accumulateSquare | accumulateProduct |
将输入图像累加到累加图像中 | 将输入图像加权累加到累加图像中 | 将输入图像的平方累加到累加图像中 | 将两个输入图像的乘积累加到累加图像中 |
将输入图像累加到累加图像中 (accumulate
)
import cv2
import numpy as np
# 读取图像
image1 = cv2.imread('path_to_image1.jpg', cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread('path_to_image2.jpg', cv2.IMREAD_GRAYSCALE)
# 初始化累加图像
accum_image = np.zeros_like(image1, dtype=np.float32)
# 执行累加操作
cv2.accumulate(image1, accum_image)
cv2.accumulate(image2, accum_image)
# 显示累加结果
cv2.imshow('Accumulated Image', cv2.convertScaleAbs(accum_image))
cv2.waitKey(0)
cv2.destroyAllWindows()
将输入图像加权累加到累加图像中 (accumulateWeighted
)
# 初始化累加图像
accum_image_weighted = np.zeros_like(image1, dtype=np.float32)
# 加权累加操作
alpha = 0.5
cv2.accumulateWeighted(image1, accum_image_weighted, alpha)
cv2.accumulateWeighted(image2, accum_image_weighted, alpha)
# 显示加权累加结果
cv2.imshow('Accumulated Weighted Image', cv2.convertScaleAbs(accum_image_weighted))
cv2.waitKey(0)
cv2.destroyAllWindows()
将输入图像的平方累加到累加图像中 (accumulateSquare
)
# 初始化累加图像
accum_image_square = np.zeros_like(image1, dtype=np.float32)
# 累加平方操作
cv2.accumulateSquare(image1, accum_image_square)
cv2.accumulateSquare(image2, accum_image_square)
# 显示累加平方结果
cv2.imshow('Accumulated Square Image', cv2.convertScaleAbs(accum_image_square))
cv2.waitKey(0)
cv2.destroyAllWindows()
将两个输入图像的乘积累加到累加图像中 (accumulateProduct
)
# 初始化累加图像
accum_image_product = np.zeros_like(image1, dtype=np.float32)
# 累加乘积操作
cv2.accumulateProduct(image1, image2, accum_image_product)
# 显示累加乘积结果
cv2.imshow('Accumulated Product Image', cv2.convertScaleAbs(accum_image_product))
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
accumulate
函数:将输入图像累加到累加图像中,适用于累积多帧图像。accumulateWeighted
函数:将输入图像加权累加到累加图像中,可以用于背景建模和图像融合,参数alpha
用于控制权重。accumulateSquare
函数:将输入图像的平方累加到累加图像中,适用于平方累加操作。accumulateProduct
函数:将两个输入图像的乘积累加到累加图像中,适用于乘积累加操作。
这些示例展示了如何使用OpenCV中的各种累加函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现复杂的图像处理任务。
三十、随机数与添加噪声
在OpenCV中,randu
和 randn
是两个用于生成随机数的函数,常用于图像处理中的噪声添加等操作。下面介绍这些函数及其使用示例。
随机数生成与添加噪声函数 | |
randu | randn |
生成均匀分布的随机数 | 生成正态(高斯)分布的随机数 |
使用 randu
生成均匀分布的随机数并添加噪声
import cv2
import numpy as np
# 读取图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 生成与图像大小相同的均匀分布噪声
noise = np.zeros_like(image, dtype=np.float32)
cv2.randu(noise, 0, 255)
# 将噪声添加到图像中
noisy_image = cv2.add(image.astype(np.float32), noise)
# 显示原图像和添加噪声后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Uniform Noise Image', noisy_image.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()
使用 randn
生成正态分布的随机数并添加噪声
# 生成与图像大小相同的正态分布噪声
noise = np.zeros_like(image, dtype=np.float32)
cv2.randn(noise, 0, 25) # 均值为0,标准差为25
# 将噪声添加到图像中
noisy_image = cv2.add(image.astype(np.float32), noise)
# 显示原图像和添加噪声后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Gaussian Noise Image', noisy_image.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
randu
函数:生成均匀分布的随机数。可以指定随机数的上下限。例如,在上述代码中,噪声值在0到255之间均匀分布。randn
函数:生成正态(高斯)分布的随机数。可以指定随机数的均值和标准差。例如,在上述代码中,噪声值服从均值为0,标准差为25的正态分布。
实际应用
在图像处理中,添加噪声常用于以下场景:
- 算法测试:在处理算法中测试其抗噪能力。
- 数据增强:在训练机器学习模型时,使用带噪声的数据增强模型的鲁棒性。
- 模拟真实情况:在某些情况下,需要模拟现实中的噪声以测试图像处理算法的性能。
通过这些示例,可以看到如何使用OpenCV中的randu
和randn
函数来生成随机数并将其添加到图像中作为噪声。根据具体的应用需求,可以灵活运用这些函数来实现图像处理任务。
三一、PCA
在OpenCV中,主成分分析(PCA)是一种常用的降维技术,广泛应用于图像处理和机器学习领域。OpenCV提供了几个用于PCA操作的函数:PCACompute
、project
和 backProject
。下面介绍这些函数及其使用示例。
PCA函数 | ||
PCACompute | project | backProject |
计算主成分 | 将数据投影到主成分空间 | 将数据从主成分空间反投影回原空间 |
计算主成分 (PCACompute
)
import cv2
import numpy as np
# 创建示例数据
data = np.array([[2.5, 2.4],
[0.5, 0.7],
[2.2, 2.9],
[1.9, 2.2],
[3.1, 3.0],
[2.3, 2.7],
[2, 1.6],
[1, 1.1],
[1.5, 1.6],
[1.1, 0.9]], dtype=np.float32)
# 计算PCA
mean, eigenvectors = cv2.PCACompute(data, mean=None)
print("Mean:\n", mean)
print("Eigenvectors:\n", eigenvectors)
将数据投影到主成分空间 (project
)
# 将数据投影到主成分空间
projected_data = cv2.PCAProject(data, mean, eigenvectors)
print("Projected Data:\n", projected_data)
将数据从主成分空间反投影回原空间 (backProject
)
# 将数据从主成分空间反投影回原空间
back_projected_data = cv2.PCABackProject(projected_data, mean, eigenvectors)
print("Back Projected Data:\n", back_projected_data)
解释
PCACompute
函数:计算数据的主成分。返回均值和特征向量(主成分)。project
函数:将数据投影到主成分空间。使用计算得到的均值和特征向量,将原数据转换到主成分空间。backProject
函数:将数据从主成分空间反投影回原空间。使用计算得到的均值和特征向量,将主成分空间的数据转换回原始数据空间。
实际应用
PCA在图像处理中有许多应用,例如:
- 图像压缩:通过保留主要成分,减少图像的维度,从而实现压缩。
- 特征提取:在图像分类和识别任务中,使用PCA提取主要特征,减少计算复杂度。
- 数据可视化:将高维数据降维到2D或3D空间,方便可视化。
图像压缩示例
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
image = np.float32(image) / 255.0
h, w = image.shape
# 将图像展开为2D数据
data = image.reshape((-1, w))
# 计算PCA,保留主要成分
mean, eigenvectors = cv2.PCACompute(data, mean=None, maxComponents=10)
# 投影到主成分空间
projected_data = cv2.PCAProject(data, mean, eigenvectors)
# 反投影回原空间
back_projected_data = cv2.PCABackProject(projected_data, mean, eigenvectors)
# 将数据重塑为图像
compressed_image = back_projected_data.reshape((h, w))
# 显示原图像和压缩后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Compressed Image', compressed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过这些示例,可以看到如何使用OpenCV中的PCA函数来处理数据和图像。根据具体的应用需求,可以灵活运用这些函数来实现数据降维和特征提取等任务。
三二、直方图
在OpenCV中,直方图是图像处理中的一个重要工具,用于表示图像中像素值的分布情况。常用的直方图函数包括 calcHist
、compareHist
和 calcBackProject
。下面介绍这些函数及其使用示例。
直方图函数 | ||
calcHist | compareHist | calcBackProject |
计算图像的直方图 | 比较两个直方图的相似度 | 计算反向投影 |
计算图像的直方图 (calcHist
)
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)
# 计算直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])
# 绘制直方图
plt.plot(hist)
plt.title('Grayscale Histogram')
plt.xlabel('Pixel Value')
plt.ylabel('Frequency')
plt.show()
比较两个直方图的相似度 (compareHist
)
# 读取两幅图像并转换为灰度图
image1 = cv2.imread('path_to_image1.jpg', cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread('path_to_image2.jpg', cv2.IMREAD_GRAYSCALE)
# 计算直方图
hist1 = cv2.calcHist([image1], [0], None, [256], [0, 256])
hist2 = cv2.calcHist([image2], [0], None, [256], [0, 256])
# 归一化直方图
hist1 = cv2.normalize(hist1, hist1)
hist2 = cv2.normalize(hist2, hist2)
# 比较直方图
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
print('Histogram similarity:', similarity)
计算反向投影 (calcBackProject
)
# 读取图像并转换为HSV色彩空间
image = cv2.imread('path_to_image.jpg')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 选择感兴趣的区域(ROI)
roi = hsv[100:200, 100:200]
# 计算ROI的直方图
roi_hist = cv2.calcHist([roi], [0, 1], None, [180, 256], [0, 180, 0, 256])
roi_hist = cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)
# 计算反向投影
back_project = cv2.calcBackProject([hsv], [0, 1], roi_hist, [0, 180, 0, 256], 1)
# 显示反向投影结果
cv2.imshow('Back Projection', back_project)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释
calcHist
函数:计算图像的直方图。参数说明:[image]
:输入图像,必须用方括号括起来。[0]
:使用的通道,灰度图为0。None
:没有使用掩码。[256]
:直方图的大小。[0, 256]
:像素值的范围。
compareHist
函数:比较两个直方图的相似度。常用的相似度度量方法包括:cv2.HISTCMP_CORREL
:相关性。cv2.HISTCMP_CHISQR
:卡方。cv2.HISTCMP_INTERSECT
:交集。cv2.HISTCMP_BHATTACHARYYA
:Bhattacharyya距离。
calcBackProject
函数:计算反向投影。反向投影用于在图像中查找与给定直方图相匹配的像素。参数说明:[hsv]
:输入图像,必须用方括号括起来。[0, 1]
:使用的通道。roi_hist
:感兴趣区域的直方图。[0, 180, 0, 256]
:像素值的范围。1
:缩放因子。
通过这些示例,可以看到如何使用OpenCV中的直方图函数来处理图像。根据具体的应用需求,可以灵活运用这些函数来实现图像的分析和处理任务。
三三、图像特征
在OpenCV中,图像特征检测和描述是计算机视觉中的一个重要领域,用于图像匹配、物体识别、图像拼接等任务。下面介绍一些常用的图像特征检测和描述算法及其使用示例。
像特征检测和描述算法 | |||
HOG(Histogram of Oriented Gradients) | LBP(Local Binary Patterns) | SIFT(Scale-Invariant Feature Transform) | SURF(Speeded-Up Robust Features) |
方向梯度直方图 | 局部二值模式 | 尺度不变特征变换 | 加速鲁棒特征 |
FAST(Features from Accelerated Segment Test) | ORB(Oriented FAST and Rotated BRIEF) | BRISK(Binary Robust Invariant Scalable Keypoints) | MSER(Maximally Stable Extremal Regions) |
加速分割测试特征 | 方向FAST和旋转BRIEF | 二进制鲁棒可扩展关键点 | 最大稳定极值区域 |
Star | BRIEF(Binary Robust Independent Elementary Features) | FREAK(Fast Retina Keypoint) | cornerHarris |
星形特征检测器 | 二进制鲁棒独立基本特征 | 快速视网膜关键点 | Harris角点检测 |
preCornerDetect | LineSegmentDetector | FastLineDetector | goodFeaturesToTrack |
预角点检测 | 线段检测器 | 快速线段检测器 | 检测好特征点 |
SIFT 特征检测和描述
import cv2
# 读取图像并转换为灰度图
image = cv2.imread('path_to_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 初始化SIFT检测器
sift = cv2.SIFT_create()
# 检测SIFT特征点并计算描述子
keypoints, descriptors = sift.detectAndCompute(gray, None)
# 在图像上绘制特征点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 显示结果
cv2.imshow('SIFT Keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
ORB 特征检测和描述
# 初始化ORB检测器
orb = cv2.ORB_create()
# 检测ORB特征点并计算描述子
keypoints, descriptors = orb.detectAndCompute(gray, None)
# 在图像上绘制特征点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 显示结果
cv2.imshow('ORB Keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
Harris 角点检测
# Harris角点检测
gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
# 结果通过阈值化标记角点
image[dst > 0.01 * dst.max()] = [0, 0, 255]
# 显示结果
cv2.imshow('Harris Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
HOG 特征描述
# 初始化HOG描述子
hog = cv2.HOGDescriptor()
# 计算HOG描述子
hog_features = hog.compute(gray)
print("HOG Features:", hog_features)
解释
- HOG:用于特征描述,常用于行人检测等任务。
- LBP:用于纹理特征描述,适合纹理分析。
- SIFT和SURF:用于特征检测和描述,具有尺度和旋转不变性。
- FAST和ORB:用于快速特征检测和描述,ORB是基于FAST和BRIEF的改进。
- BRISK、MSER、Star、BRIEF、FREAK:用于特征检测和描述的不同算法。
- cornerHarris和preCornerDetect:用于角点检测。
- LineSegmentDetector和FastLineDetector:用于线段检测。
- goodFeaturesToTrack:用于检测图像中的好特征点。
通过这些示例代码,可以看到如何使用OpenCV中的各种图像特征检测和描述算法来处理图像。根据具体的应用需求,可以灵活运用这些算法来实现复杂的图像处理和分析任务。
三四、机器学习
在OpenCV中,机器学习模块(ML module)提供了多种分类器和回归器,用于各种机器学习任务。下面介绍一些常用的机器学习算法及其使用示例。
常用机器学习算法 | |||
SVM(Support Vector Machine) | KNearest | RTrees(Random Trees) | NormalBayesClassifier |
支持向量机 | K近邻算法 | 随机森林 | 朴素贝叶斯分类器 |
Boost(AdaBoost) | ANN_MLP(Artificial Neural Network - Multi-Layer Perceptron): | DNN(Deep Neural Network) | |
自适应增强算法 | 多层感知器人工神经网络 | 深度神经网络 |
支持向量机(SVM)
import cv2
import numpy as np
# 创建训练数据
train_data = np.array([[1, 2], [2, 3], [3, 3], [6, 6], [7, 7], [8, 8]], dtype=np.float32)
labels = np.array([0, 0, 0, 1, 1, 1], dtype=np.int32)
# 初始化SVM并设置参数
svm = cv2.ml.SVM_create()
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setType(cv2.ml.SVM_C_SVC)
svm.setC(1)
# 训练SVM
svm.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 创建测试数据
test_data = np.array([[2, 2], [5, 5]], dtype=np.float32)
# 预测
_, results = svm.predict(test_data)
print("Predicted labels:", results.ravel())
K近邻算法(KNearest)
# 初始化K近邻分类器并设置参数
knn = cv2.ml.KNearest_create()
knn.setDefaultK(3)
# 训练K近邻分类器
knn.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 预测
ret, results, neighbours, dist = knn.findNearest(test_data, k=3)
print("Predicted labels:", results.ravel())
随机森林(RTrees)
# 初始化随机森林分类器
rtrees = cv2.ml.RTrees_create()
# 训练随机森林分类器
rtrees.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 预测
_, results = rtrees.predict(test_data)
print("Predicted labels:", results.ravel())
朴素贝叶斯分类器(NormalBayesClassifier)
# 初始化朴素贝叶斯分类器
bayes = cv2.ml.NormalBayesClassifier_create()
# 训练朴素贝叶斯分类器
bayes.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 预测
_, results = bayes.predict(test_data)
print("Predicted labels:", results.ravel())
自适应增强算法(Boost)
# 初始化Boost分类器
boost = cv2.ml.Boost_create()
# 训练Boost分类器
boost.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 预测
_, results = boost.predict(test_data)
print("Predicted labels:", results.ravel())
多层感知器人工神经网络(ANN_MLP)
# 初始化多层感知器人工神经网络
mlp = cv2.ml.ANN_MLP_create()
mlp.setLayerSizes(np.array([2, 5, 1])) # 输入层2个节点,隐藏层5个节点,输出层1个节点
mlp.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP)
# 训练多层感知器
mlp.train(train_data, cv2.ml.ROW_SAMPLE, labels)
# 预测
_, results = mlp.predict(test_data)
print("Predicted labels:", results.ravel())
解释
- SVM:适用于分类和回归任务,通过最大化类别间的间隔来找到最佳分类超平面。
- KNearest:基于最近邻居的投票进行分类,简单易实现但计算量大。
- RTrees:随机森林,通过多个决策树的集成提高分类精度和防止过拟合。
- NormalBayesClassifier:基于贝叶斯定理进行分类,假设特征之间相互独立。
- Boost:通过加权的方式结合多个弱分类器形成一个强分类器,常用AdaBoost算法。
- ANN_MLP:多层感知器神经网络,通过反向传播算法进行训练,适用于复杂的非线性问题。
- DNN:深度神经网络,适用于处理大规模数据和复杂模式识别任务。
这些示例展示了如何使用OpenCV中的各种机器学习算法来进行分类和预测任务。根据具体的应用需求,可以灵活运用这些算法来实现机器学习任务。
三五、相机标定
在OpenCV中,摄像机标定是计算机视觉中的一个重要步骤,用于确定摄像机的内部参数和外部参数。摄像机标定包括一系列步骤,如角点检测、图像畸变校正、姿态估计等。下面介绍一些常用的摄像机标定函数及其使用示例。
摄像机标定函数 | |||
findChessboardCorners | findCirclesGrid | find4QuadCornerSubpix | cornerSubPix |
检测棋盘格角点 | 检测圆形网格点 | 精确化角点检测 | 进一步精确化角点位置 |
calibrateCamera | initUndistortRectifyMap | remap | undistort |
摄像机标定 | 初始化去畸变和校正映射 | 重映射图像 | 校正图像的畸变 |
findHomography | solvePnP | solvePnPRansac | Rodrigues |
计算单应性矩阵 | 解PnP问题,估计物体的姿态 | 使用RANSAC解PnP问题 | 将旋转向量转换为旋转矩阵 |
convertPointsToHomogeneous | convertPointsFromHomogeneous | ||
将点转换为齐次坐标 | 将齐次坐标转换为普通坐标 |
棋盘格角点检测 (findChessboardCorners
)
import cv2
import numpy as np
# 读取棋盘格图像
image = cv2.imread('path_to_chessboard_image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 设置棋盘格大小
chessboard_size = (9, 6)
# 检测棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None)
# 如果找到角点,则绘制并显示
if ret:
cv2.drawChessboardCorners(image, chessboard_size, corners, ret)
cv2.imshow('Chessboard Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
精确化角点位置 (cornerSubPix
)
# 进一步精确化角点位置
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
# 绘制精确化后的角点
cv2.drawChessboardCorners(image, chessboard_size, corners2, ret)
cv2.imshow('Refined Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
摄像机标定 (calibrateCamera
)
# 准备对象点和图像点
objp = np.zeros((chessboard_size[0] * chessboard_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2)
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点
objpoints.append(objp)
imgpoints.append(corners2)
# 摄像机标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
print("Camera matrix:\n", mtx)
print("Distortion coefficients:\n", dist)
图像畸变校正 (undistort
)
# 校正图像的畸变
dst = cv2.undistort(image, mtx, dist, None, mtx)
# 显示校正后的图像
cv2.imshow('Undistorted Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
单应性矩阵计算 (findHomography
)
# 假设有两个点集,pts_src 和 pts_dst
pts_src = np.array([[0, 0], [0, 1], [1, 1], [1, 0]], dtype=np.float32)
pts_dst = np.array([[0, 0], [0, 1], [1, 1], [1, 0]], dtype=np.float32)
# 计算单应性矩阵
H, mask = cv2.findHomography(pts_src, pts_dst, cv2.RANSAC, 5.0)
print("Homography matrix:\n", H)
PnP 问题求解 (solvePnP
)
# 对象点和图像点
obj_points = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]], dtype=np.float32)
img_points = np.array([[100, 100], [100, 200], [200, 200], [200, 100]], dtype=np.float32)
# 估计物体姿态
success, rotation_vector, translation_vector = cv2.solvePnP(obj_points, img_points, mtx, dist)
print("Rotation vector:\n", rotation_vector)
print("Translation vector:\n", translation_vector)
这些示例展示了如何使用OpenCV中的摄像机标定函数来进行角点检测、图像畸变校正、姿态估计等任务。根据具体的应用需求,可以灵活运用这些函数来实现复杂的摄像机标定和图像处理任务。
三六、绘制几何与文本
在OpenCV中,绘制几何图形和文本是图像处理中的基本操作。OpenCV提供了一些函数来绘制直线、矩形、圆、椭圆、多边形、箭头线、标记和文本。下面介绍这些函数及其使用示例。
绘制几何图形与文本函数 | |||
line | circle | rectangle | ellipse |
绘制直线 | 绘制圆 | 绘制矩形 | 绘制椭圆 |
polylines | arrowedLine | drawMarker | putText |
绘制多边形 | 绘制箭头线 | 绘制标记 | 绘制文本 |
绘制直线 (line
)
import cv2
import numpy as np
# 创建一个黑色图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条蓝色的直线
cv2.line(image, (0, 0), (511, 511), (255, 0, 0), 5)
# 显示图像
cv2.imshow('Line', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制圆 (circle
)
# 绘制一个绿色的圆
cv2.circle(image, (256, 256), 100, (0, 255, 0), -1)
# 显示图像
cv2.imshow('Circle', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制矩形 (rectangle
)
# 绘制一个红色的矩形
cv2.rectangle(image, (100, 100), (400, 400), (0, 0, 255), 3)
# 显示图像
cv2.imshow('Rectangle', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制椭圆 (ellipse
)
# 绘制一个白色的椭圆
cv2.ellipse(image, (256, 256), (150, 100), 0, 0, 180, (255, 255, 255), -1)
# 显示图像
cv2.imshow('Ellipse', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制多边形 (polylines
)
# 定义多边形的顶点
points = np.array([[100, 50], [200, 300], [700, 200], [500, 100]], np.int32)
points = points.reshape((-1, 1, 2))
# 绘制多边形
cv2.polylines(image, [points], True, (0, 255, 255), 3)
# 显示图像
cv2.imshow('Polylines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制箭头线 (arrowedLine
)
# 绘制一个箭头线
cv2.arrowedLine(image, (50, 50), (450, 450), (255, 255, 0), 5)
# 显示图像
cv2.imshow('Arrowed Line', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制标记 (drawMarker
)
# 绘制一个标记
cv2.drawMarker(image, (256, 256), (0, 255, 255), markerType=cv2.MARKER_STAR, markerSize=40, thickness=2)
# 显示图像
cv2.imshow('Marker', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制文本 (putText
)
# 绘制文本
cv2.putText(image, 'OpenCV', (100, 400), cv2.FONT_HERSHEY_SIMPLEX, 4, (255, 255, 255), 2, cv2.LINE_AA)
# 显示图像
cv2.imshow('Text', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
通过这些示例代码,可以看到如何使用OpenCV中的绘图函数在图像上绘制各种几何图形和文本。这些基本的绘图操作在图像处理、计算机视觉、数据可视化等领域有着广泛的应用。