OpenCV 零基础入门(二):图像修改、缩放、运算与边界填充
本文是OpenCV入门系列第二篇,详细介绍了视频处理、颜色通道操作、图像修改与缩放等核心功能。主要内容包括:1)视频读取与实时灰度处理的完整流程;2)BGR通道的拆分合并及单通道保留方法;3)图像修改技巧(马赛克效果和图像拼接);4)两种图像缩放方式及其注意事项。文章采用逐行语法解析+注意事项+核心说明的形式,特别强调了OpenCV特有的BGR顺序、数组形状匹配、资源释放等关键点,帮助开发者避免常
在上一篇中,我们学习了OpenCV的图像读写、视频处理、ROI和颜色通道操作。本篇将继续深入,介绍图像修改、缩放、多种图像运算以及边界填充技巧,这些都是日常图像处理中非常实用的功能。
一、图片修改
1. 图片打码
通过NumPy数组的切片赋值,可以轻松实现对图像特定区域的“打码”效果。其原理是将目标区域替换为随机生成的像素值。
import cv2
import numpy as np
# 读取图像
a = cv2.imread(r'./timg98.jpg')
# 将指定区域(行20~230,列200~300)替换为随机像素
# 注意:赋值矩阵的尺寸必须与切片区域完全一致 (210, 100, 3)
a[20:230, 200:300] = np.random.randint(0, 256, (210, 100, 3))
cv2.imshow('masaike', a)
cv2.waitKey(1000) # 显示1秒
cv2.destroyAllWindows()
运行结果说明:

原图的某矩形区域被彩色噪点覆盖,实现简单的马赛克或遮挡效果。
2. 图片组合
将一张图像的局部区域复制到另一张图像的指定位置,可以用于图像拼接、水印添加等场景。关键点是两个区域的尺寸必须相等。
import cv2
a = cv2.imread('timg98.jpg')
b = cv2.imread('zl.png')
# 将a图的某区域(行50~300,列100~250)复制到b图的指定区域(行100~350,列200~350)
# 尺寸必须一致:a的区域大小为250x150,b的区域也是250x150
b[100:350, 200:350] = a[50:300, 100:250]
cv2.imshow('b', b)
cv2.imshow('a', a)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果说明:

显示两张图像,其中b图的指定位置嵌入了a图的局部区域,实现了图像的组合。
二、图片缩放
cv2.resize()是OpenCV中调整图像大小的核心函数,支持指定目标尺寸或缩放比例。
函数参数
-
src:输入图像(NumPy数组)
-
dsize:输出图像尺寸,格式为(宽, 高)。若为
None,则根据fx和fy计算 -
fx:水平方向的缩放比例
-
fy:垂直方向的缩放比例
-
interpolation:插值方式(默认
cv2.INTER_LINEAR)
python
import cv2
a = cv2.imread('timg98.jpg')
# 方式一:指定目标尺寸(宽200,高600)
a_new1 = cv2.resize(a, (200, 600))
# 方式二:指定缩放比例(宽高各缩小0.5倍)
a_new2 = cv2.resize(a, dsize=None, fx=0.5, fy=0.5)
cv2.imshow('a', a)
cv2.imshow('a_new1 (200x600)', a_new1)
cv2.imshow('a_new2 (0.5x)', a_new2)
print("原图尺寸 (高,宽,通道):", a.shape)
print("缩放1尺寸:", a_new1.shape)
print("缩放2尺寸:", a_new2.shape)
cv2.waitKey(100000)
cv2.destroyAllWindows()
运行结果说明:


三个窗口分别显示原图、固定尺寸缩放和比例缩放(保持宽高比)的效果,控制台输出对应的形状信息。
三、图像运算
图像运算是指对两张或多张图像的像素值进行数学运算,生成新的图像。OpenCV提供了多种运算方式,需注意不同方法的区别。
1. 加法运算(NumPy加法)
NumPy的+运算符对图像进行逐像素加法,属于模运算:当像素值超过255时,会对256取模(例如260 → 260%256=4)。
import cv2
a = cv2.imread('timg98.jpg')
b = cv2.imread('zl.png')
# 示例1:图像整体加常数(亮度提升)
c = a + 10
cv2.imshow('yuan', a)
cv2.imshow('a+10', c)
# 示例2:两张图像对应区域相加(必须尺寸相同)
c_region = a[50:450, 50:400] + b[50:450, 50:400]
cv2.imshow('a+b (区域)', c_region)
cv2.waitKey(100000)
cv2.destroyAllWindows()
特点:由于模运算,相加后可能产生非预期的暗区或色彩失真(例如原本很亮的区域相加后反而变暗)。
运算结果说明:

2. 加法运算(OpenCV的cv2.add)
cv2.add()执行的是饱和运算:当像素值超过255时,直接取255(最大值)。这更符合人眼对亮度的感知。
import cv2
a = cv2.imread('timg98.jpg')
b = cv2.imread('zl.png')
# 确保两张图尺寸一致
b = cv2.resize(b, (400, 400))
a = cv2.resize(a, (400, 400))
c = cv2.add(a, b)
cv2.imshow('a add b', c)
cv2.waitKey(100000)
cv2.destroyAllWindows()
运行结果说明:

两种加法对比:
| 运算方式 | 超过255时的处理 | 适用场景 |
|---|---|---|
a + b |
取模(模运算) | 特殊效果、图像加密 |
cv2.add(a, b) |
截断至255(饱和运算) | 常规图像融合、亮度叠加 |
3. 加权运算(cv2.addWeighted)
加权运算可以按不同比例混合两张图像,并添加一个亮度常数,公式为:dst = src1 × α + src2 × β + γ
import cv2
a = cv2.imread('timg98.jpg')
b = cv2.imread('zl.png')
b = cv2.resize(b, (400, 400))
a = cv2.resize(a, (400, 400))
# α=0.5, β=0.5, γ=0 (各占50%,无额外亮度)
c = cv2.addWeighted(a, 0.5, b, 0.5, 0)
cv2.imshow('addWeighted', c)
cv2.waitKey(100000)
cv2.destroyAllWindows()
参数说明:
-
α、β:两张图像的权重(通常和为1,但非必须) -
γ:添加到结果的亮度常数,可调整整体明暗
运行结果:

两张图像半透明叠加,效果平滑自然。
四、边界填充
在卷积神经网络、图像滤波等任务中,经常需要为图像添加边框。cv2.copyMakeBorder()提供了五种填充方式。
函数语法
cv2.copyMakeBorder(src, top, bottom, left, right, borderType[, value])
参数详解
-
src:输入图像
-
top, bottom, left, right:四个方向要填充的像素数
-
borderType:填充类型(核心参数)
-
value:当
borderType=cv2.BORDER_CONSTANT时,指定填充颜色(BGR格式)
五种填充方式示例
import cv2
ys = cv2.imread('mei.jpg')
ys = cv2.resize(ys, dsize=None, fx=0.5, fy=0.6) # 缩放便于观察
top = bottom = 100
left = right = 50
# 五种填充方式
constant = cv2.copyMakeBorder(ys, top, bottom, left, right,
cv2.BORDER_CONSTANT, value=(80, 25, 229)) # 紫红色
reflect = cv2.copyMakeBorder(ys, top, bottom, left, right,
cv2.BORDER_REFLECT) # 反射填充
reflect101 = cv2.copyMakeBorder(ys, top, bottom, left, right,
cv2.BORDER_REFLECT_101) # 对称填充
replicate = cv2.copyMakeBorder(ys, top, bottom, left, right,
cv2.BORDER_REPLICATE) # 复制填充
wrap = cv2.copyMakeBorder(ys, top, bottom, left, right,
cv2.BORDER_WRAP) # 外包装填充
cv2.imshow('yuantu', ys)
cv2.imshow('CONSTANT', constant)
cv2.imshow('REFLECT', reflect)
cv2.imshow('REFLECT_101', reflect101)
cv2.imshow('REPLICATE', replicate)
cv2.imshow('WRAP', wrap)
cv2.waitKey(0)
cv2.destroyAllWindows()
填充类型详解
| 类型 | 原理说明 | 示意图(假设原图行像素为abcdefgh) |
|---|---|---|
| BORDER_CONSTANT | 用指定颜色填充边框 | 纯色边框 |
| BORDER_REFLECT | 边框像素是原图边缘的镜像反射(不包含边缘像素本身) | fedcba|abcdefgh|hgfedcb |
| BORDER_REFLECT_101 | 类似反射,但以边缘像素为轴(包含边缘像素) | gfedcb|abcdefgh|gfedcba |
| BORDER_REPLICATE | 边框像素由最边缘的像素复制而来 | aaaaaa|abcdefgh|hhhhhhh |
| BORDER_WRAP | 边框像素从图像对侧“缠绕”而来,类似平铺 | cdefgh|abcdefgh|abcdefg |
运行结果说明:
六个窗口依次展示原图及五种填充效果,可以直观看到常数填充的纯色边框、反射填充的镜像效果、复制填充的条纹延伸等不同视觉效果。
五、总结
本文详细介绍了OpenCV中图像修改、缩放、运算和边界填充的核心操作:
-
通过NumPy切片实现了打码和图像组合;
-
使用
resize灵活调整图像尺寸; -
区分了NumPy加法(模运算)与OpenCV加法(饱和运算)的区别,并学习了加权融合;
-
掌握了五种边界填充方式的原理与应用。
这些基础操作是后续学习图像滤波、特征提取、深度学习预处理等进阶内容的重要基石。建议读者动手运行代码,观察不同参数带来的变化,在实践中加深理解。
更多推荐
所有评论(0)