Opencv 边界填充 图像运算 阈值处理 和图像平滑处理
目录
一.边界填充
1.边界填充实现方法(cv2.copyMakeBorder())
2.边界填充样式参数
3.简单案例
二.图像加法运算
1.直接图片相加与add()方法对比
2.加权运算(图像融合)
三.阈值处理
1.阈值处理概述
2.阈值处理类型与效果
四.图像平滑处理
1.图像平滑处理(模糊处理概述)
2.四种滤波方法介绍
3.实现人为的噪声添加方法
4.均值滤波
①均值滤波处理原理与实现
②平滑处理效果与局限性
5.方框滤波
6.高斯滤波
7.中值滤波
五.视频平滑处理案例
一.边界填充
1.边界填充实现方法(cv2.copyMakeBorder())
- 第一步读取图片,若图片过大建议先缩放尺寸以便观察边界填充效果。
- 设置边界填充参数(如
top
,bottom
,left
,right
均为50),数值可自定义调整。 - 使用 copyMakeBorder() 进行边界填充,需指定图片对象、边界大小及填充样式。
2.边界填充样式参数
BORDER_CONSTANT
:以指定颜色填充边界(如RGB值需注意通道顺序为BGR)。BORDER_REFLECT
:镜面反射填充,对称轴两侧内容完全反射。BORDER_REFLECT_101
:类似镜面反射,但删除交界处像素(反射时不包含边界元素)。BORDER_REPLICATE
:以最边界像素值拉伸填充。BORDER_WRAP
:上下左右区域依次颠倒替换填充。
3.简单案例
import cv2
img1=cv2.imread('img1.png')
new_img=cv2.resize(img1,dsize=None,fx=0.5,fy=0.5)
top,bottom,left,right=50,50,50,50
#添加的边框像素值为常数
constant=cv2.copyMakeBorder(new_img,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=(223,34,23))
#添加的边框像素值是边界元素的镜面反射
reflect=cv2.copyMakeBorder(new_img,top,bottom,left,right,borderType=cv2.BORDER_REFLECT)
#和上面相似但边界交接处删了
reflect101=cv2.copyMakeBorder(new_img,top,bottom,left,right,borderType=cv2.BORDER_REFLECT101)
#使用最边界的像素值代替
replicate=cv2.copyMakeBorder(new_img,top,bottom,left,right,borderType=cv2.BORDER_REPLICATE)
#上下左右依次替换
wrap=cv2.copyMakeBorder(new_img,top,bottom,left,right,borderType=cv2.BORDER_WRAP)
cv2.imshow('yuantu',new_img)
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)
二.图像加法运算
1.直接图片相加与add()方法对比
- 直接相加(+):图片的指定区域相加后,颜色混合杂乱,但保留部分原图特征
add()
方法:相同图片相加后,大部分区域变为白色。原因为超限像素值被强制设为255(白色),导致特征丢失。- 关键区别:直接相加通过与256取余处理超限值(如260→260-256=4),
add()
方法直接截断为255。类似现象出现在减法(如减100)和乘法(如乘2)运算中,均遵循数值截断规则(负数或超限值通过取余调整至0-255范围)
import cv2
img1=cv2.imread('img1.jpg')
a=cv2.resize(img1,dsize=None,fx=0.5,fy=0.5)
img2=cv2.imread('img2.png')
b=cv2.resize(img2,dsize=None,fx=0.5,fy=0.5)
#+号运算中当某位置像素相加得到的数值大于255则该位置数值为该数值对256取余,例如时260,则最后数值是260-256=4
c=a+10
cv2.imshow('yuan',a)
cv2.imshow('a+10',c)
cv2.waitKey(0)c=a[220:330,30:330]+b[220:330,30:330]
cv2.imshow('a+b',c)
cv2.waitKey(0)a=cv2.resize(a,(400,400))
b=cv2.resize(b,(400,400))
#add()方法中当某位置像素相加得到的数值大于255则该位置数值就为255了
c=cv2.add(a,b)
cv2.imshow('a add b',c)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.加权运算(图像融合)
使用addWeighted()
方法,通过权重分配实现图像融合。
在计算两幅图的像素值之和时,将每幅图的权重考虑进来,可用公式表示dst=src1*alpha+src2*beta+gamma即结果 = 图片1×权重1 + 图片2×权重2 + 常数(伽马值)
img1=cv2.imread('img1.jpg')
a=cv2.resize(img1,dsize=None,fx=0.5,fy=0.5)
img2=cv2.imread('img2.png')
b=cv2.resize(img2,dsize=None,fx=0.5,fy=0.5)
#图像加权运算
#在计算两幅图的像素值之和时,将每幅图的权重考虑进来,可用公式表示dst=src1*alpha+src2*beta+gamma
c=cv2.addWeighted(a,0.5,b,0.5,10)#10图像的亮度值,添加到权和上
cv2.imshow('addWeighed c',c)
cv2.waitKey(0)
cv2.destroyAllWindows()
三.阈值处理
1.阈值处理概述
- 阈值处理是图像预处理的重要步骤,用于将图像转换为二值化形式(仅包含黑白两种像素值)。
- 核心方法:
cv2.threshold()
,包含四个参数:src
:待处理的图像(如灰度图)。thresh
:手动设置的阈值(如175)。maxval
:最大值(如255)。type
:阈值处理类型(决定规则)。
cv2.threshold()
返回值说明:- 第一个返回值(
ret
):实际使用的阈值(通常与输入一致)。 - 第二个返回值(
dst
):处理后的二值化图像。
- 第一个返回值(
2.阈值处理类型与效果
注意:阈值thresh
需根据具体图像调整(如175仅为示例)。
THRESH_BINARY
:- 规则:像素值 >
thresh
→maxval
(白);否则 → 0(黑)。 - 效果:原图中较亮区域变纯白,较暗区域变纯黑。
- 规则:像素值 >
THRESH_BINARY_INV
:- 规则:与
BINARY
相反(>thresh
→ 0;否则 →maxval
)。 - 效果:亮暗区域颜色反转。
- 规则:与
THRESH_TRUNC
:- 规则:>
thresh
→thresh
(灰);否则保持原灰度值。 - 效果:亮区域变灰,暗区域不变。
- 规则:>
THRESH_TOZERO
:- 规则:>
thresh
→ 保持原值;否则 → 0。 - 效果:亮区域不变,暗区域变黑。
- 规则:>
THRESH_TOZERO_INV
:- 规则:>
thresh
→ 0;否则 → 保持原值。 - 效果:亮区域变黑,暗区域不变。
- 规则:>
import cv2
# image=cv2.imread('img1.jpg')
image=cv2.imread('img1.jpg',0)
image=cv2.resize(image,dsize=None,fx=0.5,fy=0.5)
ret,binary=cv2.threshold(image,175,255,cv2.THRESH_BINARY)
ret,binary_inv=cv2.threshold(image,175,255,cv2.THRESH_BINARY_INV)
ret,trunc=cv2.threshold(image,175,255,cv2.THRESH_TRUNC)
ret,tozero=cv2.threshold(image,175,255,cv2.THRESH_TOZERO)
ret,tozero_inv=cv2.threshold(image,175,255,cv2.THRESH_TOZERO_INV)
cv2.imshow('yuantu',image)
cv2.waitKey(0)
cv2.imshow('binary',binary)
cv2.waitKey(0)
cv2.imshow('binary_inv',binary_inv)
cv2.waitKey(0)
cv2.imshow('trunc',trunc)
cv2.waitKey(0)
cv2.imshow('tozero',tozero)
cv2.waitKey(0)
cv2.imshow('tozero_inv',tozero_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()
四.图像平滑处理
1.图像平滑处理(模糊处理概述)
- 通过消除噪声或细节使图像更平滑,但会导致图像轻微模糊。
- 主要功能:去除噪声、压制弱化细节突变。
2.四种滤波方法介绍
均值滤波:用当前像素点周围N×N个像素值的平均值代替当前像素值
方框滤波:用邻域像素的和替换中心像素(若未归一化),或归一化后等同于均值滤波。
高斯滤波:
- 高斯滤波通过卷积核权重分布实现,权重基于高斯分布确定。中心权重最高(如0.4),相邻方格权重递减(如0.1),拐角权重最低(如0.05)。
- 权重计算依据方格与中心的位置距离(X值),距离越近权重越大。
中值滤波:取像素邻域内所有值的中位数作为当前像素值,排序后过滤极端值(如0和255)。
3.实现人为的噪声添加方法
- 通过随机生成坐标点(行、列),并在这些位置随机赋值为0(黑点)或255(白点),模拟椒盐噪声。
- 噪声数量由参数
n
控制(默认1万次循环),黑白点概率各50%。 - 代码步骤:复制原图→循环生成随机坐标→随机赋值→返回噪声图像。
可通过下面自定义方法实现:
def add_noise(img,n=10000):result=img.copy()h,w=result.shape[:2]for i in range(n):x=np.random.randint(1,h)y=np.random.randint(1,w)if np.random.randint(0,2)==1:result[x,y]=0else:result[x,y]=1return result
4.均值滤波
①均值滤波处理原理与实现
- 均值滤波通过遍历图片,计算每个像素点周围区域(如3x3、5x5等奇数尺寸卷积核)的像素平均值,并用该值替换中心像素。
- 边界处理:为避免图片缩小,需对边界进行填充(如零填充或复制边缘像素)。
- 卷积核大小必须为奇数(如3、5、7),偶数会导致无法定位中心像素。
- 代码实现:使用OpenCV的
cv2.blur()
函数,参数包括输入图像和卷积核尺寸(如(3,3)
)。 - 效果:噪声点被模糊化,但图片可能失真;卷积核越大,平滑效果越强,但失真也更明显。
img=cv2.imread('img1.jpg')
img=cv2.resize(img,dsize=None,fx=0.5,fy=0.5)
img_add_noise=add_noise(img)
cv2.imshow('yuantu',img)
cv2.waitKey(0)
cv2.imshow('noise',img_add_noise)
cv2.waitKey(0)
# 均值滤波
blur1= cv2.blur(img_add_noise,ksize=(3,3))
cv2.imshow('blur1',blur1)
cv2.waitKey(0)
blur2= cv2.blur(img_add_noise,ksize=(63,63))
cv2.imshow('blur2',blur2)
cv2.waitKey(0)
- 通过代码人为添加噪声(黑白点,称为“椒盐噪声”)。
- 均值滤波处理后,噪声减弱但图像变模糊(失真)。
- 参数调整(如从3×3改为63×63)会显著增加模糊效果。
②平滑处理效果与局限性
- 平滑后颜色过渡更平缓,但边界清晰度降低。
- 均值滤波对椒盐噪声效果一般,需结合其他滤波方法优化。
5.方框滤波
- 原理:用邻域像素的和替换中心像素(若未归一化),或归一化后等同于均值滤波。
- 参数
normalize
:True
:求和后除以面积,等效均值滤波。False
:直接使用像素和,易导致值超过255(显示为白色)。
- 代码实现:
cv2.boxFilter()
,需指定图像深度(-1
表示同原图)、卷积核尺寸及归一化标志。 - 效果:未归一化时图片大面积变白,实用性较低;归一化后与均值滤波一致。
#方框滤波
boxFilter1=cv2.boxFilter(img_add_noise,-1,(3,3),normalize=True)#结果与均值滤波相同
cv2.imshow('boxFilter1',boxFilter1)
cv2.waitKey(0)
boxFilter2=cv2.boxFilter(img_add_noise,-1,(3,3),normalize=False)
cv2.imshow('boxFilter2',boxFilter2)
cv2.waitKey(0)
- 均值滤波后图片可能模糊,需权衡噪声去除与细节保留。
- 方框滤波未归一化时结果异常,通常仅用于特定场景。
6.高斯滤波
原理与应用:
- 高斯滤波通过卷积核权重分布实现,权重基于高斯分布确定。中心权重最高(如0.4),相邻方格权重递减(如0.1),拐角权重最低(如0.05)。
- 权重计算依据方格与中心的位置距离(X值),距离越近权重越大。
- 代码实现:
cv2.GaussianBlur()
,参数包括输入图像、卷积核大小(如3x3)、标准差(如1)。 - 效果评估:对椒盐噪声处理效果一般,噪声点仍可见,建议调整卷积核大小(如5x5或7x7)优化。
#高斯滤波 gauss1= cv2.GaussianBlur(img_add_noise,ksize=(3,3),sigmaX=1)#标准差为1 cv2.imshow('gauss1',gauss1) cv2.waitKey(0)
7.中值滤波
中值滤波原理与优势:
- 原理:取像素邻域内所有值的中位数作为当前像素值,排序后过滤极端值(如0和255)。
- 对椒盐噪声效果显著,因噪声点(黑白点)被排序至两端,中位数取中间值有效消除噪声。
- 代码实现:
cv2.medianBlur()
,参数为输入图像和卷积核大小(如3)。 - 对比展示:中值滤波处理后图像清晰度高,噪声基本消除,优于均值滤波和高斯滤波。
#中值滤波
media= cv2.medianBlur(img_add_noise,ksize=3)#这里3就表示3×3
cv2.imshow('media',media)
cv2.waitKey(0)
cv2.destroyAllWindows()
五.视频平滑处理案例
- 任务:对视频文件
test.avi
逐帧添加椒盐噪声(每帧1万个黑白点),选择合适的平滑方法处理,要求去噪且保留清晰度。 - 输出要求:同时显示原视频、噪声视频和处理后视频的窗口。
- 推荐方法:中值滤波(效果最佳)。
import cv2
import numpy as np
def add_noise(img,n=10000):result=img.copy()h,w=img.shape[:2]for i in range(n):x=np.random.randint(1,h)y=np.random.randint(1,w)if np.random.randint(1,3)==1:result[x, y]=1else:result[x,y]=0return resultvideo=cv2.VideoCapture('test.avi')
if not video.isOpened():print('视频打开失败')exit()
while True:ret,frame=video.read()cv2.imshow('video', frame)if not ret:breakframe_addNoise=add_noise(frame)cv2.imshow('frame_addNoise', frame_addNoise)media= cv2.medianBlur(frame_addNoise,ksize=3)cv2.imshow('media',media)if cv2.waitKey(20)==27:break
video.release()
cv2.destroyAllWindows()