OpenCV 图像操作进阶:像素、边界与融合技术
在掌握了 OpenCV 的基础操作后,我们可以深入学习更核心的图像处理技术。本文将通过实战代码解析,带你探索图像像素操作、边界填充以及图像算术运算与融合的关键技能,这些都是计算机视觉应用中的基础而重要的操作。
一、图像像素与属性操作
直接操作图像的像素和属性是深入理解图像数据结构的基础,也是进行高级处理的前提。
1. 像素访问与修改
import cv2
import numpy as npimg = cv2.imread('ocv01.jpg')# 访问像素值(BGR格式)
# px = img[100, 100] # 获取(100,100)位置的像素值
# print(px) # 输出格式:[B, G, R]# 修改像素值
# img[100, 100] = [255, 255, 255] # 将该像素设为白色
# cv2.imshow('image', img)
# cv2.waitKey(0)# 更高效的像素访问与修改(推荐使用)
# print(img.item(10, 10, 2)) # 获取(10,10)位置的红色通道值(通道索引2)
# img.itemset((10, 10, 2), 255) # 修改红色通道值为255
# print(img.item(10, 10, 2))
关键知识点:
- 直接通过
img[x,y]
访问像素直观但效率较低,适合单个像素操作 item()
和itemset()
方法更高效,尤其适合批量操作,需指定通道索引(B:0, G:1, R:2)- OpenCV 中图像默认以 BGR 格式存储,与 RGB 格式不同
2. 图像属性获取
# 获取图像属性
# print(img.shape) # 输出(高度, 宽度, 通道数),灰度图无通道数
# print(img.size) # 输出总像素数(高度×宽度×通道数)
# print(img.dtype) # 输出数据类型(通常为uint8)
应用价值:
shape
用于判断图像尺寸和类型(彩色 / 灰度)size
帮助计算图像数据量大小dtype
至关重要,错误的类型会导致很多 OpenCV 函数报错
3. ROI(感兴趣区域)操作
ROI 是指从图像中提取的特定区域,便于聚焦处理图像的关键部分:
# 定义ROI([y1:y2, x1:x2])
# roi = img[500:600, 500:600] # 提取500-600行、500-600列的区域
# img[200:300, 200:300] = roi # 将ROI复制到图像的另一个位置
# cv2.imshow('image', img)
# cv2.waitKey(0)
使用场景:
- 图像局部区域的单独处理(如人脸区域的特效处理)
- 图像局部复制、移动(如物体克隆)
4. 通道分离与合并
彩色图像由 B、G、R 三个通道组成,可单独处理每个通道:
# 通道分离与合并
# b, g, r = cv2.split(img) # 分离三个通道(耗时操作)
# img = cv2.merge((r, g, b)) # 合并通道(转换为RGB格式)# 更高效的通道提取(推荐)
b = img[:, :, 0] # 提取蓝色通道(所有行,所有列,第0通道)
cv2.imshow('blue', b) # 显示蓝色通道(灰度图形式,值越高表示该通道分量越重)
cv2.waitKey(0)
注意:cv2.split()
效率较低,对于大型图像,直接通过索引提取通道(img[:,:,0]
)更高效。
二、图像边界填充
在许多图像处理任务(如卷积操作、特征提取)中,需要对图像进行边界填充。OpenCV 提供了多种填充方式:
import cv2
import numpy as np
from matplotlib import pyplot as pltimg = cv2.imread('ocv02.jpg')# 创建不同类型的边界填充
replicate = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REPLICATE) # 复制边缘像素
reflect = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REFLECT) # 镜像反射(包括边缘像素)
reflect101 = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_REFLECT_101)# 镜像反射(不包括边缘像素)
wrap = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_WRAP) # 外包装(循环填充)
constant = cv2.copyMakeBorder(img, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=(255,0,0))# 常量填充(蓝色)# 显示所有填充效果
plt.subplot(231), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('Original')
plt.subplot(232), plt.imshow(cv2.cvtColor(replicate, cv2.COLOR_BGR2RGB)), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(cv2.cvtColor(reflect, cv2.COLOR_BGR2RGB)), plt.title('REFLECT')
plt.subplot(234), plt.imshow(cv2.cvtColor(reflect101, cv2.COLOR_BGR2RGB)), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(cv2.cvtColor(wrap, cv2.COLOR_BGR2RGB)), plt.title('WRAP')
plt.subplot(236), plt.imshow(cv2.cvtColor(constant, cv2.COLOR_BGR2RGB)), plt.title('CONSTANT')plt.show()
函数解析:cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value)
src
:输入图像top/bottom/left/right
:上下左右的填充宽度borderType
:填充类型(上述 5 种)value
:BORDER_CONSTANT
时的填充颜色(BGR 格式)
应用场景:
- 卷积操作中保持输出图像尺寸
- 图像拼接时处理边缘对齐
- 视觉效果增强(如添加相框)
三、图像算术运算与融合
图像算术运算包括加法、加权加法等,而基于掩码的融合技术则能实现更复杂的图像合成效果。
1. 基本算术运算
import cv2
import numpy as np# 图像加法
# img = cv2.imread('ocv01.jpg')
# cv2.add(img, img, img) # 每个像素值翻倍(超过255则截断为255)
# cv2.imshow('image', img)
# cv2.waitKey(0)# OpenCV加法 vs NumPy加法
x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y)) # OpenCV加法:饱和操作(250+10=260→255)
print(x + y) # NumPy加法:模运算(250+10=260→4)
核心区别:
- OpenCV 的
cv2.add()
会进行饱和处理(超过 255 则取 255) - NumPy 的
+
运算会进行模运算(超过 255 则对 256 取余) - 处理图像时应优先使用 OpenCV 的函数,避免像素值异常
2. 加权加法(图像混合)
加权加法可实现两张图像的平滑过渡融合:
# 图像加权融合
# img1 = cv2.imread('ocv01.jpg')
# img2 = cv2.imread('ocv02.jpg')
# if img1.size != img2.size: # 确保两张图像尺寸相同
# img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))# # 加权公式:dst = α×img1 + β×img2 + γ
# dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0) # 70% img1 + 30% img2
# cv2.imshow('dst', dst)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
参数意义:cv2.addWeighted(img1, α, img2, β, γ)
α
和β
:两张图像的权重(α + β 通常为 1)γ
:亮度调节值(偏移量)- 应用场景:图像淡入淡出效果、数据增强中的图像混合
3. 基于掩码的图像融合
通过掩码(mask)可以实现更精细的图像融合,只将前景物体融合到目标图像中:
# 基于掩码的图像融合
img1 = cv2.imread('ocv01.jpg') # 背景图像
img2 = cv2.imread('ocv02.jpg') # 前景图像# 确保前景图像尺寸小于背景图像,获取前景图像尺寸
rows, cols, channels = img2.shape
# 定义背景图像中的ROI(放置前景的位置)
roi = img1[0:rows, 0:cols]# 1. 创建前景图像的掩码
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) # 转换为灰度图
# 阈值处理:大于175的像素设为255(白色),否则设为0(黑色),取反
ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY_INV)
mask_inv = cv2.bitwise_not(mask) # 掩码反转(前景变背景,背景变前景)# 2. 提取ROI中的背景和前景中的物体
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) # ROI中与掩码重叠的背景
img2_fg = cv2.bitwise_and(img2, img2, mask=mask) # 前景图像中的物体# 3. 融合背景和前景
dst = cv2.add(img1_bg, img2_fg)
# 将融合结果放回背景图像的ROI位置
img1[0:rows, 0:cols] = dstcv2.imshow('res', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
核心原理:
- 掩码(mask)是单通道图像,用于标记前景(白色)和背景(黑色)
bitwise_and
操作只保留与掩码白色区域重叠的像素- 分离背景和前景后,通过加法实现精确融合
应用场景:
- 图像水印添加(只保留水印区域)
- 物体替换(将 A 图中的物体放到 B 图中)
- 图像合成(如证件照换背景)
总结
本文介绍的图像操作技术是 OpenCV 应用的核心基础,包括:
- 像素级操作:高效访问、修改像素,获取图像属性
- ROI 处理:聚焦关键区域,实现局部操作
- 通道分离:单独处理 BGR 三个通道
- 边界填充:多种填充方式满足不同预处理需求
- 算术运算:加法与加权融合实现图像混合
- 掩码融合:精确控制图像合成效果
这些技术看似基础,却是实现高级计算机视觉任务(如目标检测、图像分割、风格迁移)的基石。在实际应用中,需根据具体需求选择合适的操作,并注意图像格式(BGR/RGB)、尺寸匹配等细节问题。