一、边界填充
python
cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value=None)
参数介绍:
src:
要扩充边界的原始图像
top(int):
顶部 需要添加的边框像素数((比如 top=10 表示顶部加 10 行像素))
bottom(int):
底部需要添加的边框像素数
left(int):
左侧需要添加的边框像素数
right(int):
右侧需要添加的边框像素数
bordetType:
边框填充类型,决定边界填充方式
取值:
cv2.BORDER_CONSTANT:用固定颜色填充边框(需要配合 value 参数指定颜色)
cv2.BORDER_REPLICATE:复制图像边缘的最后一个像素填充(边缘延伸)
cv2.BORDER_REFLECT:镜像填充(以边缘为轴,反射图像像素)
cv2.BORDER_WRAP:环绕填充(用图像另一侧的像素填充)
value:
仅当 borderType=cv2.BORDER_CONSTANT 时生效,指定边框的颜色(BGR 格式)
示例:
python
import cv2
yt = cv2.imread('../data/image.jpeg')
top,bottom,left,right = 50,50,50,50
# ys=cv2.resize(ys,dsize=None,fx=0.5,fy=0.5) # 图片缩放
# ys=cv2.resize(ys,(640,480))
constant = cv2.copyMakeBorder(yt,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=(200,30,80))
reflect = cv2.copyMakeBorder(yt,top,bottom,left,right,borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(yt,top,bottom,left,right,borderType=cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(yt,top,bottom,left,right,borderType=cv2.BORDER_REPLICATE)
wrap = cv2.copyMakeBorder(yt,top,bottom,left,right,borderType=cv2.BORDER_WRAP)
cv2.imshow('yuantu',yt)
cv2.waitKey(0)
cv2.imshow('CONSTANT',constant)
cv2.waitKey(0)
cv2.imshow('REFLECT',reflect)
cv2.waitKey(0)
cv2.imshow('REFLECT_101',reflect101)
cv2.waitKey(0)
cv2.imshow('REPLICATE',replicate)
cv2.waitKey(0)
cv2.imshow('WRAP',wrap)
cv2.waitKey(0)
二、图像运算
2.1 图像加法运算(+)
对于+号运算,当对图像a,图像b进行加法求和时,遵循以下规则:
当某位置像素相加得到的数值小于255时,该位置数值为两图像该位置像素相加之和
当某位置像素相加得到的数值大于255时.该位置数值将截断结果并将其减去 256 例如:相加后是260.实际是260-256=4
python
import cv2
a = cv2.imread('../data/image.jpeg')
b = cv2.imread('../data/QQ_image.png')
c = a+10
cv2.imshow('yuantu',a)
cv2.imshow('a+10',c)
cv2.waitKey(0)
c = a[4:40,4:35]+b[4:40,4:35]
cv2.imshow('a+b',c)
cv2.waitKey(0)
2.2 cv2.add()运算
当某位置像素相加得到的数值小于255时,该位置数值为两图像该位置像素相加之和
当某位置像素相加得到的数值大于255时,该位置数值为255
python
dst = cv2.add(src1, src2)
参数介绍:
src1:
第一个输入图像 / 数值(numpy 数组):可以是单通道 / 多通道图像(如灰度图 / 彩色图); 也可以是标量(单个数值),表示给整张图像的所有像素加这个值
src2:
第二个输入图像 / 数值(numpy 数组):可以是单通道 / 多通道图像(如灰度图 / 彩色图); 也可以是标量(单个数值),表示给整张图像的所有像素加这个值
python
import cv2
a = cv2.imread('../data/image.jpeg')
b = cv2.imread('../data/QQ_image.png')
a = cv2.resize(a,(400,400))
b = cv2.resize(b,(400,400))
c = cv2.add(a,b)
cv2.imshow('a add b',c)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.3 图像加权运算
即在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来
python
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma)
参数介绍:
src1:
第一个输入图像(numpy 数组):可以是单通道(灰度图)或多通道(彩色图)
alpha:
浮点数,src1 的权重(融合系数),表示 src1 占最终图像的比例(如 alpha=0.7 表示占 70%)
src2:
第二个输入图像:必须和 src1 尺寸(高、宽)、通道数完全一致
beta:
浮点数,src2 的权重(融合系数),表示 src2 占最终图像的比例
gamma:
浮点数,亮度调整值(偏置项):加到加权和结果上的常数,可提亮 / 调暗整体图像
示例:
python
import cv2
a = cv2.imread('../data/image.jpeg')
b = cv2.imread('../data/QQ_image.png')
a = cv2.resize(a,(400,400))
b = cv2.resize(b,(400,400))
c = cv2.addWeighted(a,0.8,b,0.2,10)
cv2.imshow('addweight',c)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、阈值处理
阈值处理是指剔除图像内像素值高于一定值或低于一定值的像素点
python
ret, dst = cv2.threshold(src, thresh, maxval, type)
参数:
src:
输入图像:代表要进行阈值分割的图像,可以是多通道的
thresh:
阈值(门槛值):浮点数 / 整数,比如 thresh=127 表示以 127 为分界点
maxval:
最大值:仅对部分阈值类型生效(见下文),表示「高于阈值的像素」要设置的目标值(通常设为 255,即白色)
type:
阈值分割类型(OpenCV 预定义常量):决定「像素高于 / 低于阈值时如何处理」
取值如下:
cv2.THRESH_BINARY:二值化:高于阈值→maxval,低于→0
cv2.THRESH_BINARY_INV:反二值化:高于阈值→0,低于→maxval
cv2.THRESH_TRUNC:截断:高于阈值→thresh,低于→保持原值
cv2.THRESH_TOZERO:归零:高于阈值→保持原值,低于→0
cv2.THRESH_TOZERO_INV:反归零:高于阈值→0,低于→保持原值
选项 像素值>thresh 其他情况
CV2.THRESH_BINARY maxval 0
CV2.THRESH_BINARY_INV 0 maxval
CV2.THRESH_TRUNC thresh 当前灰度值
cV2. THRESH_T0ZERO 当前灰度值 0
CV2.THRESH_TOZERO_INV 0 当前灰度值
python
import cv2
img = cv2.imread('../data/image.jpeg',cv2.IMREAD_GRAYSCALE)
ret,binary = cv2.threshold(img,170,255,cv2.THRESH_BINARY)
ret1,binaryinv = cv2.threshold(img,170,255,cv2.THRESH_BINARY_INV)
ret2,trunc = cv2.threshold(img,170,255,cv2.THRESH_TRUNC)
ret3,tozero = cv2.threshold(img,170,255,cv2.THRESH_TOZERO)
ret4,tozeroinv = cv2.threshold(img,170,255,cv2.THRESH_TOZERO_INV)
cv2.imshow('gray',img)
cv2.waitKey(0)
cv2.imshow('binary',binary)
cv2.waitKey(0)
cv2.imshow('binartinv',binaryinv)
cv2.waitKey(0)
cv2.imshow('trunc',trunc)
cv2.waitKey(0)
cv2.imshow('tozero',tozero)
cv2.waitKey(0)
cv2.imshow('tozeroinv',tozeroinv)
cv2.waitKey(0)
四、图像平滑处理(模糊处理)
4.1 增加椒盐噪声
python
import cv2
image = cv2.imread('../data/image.jpeg')
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(0,h)
y = np.random.randint(0,w)
if i in range(n):
result[x,y] = 0
else:
result[x,y] = 255
return result
cv2.imshow('yuantu',image)
cv2.waitKey(0)
noise = add_peppersalt_noise(image)
cv2.imshow('noise',noise)
cv2.waitKey(0)
4.2 滤波器
通过消除图像中的噪声或细节来使图像看起来更为模糊,从而实现平滑效果
可以用来压制、弱化、消除图像中的细节、突变和噪声
4.2.1 均值滤波
对图像每个像素取其邻域内所有像素的平均值,从而达到平滑、降噪的效果。
用滤波核覆盖区域内所有像素的平均值,替换锚点位置的像素值
python
dst = cv2.blur(src, ksize, anchor=(-1,-1), borderType=cv2.BORDER_DEFAULT)
参数介绍:
src:
输入图像(可以是单通道灰度图或多通道彩色图)
ksize:
滤波核(卷积核)的大小,格式为 (宽度, 高度),建议是正奇数 (也可填偶数,但奇数效果更稳定),ksize 数值越大,模糊效果越强,但图像细节丢失越多
anchor: (-1,-1)
核的锚点(即滤波时的参考点),表示核中对应像素的位置,一般不用改。
borderType:图像边界填充方式(默认即可)
cv2.BORDER_DEFAULT:默认填充
cv2.BORDER_CONSTANT:常量填充(黑色)
python
import cv2
import pandas as pd
image = cv2.imread('../data/image.jpeg')
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(0,h)
y = np.random.randint(0,w)
if i in range(n):
result[x,y] = 0
else:
result[x,y] = 255
return result
cv2.imshow('yuantu',image)
cv2.waitKey(0)
noise = add_peppersalt_noise(image)
cv2.imshow('noise',noise)
cv2.waitKey(0)
#均值滤波
blur_1 = cv2.blur(noise,(5,5))
cv2.imshow('blur_1',blur_1)
cv2.waitKey(0)
blur_2 = cv2.blur(noise,(13,13))
cv2.imshow('blur_2',blur_2)
cv2.waitKey(0)
4.2.2 方框滤波
用当前像素点周围nxn(ksize滤波核有关)个像素值的和来代替当前像素值。
python
cv2.boxFilter (src, ddepth, ksize, anchor,normalize, borderType)
参数介绍:
src:
需要处理的图像(单通道灰度图 / 多通道彩色图)
ddepth(int):
输出图像的深度(数据类型),常用值:cv2.CV_8U:8 位无符号整数(和原图一致)-1:表示输出图像深度与输入图像相同(建议)
ksize:
滤波核大小,格式为 (宽度, 高度),需为正整数(奇数更稳定)
anchor:
核的锚点(-1,-1)(锚点在核中心)
borderType:
图像边界填充方式
normalize(布尔值):
是否归一化
当值为True时,归一化,用邻域像素值的和除以面积。此时方框滤波与 均值滤波 效果相同。 当值为False时,不归一化,直接使用邻域像素值的和。和>255时使用255
注意:normalize=False 时,必须将 ddepth 设为 cv2.CV_32F/cv2.CV_64F,否则 8 位图像求和后会溢出(像素值被截断,出现大片白色)
python
import cv2
import pandas as pd
image = cv2.imread('../data/image.jpeg')
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(0,h)
y = np.random.randint(0,w)
if i in range(n):
result[x,y] = 0
else:
result[x,y] = 255
return result
boxFilter_1 = cv2.boxFilter(noise,-1,(3,3),normalize = True)
cv2.imshow('boxFilter_1',boxFilter_1)
cv2.waitKey(0)
boxFilter_2 = cv2.boxFilter(noise,-1,(3,3),normalize = False)
cv2.imshow('boxFilter_2',boxFilter_2)
cv2.waitKey(0)
4.2.3 高斯滤波(专门针对高斯噪声(如低光照片的颗粒感))
对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。
目标像素值 = 核内每个像素值 × 对应权重 的总和;
相比均值滤波(cv2.blur()),高斯滤波对图像的模糊更 "自然",能更好地保留图像整体轮廓,同时有效去除高斯噪声
python
dst = cv2.GaussianBlur(src, ksize, sigmaX, sigmaY=None, borderType)
参数介绍:
src:
需要处理的图像(单通道灰度图 / 多通道彩色图)
ksize:(建议奇数)
高斯核大小,格式为 (宽度, 高度)
sigmaX:
X 方向的高斯核标准差(σ),核心控制模糊程度:σ 越大,权重分布越分散,模糊越强
sigmaY:(默认None)
Y 方向的高斯核标准差,若设为 None/0(常用),自动等于 sigmaX, 若设为非 0 值,可实现 X/Y 方向不同程度的模糊。
borderType:
图像边界填充方式。
python
import cv2
import pandas as pd
image = cv2.imread('../data/image.jpeg')
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(0,h)
y = np.random.randint(0,w)
if i in range(n):
result[x,y] = 0
else:
result[x,y] = 255
return result
GaussianB = cv2.GaussianBlur(noise,(3,3),1) #标准差为1,标准正态分布
cv2.imshow('GaussianBlur',GaussianB)
cv2.waitKey(0)
4.2.4 中值滤波(仅针对椒盐噪声(黑白斑点)效果最佳,对高斯噪声(颗粒感)效果差,需搭配高斯滤波使用)
不做加权 / 平均计算,而是取滤波核内像素值的中位数替换锚点像素值。
python
cv2.medianBlur(src, ksize)
参数介绍:
src:
单通道灰度图 / 多通道彩色图(彩色图会对每个通道独立计算)(仅支持 uint8/uint16/float32 类型)
ksize:
滤波核的尺寸(边长)
python
import cv2
import pandas as pd
image = cv2.imread('../data/image.jpeg')
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(0,h)
y = np.random.randint(0,w)
if i in range(n):
result[x,y] = 0
else:
result[x,y] = 255
return result
medianB = cv2.medianBlur(noise,3)
cv2.imshow('medianBlur',medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()