在上一篇中,我们学习了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,则根据fxfy计算

  • 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加法(饱和运算)的区别,并学习了加权融合

  • 掌握了五种边界填充方式的原理与应用。

这些基础操作是后续学习图像滤波、特征提取、深度学习预处理等进阶内容的重要基石。建议读者动手运行代码,观察不同参数带来的变化,在实践中加深理解。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐