OpenCV 图像处理核心技术:边界填充、算术运算与滤波处理实战
目录
一、边界填充:cv2.copyMakeBorder () 函数详解
1. 函数参数说明
2. 常见边界填充类型及效果
3. 代码示例
二、图像算术运算:加法与加权加法
1. 普通加法(+ 运算符)
2. cv2.add () 函数
3. 加权加法:cv2.addWeighted () 函数
三、阈值处理:图像二值化与分割
1. 函数参数说明
2. 代码示例
四、图像平滑处理(模糊处理)
1. 常见滤波算法及函数
2. 代码示例(含噪声添加)
3. 滤波效果对比
在计算机视觉领域,OpenCV 库提供了丰富的图像处理函数,助力开发者实现各类图像编辑与分析任务。本文将围绕边界填充、图像算术运算、阈值处理以及平滑滤波等核心技术,通过具体代码示例详细讲解其实现方法与应用场景。
一、边界填充:cv2.copyMakeBorder () 函数详解
边界填充(Padding)是图像处理中常用的技术,可用于图像增强、卷积运算前的预处理等场景。OpenCV 的 cv2.copyMakeBorder()
函数提供了多种边界填充方式,能满足不同的需求。
1. 函数参数说明
cv2.copyMakeBorder(src: UMat, top: int, bottom: int, left: int, right: int, borderType: int, dst: UMat | None = ..., value: cv2.typing.Scalar = ...)
src
:要扩充边界的原始图像。top, bottom, left, right
:相应方向上的边框宽度。borderType
:边界填充类型,决定了填充像素的计算方式。value
:当borderType
为cv2.BORDER_CONSTANT
时,指定填充的常数数值。
2. 常见边界填充类型及效果
cv2.BORDER_CONSTANT
:添加常数边界,填充像素值为指定的value
。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
。
3. 代码示例
import cv2# 读取图像a = cv2.imread(\'img_1.jpg\')# 设置各方向填充宽度top, bottom, left, right = 50, 50, 50, 50# 不同类型的边界填充constant = cv2.copyMakeBorder(a, top, bottom, left, right, cv2.BORDER_CONSTANT, value=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.waitKey(0)cv2.imshow(\'CONSTANT 填充\', constant)cv2.waitKey(0)cv2.imshow(\'REFLECT 填充\', reflect)cv2.waitKey(0)cv2.imshow(\'REFLECT101 填充\', reflect101)cv2.waitKey(0)cv2.imshow(\'REPLICATE 填充\', replicate)cv2.waitKey(0)cv2.imshow(\'WRAP 填充\', wrap)cv2.waitKey(0)cv2.destroyAllWindows()
二、图像算术运算:加法与加权加法
图像算术运算包括像素值的加减乘除等操作,常用于图像融合、亮度调整等场景。OpenCV 提供了两种主要的加法运算方式:普通加法(+
运算符)和 cv2.add()
函数,以及用于图像融合的加权加法 cv2.addWeighted()
函数。
1. 普通加法(+ 运算符)
普通加法遵循 “截断规则”:当像素值相加结果小于 255 时,直接取和;当结果大于 255 时,用结果减去 256 进行截断(例如 260 - 256 = 4)。
import cv2a = cv2.imread(\'img_1.jpg\')b = cv2.imread(\'img_2.jpg\')# 单个图像像素值整体加常数(调整亮度)c = a + 10 cv2.imshow(\'原始图像\', a)cv2.imshow(\'像素值+10\', c)cv2.waitKey(0)# 图像局部区域相加c = a[50:250, 50:200] + b[50:250, 50:200]cv2.imshow(\'局部区域相加\', c)cv2.waitKey(0)cv2.destroyAllWindows()
2. cv2.add () 函数
cv2.add()
函数遵循 “饱和规则”:当像素值相加结果小于 255 时,直接取和;当结果大于 255 时,取最大值 255。
import cv2a = cv2.imread(\'img_1.jpg\')b = cv2.imread(\'img_2.jpg\')# 调整图像大小至相同尺寸b = cv2.resize(b, dsize=(400, 400))a = cv2.resize(a, dsize=(400, 400))# 图像整体相加c = cv2.add(a, b) cv2.imshow(\'cv2.add() 结果\', c)cv2.waitKey(0)cv2.destroyAllWindows()
3. 加权加法:cv2.addWeighted () 函数
加权加法可实现图像的平滑融合,公式为 dst = src1×α + src2×β + γ
,其中 α
和 β
是权重,γ
是亮度调整常数。
import cv2a = cv2.imread(\'img_1.jpg\')b = cv2.imread(\'img_2.jpg\')# 调整图像大小至相同尺寸b = cv2.resize(b, dsize=(400, 400))a = cv2.resize(a, dsize=(400, 400))# 加权融合:a 占比 0.2,b 占比 0.8,亮度补偿 10c = cv2.addWeighted(a, 0.2, b, 0.8, gamma=10) cv2.imshow(\'加权融合结果\', c)cv2.waitKey(0)cv2.destroyAllWindows()
三、阈值处理:图像二值化与分割
阈值处理通过设定像素值阈值,将图像分割为目标区域和背景区域,是图像分割的基础技术。OpenCV 的 cv2.threshold()
函数支持多种阈值分割类型。
1. 函数参数说明
retval, dst = cv2.threshold(src, thresh, maxval, type)
retval
:返回的阈值。dst
:阈值分割结果图像。src
:输入图像(可多通道,8 位或 32 位浮点型)。thresh
:设定的阈值。maxval
:type
为THRESH_BINARY
或THRESH_BINARY_INV
时的最大值。type
:阈值分割类型,具体规则如下表:
cv2.THRESH_BINARY
maxval
cv2.THRESH_BINARY_INV
maxval
cv2.THRESH_TRUNC
thresh
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
2. 代码示例
import cv2# 读取灰度图像image = cv2.imread(\'img_1.jpg\', 0) # 不同类型的阈值处理ret, binary = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY) # 二值化ret1, binaryinv = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY_INV) # 反二值化ret2, trunc = cv2.threshold(image, 150, 255, cv2.THRESH_TRUNC) # 截断处理ret3, tozero = cv2.threshold(image, 150, 255, cv2.THRESH_TOZERO) # 低于阈值置0ret4, tozeroinv = cv2.threshold(image, 150, 255, cv2.THRESH_TOZERO_INV) # 高于阈值置0# 显示结果cv2.imshow(\'原始灰度图\', image)cv2.waitKey(0)cv2.imshow(\'THRESH_BINARY\', binary)cv2.waitKey(0)cv2.imshow(\'THRESH_BINARY_INV\', binaryinv)cv2.waitKey(0)cv2.imshow(\'THRESH_TRUNC\', trunc)cv2.waitKey(0)cv2.imshow(\'THRESH_TOZERO\', tozero)cv2.waitKey(0)cv2.imshow(\'THRESH_TOZERO_INV\', tozeroinv)cv2.waitKey(0)cv2.destroyAllWindows()
四、图像平滑处理(模糊处理)
平滑处理通过消除图像中的噪声和细节,使图像变得模糊,常用于噪声抑制、边缘软化等场景。OpenCV 提供了多种平滑滤波算法,适用于不同类型的噪声和应用需求。
1. 常见滤波算法及函数
- 均值滤波:
cv2.blur()
,通过邻域像素平均值计算结果像素,适用于高斯噪声。 - 方框滤波:
cv2.boxFilter()
,可选择是否归一化,归一化时与均值滤波效果相同。 - 高斯滤波:
cv2.GaussianBlur()
,基于高斯函数计算权重,对高斯噪声抑制效果好。 - 中值滤波:
cv2.medianBlur()
,用邻域像素中位数替换中心像素,对椒盐噪声抑制效果显著。
2. 代码示例(含噪声添加)
首先定义一个添加椒盐噪声的函数,再对比不同滤波算法的效果:
import cv2import numpy as np# 添加椒盐噪声def add_peppersalt_noise(image, n=10000): result = image.copy() h, w = image.shape[:2] # 获取图像高和宽 for i in range(n): # 生成n个噪声点 x = np.random.randint(low=1, high=h) y = np.random.randint(low=1, 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\')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_63x63 = cv2.blur(noise_image, ksize=(63, 63)) # 63x63卷积核(模糊更严重)cv2.imshow(\'均值滤波(3x3)\', blur_3x3)cv2.waitKey(0)cv2.imshow(\'均值滤波(63x63)\', blur_63x63)cv2.waitKey(0)# 2. 方框滤波box_norm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=True) # 归一化(同均值滤波)box_nonorm = cv2.boxFilter(noise_image, -1, ksize=(3, 3), normalize=False) # 不归一化cv2.imshow(\'方框滤波(归一化)\', box_norm)cv2.waitKey(0)cv2.imshow(\'方框滤波(不归一化)\', box_nonorm)cv2.waitKey(0)# 3. 高斯滤波gaussian = cv2.GaussianBlur(noise_image, ksize=(3, 3), sigmaX=1) # 标准差为1cv2.imshow(\'高斯滤波(3x3)\', gaussian)cv2.waitKey(0)# 4. 中值滤波median = cv2.medianBlur(noise_image, ksize=3) # 3x3卷积核cv2.imshow(\'中值滤波(3x3)\', median)cv2.waitKey(0)cv2.destroyAllWindows()
3. 滤波效果对比
- 均值滤波和方框滤波(归一化)对高斯噪声有效,但会使图像边缘模糊。
- 高斯滤波保留边缘信息更好,适合需要保留细节的场景。
- 中值滤波是椒盐噪声的 “克星”,能有效去除噪声同时减少边缘模糊。