OpenCV图像算术运算完全指南
mindmap
root((图像运算))
基础运算
加/减 : 曝光调整
乘/除 : 对比度调节
位运算 : 掩模操作
高级应用
图像融合
水印添加
背景替换
性能优化
LUT加速
并行处理
一、基础算术运算
1.1 四则运算原理
classDiagram
class PixelMath {
<>
+add()
+subtract()
+multiply()
+divide()
}
class OpenCV {
+addWeighted()
+bitwise_and()
+threshold()
}
class NumPy {
+clip()
+astype()
}
PixelMath <|-- OpenCV
PixelMath <|-- NumPy
运算公式对比
运算类型 | 数学表达 | 饱和处理 | 典型应用 |
---|---|---|---|
加法 | dst = src1 + src2 | cv2.add() | 图像增亮 |
减法 | dst = src1 - src2 | cv2.subtract() | 背景消除 |
乘法 | dst = src1 * src2 / scale | cv2.multiply() | 对比度增强 |
除法 | dst = scale * src1 / src2 | cv2.divide() | 光照归一化 |
1.2 基础运算实现
python
import cv2
import numpy as np
# 创建示例图像
img1 = cv2.imread('img1.jpg')
img2 = cv2.imread('img2.jpg')
# 安全加法(防止溢出)
add_result = cv2.add(img1, img2)
# 带权重的减法
sub_result = cv2.subtract(img1 * 1.5, img2 * 0.5)
# 乘法运算(对比度增强)
mult_result = cv2.multiply(img1, 1.2)
# 除法运算(光照补偿)
div_result = cv2.divide(img1, img2 + 1) # 避免除零
C++实现
cpp
#include <opencv2/opencv.hpp>
using namespace cv;
Mat img1 = imread("img1.jpg");
Mat img2 = imread("img2.jpg");
// 安全运算
Mat add_result, sub_result;
add(img1, img2, add_result);
subtract(img1, img2, sub_result);
// 标量乘法
Mat mult_result;
multiply(img1, Scalar(1.2, 1.2, 1.2), mult_result);
二、图像融合技术
2.1 线性混合(Alpha融合)
flowchart TD
A[图像1] --> C[addWeighted]
B[图像2] --> C
D[权重α] --> C
E[权重β] --> C
C --> F[融合结果]
渐变融合效果
python
# 创建水平渐变权重
h, w = img1.shape[:2]
alpha = np.tile(np.linspace(0, 1, w), (h, 1))
alpha = cv2.merge([alpha]*3) # 转为3通道
# 自定义融合
blend = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
custom_blend = img1 * alpha + img2 * (1 - alpha)
2.2 金字塔融合
gantt
title 金字塔融合流程
dateFormat X
axisFormat %s
section 处理步骤
高斯金字塔构建 : 0, 3
拉普拉斯金字塔 : 3, 6
层级融合 : 6, 9
重建图像 : 9, 12
无缝拼接实现
python
def pyramid_blend(img1, img2, mask, levels=5):
# 生成高斯金字塔
G1 = img1.copy()
G2 = img2.copy()
GM = mask.copy()
gp1 = [G1]
gp2 = [G2]
gpM = [GM]
for _ in range(levels):
G1 = cv2.pyrDown(G1)
G2 = cv2.pyrDown(G2)
GM = cv2.pyrDown(GM)
gp1.append(G1)
gp2.append(G2)
gpM.append(GM)
# 生成拉普拉斯金字塔
lp1 = [gp1[levels-1]]
lp2 = [gp2[levels-1]]
for i in range(levels-1,0,-1):
GE1 = cv2.pyrUp(gp1[i])
GE2 = cv2.pyrUp(gp2[i])
L1 = cv2.subtract(gp1[i-1], GE1)
L2 = cv2.subtract(gp2[i-1], GE2)
lp1.append(L1)
lp2.append(L2)
# 逐层融合
LS = []
for l1,l2,gm in zip(lp1,lp2,gpM):
ls = l1 * gm + l2 * (1 - gm)
LS.append(ls)
# 重建图像
ls_ = LS[0]
for i in range(1,levels):
ls_ = cv2.pyrUp(ls_)
ls_ = cv2.add(ls_, LS[i])
return ls_
三、位运算与遮罩
3.1 位操作原理
pie
title 位运算使用场景
"掩模应用" : 45
"ROI提取" : 30
"水印嵌入" : 15
"其他" : 10
实战:Logo添加
python
# 读取主图和Logo
img = cv2.imread('background.jpg')
logo = cv2.imread('logo.png', cv2.IMREAD_UNCHANGED)
# 提取Alpha通道
alpha = logo[:,:,3] / 255.0
logo = logo[:,:,:3]
# 定位叠加位置
x, y = 100, 50
roi = img[y:y+logo.shape[0], x:x+logo.shape[1]]
# 融合处理
for c in range(3):
roi[:,:,c] = roi[:,:,c] * (1 - alpha) + logo[:,:,c] * alpha
3.2 高级遮罩应用
flowchart LR
A[原始图像] --> B[创建掩模]
B --> C{位运算选择}
C -->|AND| D[区域提取]
C -->|OR| E[图像合成]
C -->|XOR| F[特效生成]
C -->|NOT| G[反相处理]
背景替换案例
python
# 创建HSV颜色掩模
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_green = np.array([35, 50, 50])
upper_green = np.array([85, 255, 255])
mask = cv2.inRange(hsv, lower_green, upper_green)
# 优化掩模边缘
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# 替换背景
bg = cv2.imread('new_bg.jpg')
bg = cv2.resize(bg, (img.shape[1], img.shape[0]))
result = np.where(mask[...,None]==0, img, bg)
四、性能优化技巧
4.1 LUT加速技术
stateDiagram-v2
[*] --> 创建查找表
创建查找表 --> 预计算映射
预计算映射 --> 应用LUT
应用LUT --> 输出结果
批量像素变换
python
# 创建Gamma校正LUT
gamma = 0.5
lut = np.array([((i / 255.0) ** gamma) * 255
for i in range(256)], dtype=np.uint8)
# 应用查找表
result = cv2.LUT(img, lut)
# 多通道分别处理
luts = [lut] * 3 # 每个通道相同处理
result = cv2.merge([cv2.LUT(img[:,:,i], luts[i])
for i in range(3)])
4.2 并行处理
pie
title 运算耗时分布
"像素计算" : 65
"内存访问" : 20
"其他" : 15
Python多线程处理
python
from concurrent.futures import ThreadPoolExecutor
def process_channel(channel, lut):
return cv2.LUT(channel, lut)
with ThreadPoolExecutor() as executor:
futures = []
for i in range(3):
futures.append(executor.submit(
process_channel,
img[:,:,i],
luts[i]
))
results = [f.result() for f in futures]
result = cv2.merge(results)
五、实战应用案例
5.1 双重曝光特效
flowchart TD
A[肖像图] --> C[高光提取]
B[风景图] --> D[边缘保留]
C --> E[线性混合]
D --> E
E --> F[效果增强]
实现代码
python
# 提取人像高光区域
gray = cv2.cvtColor(portrait, cv2.COLOR_BGR2GRAY)
_, mask = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)
# 风景图模糊处理
landscape_blur = cv2.GaussianBlur(landscape, (0,0), 5)
# 混合处理
result = cv2.bitwise_and(portrait, portrait, mask=mask)
result += cv2.bitwise_and(landscape_blur, landscape_blur,
mask=cv2.bitwise_not(mask))
5.2 图像HDR合成
gantt
title HDR合成流程
dateFormat X
axisFormat %s
section 处理步骤
读取曝光序列 : 0, 2
对齐图像 : 2, 5
计算响应曲线 : 5, 10
合成HDR : 10, 15
多曝光合成
python
# 读取不同曝光图像
imgs = [cv2.imread(f'exposure_{i}.jpg')
for i in range(3)]
# 转换为32位浮点
imgs = [img.astype(np.float32)/255 for img in imgs]
# 手动设置权重
weights = [0.2, 0.7, 0.1] # 低/中/高曝光权重
# 加权融合
hdr = np.zeros_like(imgs[0])
for img, w in zip(imgs, weights):
hdr += img * w
# 色调映射
hdr = np.clip(hdr * 255, 0, 255).astype(np.uint8)
六、调试与优化
6.1 常见问题排查
现象 | 原因 | 解决方案 |
---|---|---|
图像出现异常色斑 | 数值溢出未处理 | 使用cv2.add()替代+ |
融合边缘不自然 | 掩模羽化不足 | 高斯模糊掩模边缘 |
运算速度慢 | Python循环未优化 | 改用NumPy矢量化 |
透明效果失效 | Alpha通道未正确处理 | 预乘Alpha值 |
6.2 可视化调试工具
python
def show_blend_process(img1, img2, alpha):
plt.figure(figsize=(12,4))
plt.subplot(131)
plt.imshow(cv2.cvtColor(img1, cv2.COLOR_BGR2RGB))
plt.title('Image 1')
plt.subplot(132)
plt.imshow(alpha, cmap='gray')
plt.title('Alpha Mask')
plt.subplot(133)
blend = img1 * alpha[...,None] + img2 * (1-alpha[...,None])
plt.imshow(cv2.cvtColor(blend.astype(np.uint8),
cv2.COLOR_BGR2RGB)
plt.title('Blend Result')
plt.tight_layout()
plt.show()
# 创建渐变掩模
h,w = img1.shape[:2]
alpha = np.linspace(0,1,w).reshape(1,-1)
show_blend_process(img1, img2, alpha)
总结:本文系统讲解了OpenCV算术运算的核心技术,关键要点:
- 优先使用OpenCV内置函数(如addWeighted)避免溢出
- 位运算配合掩模可实现精确区域控制
- 金字塔融合适合多分辨率图像合成
- LUT加速技术可提升批量像素操作性能
下期预告:《图像阈值化》将深入讲解全局/自适应阈值、Otsu算法等二值化技术。