目录
一、边界填充 (cv2.copyMakeBorder)
边界填充是图像处理中常用的技术,用于在图像周围添加额外的边界像素。OpenCV 提供了cv2.copyMakeBorder()
函数实现这一功能。
1.1 函数语法
cv2.copyMakeBorder(src: UMat, top: int, bottom: int, left: int, right: int, borderType: int, dst: UMat | None = ..., value: cv2.typing.Scalar = ...)
1.2 参数说明
- src: 要扩充边界的原始图像
- top, bottom, left, right: 相应方向上的边框宽度
- borderType: 边界类型
- value: 当 borderType 为 cv2.BORDER_CONSTANT 时使用的常数值
1.3 边界类型详解
- cv2.BORDER_CONSTANT: 添加固定颜色的边框
- cv2.BORDER_REFLECT: 镜面反射,如 gfedcba|abcdefgh|hgfedcba
- cv2.BORDER_REFLECT_101/cv2.BORDER_DEFAULT: 改进的反射,如 gfedcb|abcdefgh|gfedcba
- cv2.BORDER_REPLICATE: 复制边界像素,如 aaaaaa|abcdefgh|hhhhhhh
- cv2.BORDER_WRAP: 环绕复制,如 cdefgh|abcdefgh|abcdefg
1.4 示例代码
import cv2
import numpy as np
# 读取图像
a = cv2.imread('img_1.jpg')
if a is None:
print("无法读取图像,请检查文件路径")
exit()
# 设置边界宽度
top, bottom, left, right = 50, 50, 50, 50
# 创建不同类型的边界
constant = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[255, 0, 0]) # 蓝色边框
reflect = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_REPLICATE)
wrap = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_WRAP)
# 显示结果
cv2.imshow('原始图像', a)
cv2.imshow('CONSTANT边界', constant)
cv2.imshow('REFLECT边界', reflect)
cv2.imshow('REFLECT101边界', reflect101)
cv2.imshow('REPLICATE边界', replicate)
cv2.imshow('WRAP边界', wrap)
# 等待按键,关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
二、图像加法运算
图像加法是基本的图像处理操作,可以用于图像融合、亮度调整等场景。OpenCV 提供了两种主要的加法方式:运算符+
和cv2.add()
函数。
2.1 运算符+
的特性
- 当像素值之和小于 255 时,直接取和
- 当像素值之和大于 255 时,结果为 (sum - 256),即模 256 运算
- 适用于简单的像素值调整
2.2 cv2.add()
函数的特性
- 当像素值之和小于 255 时,直接取和
- 当像素值之和大于 255 时,结果为 255(截断处理)
- 更适合图像融合场景
2.3 示例代码
import cv2
import numpy as np
# 读取图像
a = cv2.imread('img_1.jpg')
b = cv2.imread('img_2.jpg')
if a is None or b is None:
print("无法读取图像,请检查文件路径")
exit()
# 简单的像素值调整
c1 = a + 10 # 所有像素值增加10
cv2.imshow('原始图像', a)
cv2.imshow('a+10', c1)
cv2.waitKey(0)
# 图像区域加法
# 确保两个图像大小相同
height, width = min(a.shape[0], b.shape[0]), min(a.shape[1], b.shape[1])
a_resized = cv2.resize(a, (width, height))
b_resized = cv2.resize(b, (width, height))
# 加法运算
c2 = a_resized + b_resized
cv2.imshow('a + b', c2)
cv2.waitKey(0)
# 使用cv2.add()函数
c3 = cv2.add(a_resized, b_resized)
cv2.imshow('cv2.add(a, b)', c3)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、图像加权运算
加权运算是一种更灵活的图像融合方法,可以通过调整权重来控制不同图像在融合结果中的贡献度。
3.1 加权运算公式
dst = src1 × α + src2 × β + γ
其中:
- α 和 β 是 src1 和 src2 的权重
- γ 是亮度调整值
3.2 函数语法
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
3.3 示例代码
import cv2
import numpy as np
# 读取图像
a = cv2.imread('img_1.jpg')
b = cv2.imread('img_2.jpg')
if a is None or b is None:
print("无法读取图像,请检查文件路径")
exit()
# 调整图像大小,确保它们具有相同的尺寸
height, width = 400, 400
a_resized = cv2.resize(a, (width, height))
b_resized = cv2.resize(b, (width, height))
# 加权融合
# 公式: dst = a*0.2 + b*0.8 + 10
blended = cv2.addWeighted(a_resized, 0.2, b_resized, 0.8, gamma=10)
# 显示结果
cv2.imshow('图像1', a_resized)
cv2.imshow('图像2', b_resized)
cv2.imshow('加权融合结果', blended)
# 尝试不同的权重组合
blended2 = cv2.addWeighted(a_resized, 0.5, b_resized, 0.5, gamma=0) # 均等权重
blended3 = cv2.addWeighted(a_resized, 0.8, b_resized, 0.2, gamma=-20) # 暗化效果
cv2.imshow('均等权重融合', blended2)
cv2.imshow('暗化融合', blended3)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、阈值处理
阈值处理是将图像转换为二值图像的常用方法,通过设定一个阈值将像素分为两类:高于阈值和低于阈值。
4.1 函数语法
retval, dst = cv2.threshold(src, thresh, maxval, type)
4.2 参数说明
- retval: 返回的阈值
- dst: 阈值分割结果图像
- src: 输入图像(通常为灰度图)
- thresh: 设定的阈值
- maxval: 最大值(用于 THRESH_BINARY 和 THRESH_BINARY_INV 类型)
- type: 阈值类型
4.3 阈值类型详解
类型 | 像素值 > thresh | 其他情况 |
---|---|---|
cv2.THRESH_BINARY | maxval | 0 |
cv2.THRESH_BINARY_INV | 0 | maxval |
cv2.THRESH_TRUNC | thresh | 当前灰度值 |
cv2.THRESH_TOZERO | 当前灰度值 | 0 |
cv2.THRESH_TOZERO_INV | 0 | 当前灰度值 |
4.4 示例代码
import cv2
import numpy as np
# 读取灰度图像
image = cv2.imread('img_1.jpg', 0) # 0表示以灰度模式读取
if image is None:
print("无法读取图像,请检查文件路径")
exit()
# 设定阈值
threshold_value = 150
max_value = 255
# 应用不同的阈值类型
ret, binary = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY)
ret1, binaryinv = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY_INV)
ret2, trunc = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TRUNC)
ret3, tozero = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO)
ret4, tozeroinv = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_TOZERO_INV)
# 显示结果
cv2.imshow('原灰度图', image)
cv2.imshow('THRESH_BINARY', binary)
cv2.imshow('THRESH_BINARY_INV', binaryinv)
cv2.imshow('THRESH_TRUNC', trunc)
cv2.imshow('THRESH_TOZERO', tozero)
cv2.imshow('THRESH_TOZERO_INV', tozeroinv)
# 等待按键,关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
五、图像平滑处理(模糊处理)
图像平滑处理用于消除图像中的噪声或细节,使图像看起来更为模糊。OpenCV 提供了多种平滑滤波方法。
5.1 常用滤波方法
- 均值滤波(cv2.blur): 使用邻域像素的平均值
- 方框滤波(cv2.boxFilter): 类似于均值滤波,但可以选择是否归一化
- 高斯滤波(cv2.GaussianBlur): 使用高斯核进行滤波,更适合处理高斯噪声
- 中值滤波(cv2.medianBlur): 使用邻域像素的中值,对椒盐噪声有很好的抑制效果
5.2 示例代码
import cv2
import numpy as np
def add_peppersalt_noise(image, n=10000):
"""添加椒盐噪声"""
result = image.copy()
h, w = image.shape[:2] # 获取图片的高和宽
# 生成n个椒盐噪声
for i in range(n):
x = np.random.randint(low=0, high=h)
y = np.random.randint(low=0, high=w)
# 随机生成黑色或白色噪声
if np.random.randint(low=0, high=2) == 0:
result[x, y] = 0 # 黑色噪声
else:
result[x, y] = 255 # 白色噪声
return result
# 读取图像
image = cv2.imread('img_1.jpg')
if image is None:
print("无法读取图像,请检查文件路径")
exit()
# 显示原始图像
cv2.imshow('原始图像', image)
cv2.waitKey(0)
# 添加椒盐噪声
noise_image = add_peppersalt_noise(image)
cv2.imshow('添加椒盐噪声后的图像', noise_image)
cv2.waitKey(0)
# 1. 均值滤波
blur_3x3 = cv2.blur(noise_image, ksize=(3, 3)) # 3x3卷积核
blur_7x7 = cv2.blur(noise_image, ksize=(7, 7)) # 7x7卷积核
cv2.imshow('均值滤波 (3x3)', blur_3x3)
cv2.imshow('均值滤波 (7x7)', blur_7x7)
cv2.waitKey(0)
# 2. 方框滤波
box_norm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=True) # 归一化
box_no_norm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=False) # 不归一化
cv2.imshow('方框滤波 (归一化)', box_norm)
cv2.imshow('方框滤波 (不归一化)', box_no_norm)
cv2.waitKey(0)
# 3. 高斯滤波
gaussian_3x3 = cv2.GaussianBlur(noise_image, ksize=(3, 3), sigmaX=1) # 3x3高斯核
gaussian_7x7 = cv2.GaussianBlur(noise_image, ksize=(7, 7), sigmaX=2) # 7x7高斯核
cv2.imshow('高斯滤波 (3x3)', gaussian_3x3)
cv2.imshow('高斯滤波 (7x7)', gaussian_7x7)
cv2.waitKey(0)
# 4. 中值滤波
median_3x3 = cv2.medianBlur(noise_image, ksize=3) # 3x3中值滤波
median_7x7 = cv2.medianBlur(noise_image, ksize=7) # 7x7中值滤波
cv2.imshow('中值滤波 (3x3)', median_3x3)
cv2.imshow('中值滤波 (7x7)', median_7x7)
cv2.waitKey(0)
cv2.destroyAllWindows()