OpenCV图像算术运算:加减乘除与位运算实战

目录

一、图像算术运算概述

[1.1 什么是图像算术运算?](#1.1 什么是图像算术运算?)

[1.2 算术运算的基本概念](#1.2 算术运算的基本概念)

[1.3 算术运算的应用场景](#1.3 算术运算的应用场景)

二、图像加法

[2.1 基本原理](#2.1 基本原理)

[2.2 OpenCV实现](#2.2 OpenCV实现)

[2.2.1 使用add函数](#2.2.1 使用add函数)

[2.2.2 使用NumPy加法](#2.2.2 使用NumPy加法)

[2.3 加权加法](#2.3 加权加法)

三、图像减法

[3.1 基本原理](#3.1 基本原理)

[3.2 OpenCV实现](#3.2 OpenCV实现)

[3.2.1 使用subtract函数](#3.2.1 使用subtract函数)

[3.2.2 绝对差值](#3.2.2 绝对差值)

[3.3 运动检测应用](#3.3 运动检测应用)

四、图像乘法

[4.1 基本原理](#4.1 基本原理)

[4.2 OpenCV实现](#4.2 OpenCV实现)

[4.2.1 使用multiply函数](#4.2.1 使用multiply函数)

[4.2.2 亮度调整](#4.2.2 亮度调整)

五、图像除法

[5.1 基本原理](#5.1 基本原理)

[5.2 OpenCV实现](#5.2 OpenCV实现)

[5.2.1 使用divide函数](#5.2.1 使用divide函数)

[5.2.2 对比度调整](#5.2.2 对比度调整)

六、位运算

[6.1 基本原理](#6.1 基本原理)

[6.2 位与运算(AND)](#6.2 位与运算(AND))

[6.3 位或运算(OR)](#6.3 位或运算(OR))

[6.4 位非运算(NOT)](#6.4 位非运算(NOT))

[6.5 位异或运算(XOR)](#6.5 位异或运算(XOR))

七、ROI(感兴趣区域)操作

[7.1 基本概念](#7.1 基本概念)

[7.2 ROI提取](#7.2 ROI提取)

[7.3 ROI修改](#7.3 ROI修改)

[7.4 ROI替换](#7.4 ROI替换)

八、图像混合

[8.1 Alpha混合](#8.1 Alpha混合)

[8.1.1 基本原理](#8.1.1 基本原理)

[8.1.2 OpenCV实现](#8.1.2 OpenCV实现)

[8.2 渐变混合](#8.2 渐变混合)

九、实战案例

[9.1 水印添加](#9.1 水印添加)

[9.2 图像淡入淡出效果](#9.2 图像淡入淡出效果)

[9.3 图像拼接](#9.3 图像拼接)

十、总结

[10.1 核心要点](#10.1 核心要点)

[10.2 最佳实践](#10.2 最佳实践)


一、图像算术运算概述

1.1 什么是图像算术运算?

图像算术运算是指对图像进行基本的数学运算,包括加法、减法、乘法、除法以及位运算等。这些运算在图像处理、图像融合、特效制作等领域有着广泛的应用。

1.2 算术运算的基本概念

图像算术运算的特点:

像素级操作:对每个像素进行独立运算

维度匹配:参与运算的图像必须具有相同的尺寸和通道数

数据类型:运算结果可能超出原始数据类型的范围

饱和处理:需要处理溢出和下溢情况

1.3 算术运算的应用场景

图像融合:将多幅图像合并为一幅

图像混合:创建过渡效果

特效制作:水印、淡入淡出等

ROI操作:提取和操作图像的特定区域

图像增强:通过运算调整图像亮度、对比度

二、图像加法

2.1 基本原理

图像加法是将两幅图像对应位置的像素值相加,得到新的图像。

加法公式:

```

C(x, y) = A(x, y) + B(x, y)

```

其中,A和B是输入图像,C是输出图像。
注意事项:

像素值可能超出255(对于8位图像)

需要进行饱和处理

图像尺寸必须相同

2.2 OpenCV实现

2.2.1 使用add函数

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#图像加法

result = cv2.add(image1, image2)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('Added Image', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

2.2.2 使用NumPy加法

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#方法1:NumPy加法(可能溢出)

result_numpy = image1 + image2

#方法2:NumPy加法(带饱和处理)

result_numpy_sat = np.clip(image1.astype(np.int16) + image2.astype(np.int16), 0, 255).astype(np.uint8)

#方法3:OpenCV加法(推荐)

result_opencv = cv2.add(image1, image2)

#显示结果

cv2.imshow('NumPy Addition (No Saturation)', result_numpy)

cv2.imshow('NumPy Addition (With Saturation)', result_numpy_sat)

cv2.imshow('OpenCV Addition', result_opencv)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

2.3 加权加法

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#加权加法

alpha: 第一幅图像的权重

beta: 第二幅图像的权重

gamma: 加到结果上的标量值

alpha = 0.7

beta = 0.3

gamma = 0

result = cv2.addWeighted(image1, alpha, image2, beta, gamma)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow(f'Weighted Addition (α={alpha}, β={beta})', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

三、图像减法

3.1 基本原理

图像减法是将两幅图像对应位置的像素值相减,用于检测图像之间的差异。

减法公式:

```

C(x, y) = A(x, y) B(x, y)

```

其中,A和B是输入图像,C是输出图像。
注意事项:

像素值可能小于0

需要进行饱和处理

结果可能为负数,需要取绝对值

3.2 OpenCV实现

3.2.1 使用subtract函数

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#图像减法

result = cv2.subtract(image1, image2)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('Subtracted Image', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

3.2.2 绝对差值

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#计算绝对差值

result = cv2.absdiff(image1, image2)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('Absolute Difference', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

3.3 运动检测应用

```python

import cv2

import numpy as np

#打开摄像头

cap = cv2.VideoCapture(0)

#读取第一帧

ret, prev_frame = cap.read()

prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)

while True:

#读取当前帧

ret, frame = cap.read()

if not ret:

break

#转换为灰度图

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

#计算帧差

diff = cv2.absdiff(prev_gray, gray)

#阈值分割

_, thresh = cv2.threshold(diff, 30, 255, cv2.THRESH_BINARY)

#形态学操作去噪

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))

thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

#显示结果

cv2.imshow('Motion Detection', thresh)

#更新前一帧

prev_gray = gray

if cv2.waitKey(30) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()

```

四、图像乘法

4.1 基本原理

图像乘法是将两幅图像对应位置的像素值相乘,用于调整图像亮度或创建遮罩效果。

乘法公式:

```

C(x, y) = A(x, y) B(x, y)

```

其中,A和B是输入图像,C是输出图像。

注意事项:

像素值可能快速增大

通常需要归一化处理

适用于创建遮罩效果

4.2 OpenCV实现

4.2.1 使用multiply函数

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#创建遮罩(中心亮,边缘暗)

mask = np.zeros_like(image, dtype=np.float32)

h, w = image.shape[:2]

center_x, center_y = w // 2, h // 2

for i in range(h):

for j in range(w):

dist = np.sqrt((i center_y)2 + (j center_x)2)

mask[i, j] = np.exp(dist / (h / 4))

#归一化遮罩

mask = (mask 255).astype(np.uint8)

#图像乘法

result = cv2.multiply(image, mask, scale=1/255.0)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow('Mask', mask)

cv2.imshow('Multiplied Image', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

4.2.2 亮度调整

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#创建亮度调整因子

factor > 1.0: 增加亮度

factor < 1.0: 降低亮度

factor = 1.5

#归一化图像

image_float = image.astype(np.float32) / 255.0

#应用亮度调整

adjusted = image_float factor

#归一化回[0, 255]范围

adjusted = np.clip(adjusted 255.0, 0, 255).astype(np.uint8)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow(f'Brightness Adjusted (Factor={factor})', adjusted)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

五、图像除法

5.1 基本原理

图像除法是将两幅图像对应位置的像素值相除,用于归一化或创建特殊效果。

除法公式:

```

C(x, y) = A(x, y) / B(x, y)

```

其中,A和B是输入图像,C是输出图像。

注意事项:

需要处理除零情况

结果通常需要归一化

适用于归一化操作

5.2 OpenCV实现

5.2.1 使用divide函数

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#创建归一化图像

normalization_map = np.ones_like(image, dtype=np.float32) 2.0

#图像除法

result = cv2.divide(image.astype(np.float32), normalization_map)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow('Divided Image', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

5.2.2 对比度调整

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#计算图像均值

mean_value = np.mean(image)

#创建对比度调整图像

factor > 1.0: 增加对比度

factor < 1.0: 降低对比度

factor = 1.5

#对比度调整公式

adjusted = (image mean_value) factor + mean_value

#饱和处理

adjusted = np.clip(adjusted, 0, 255).astype(np.uint8)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow(f'Contrast Adjusted (Factor={factor})', adjusted)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

六、位运算

6.1 基本原理

位运算是对图像的像素值进行二进制位操作,包括与(AND)、或(OR)、非(NOT)、异或(XOR)等。

位运算的特点:

直接操作像素的二进制位

适用于二值图像

可以创建复杂的遮罩效果

计算速度快

6.2 位与运算(AND)

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#创建矩形遮罩

mask = np.zeros_like(image)

h, w = image.shape[:2]

cv2.rectangle(mask, (w//4, h//4), (w3//4, h3//4), (255, 255, 255), 1)

#位与运算

result = cv2.bitwise_and(image, mask)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow('Mask', mask)

cv2.imshow('AND Result', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

6.3 位或运算(OR)

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#位或运算

result = cv2.bitwise_or(image1, image2)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('OR Result', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

6.4 位非运算(NOT)

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('image.jpg')

#位非运算

result = cv2.bitwise_not(image)

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow('NOT Result', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

6.5 位异或运算(XOR)

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#位异或运算

result = cv2.bitwise_xor(image1, image2)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('XOR Result', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

七、ROI(感兴趣区域)操作

7.1 基本概念

ROI(Region of Interest,感兴趣区域)是指图像中需要特别处理的区域。ROI操作可以提取、修改或替换图像的特定部分。

ROI的特点:

减少计算量

提高处理速度

专注于图像的重要部分

可以进行复杂的区域操作

7.2 ROI提取

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('full_image.jpg')

#定义ROI区域

格式:image[y:y+h, x:x+w]

x, y, w, h = 100, 100, 200, 200

roi = image[y:y+h, x:x+w]

#显示结果

cv2.imshow('Original Image', image)

cv2.imshow('ROI', roi)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

7.3 ROI修改

```python

import cv2

import numpy as np

#读取图像

image = cv2.imread('full_image.jpg')

#定义ROI区域

x, y, w, h = 100, 100, 200, 200

roi = image[y:y+h, x:x+w]

#修改ROI(添加红色边框)

cv2.rectangle(roi, (10, 10), (w10, h10), (0, 0, 255), 3)

#将修改后的ROI放回原图

image[y:y+h, x:x+w] = roi

#显示结果

cv2.imshow('Modified Image', image)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

7.4 ROI替换

```python

import cv2

import numpy as np

#读取两幅图像

main_image = cv2.imread('main_image.jpg')

logo_image = cv2.imread('logo.png')

#确保logo图像小于主图像

logo_h, logo_w = logo_image.shape[:2]

main_h, main_w = main_image.shape[:2]

if logo_h < main_h and logo_w < main_w:

#定义logo位置(右下角)

x, y = main_w logo_w 20, main_h logo_h 20

#创建ROI

roi = main_image[y:y+logo_h, x:x+logo_w]

#将logo添加到ROI

#使用alpha混合(如果logo有透明通道)

if logo_image.shape[2] == 4: 有alpha通道

#分离alpha通道

b, g, r, alpha = cv2.split(logo_image)

#归一化alpha通道

alpha = alpha.astype(np.float32) / 255.0

#对每个通道应用alpha混合

for c in range(3):

roi[:, :, c] = roi[:, :, c] (1 alpha) + logo_image[:, :, c] alpha

else:

#直接替换

roi[:, :] = logo_image

#将修改后的ROI放回原图

main_image[y:y+logo_h, x:x+logo_w] = roi

#显示结果

cv2.imshow('Image with Logo', main_image)

cv2.waitKey(0)

cv2.destroyAllWindows()

else:

print("Logo图像尺寸大于主图像!")

```

八、图像混合

8.1 Alpha混合

8.1.1 基本原理

Alpha混合是一种图像融合技术,它使用alpha通道(透明度)来控制两幅图像的混合比例。

Alpha混合公式:

```

C = α F + (1 α) B

```

其中:

C是混合后的像素值

α是alpha值(0表示完全透明,1表示完全不透明)

F是前景图像

B是背景图像

8.1.2 OpenCV实现

```python

import cv2

import numpy as np

#读取前景图像和背景图像

foreground = cv2.imread('foreground.png') 假设有alpha通道

background = cv2.imread('background.jpg')

#确保前景图像有alpha通道

if foreground.shape[2] == 4:

#分离alpha通道

b, g, r, alpha = cv2.split(foreground)

#归一化alpha通道到[0, 1]范围

alpha = alpha.astype(np.float32) / 255.0

#调整前景图像尺寸

foreground_resized = cv2.resize(foreground[:, :, :3], (background.shape[1], background.shape[0]))

#Alpha混合

result = np.zeros_like(background, dtype=np.float32)

for c in range(3):

result[:, :, c] = (foreground_resized[:, :, c] alpha +

background[:, :, c] (1 alpha))

#转换回uint8

result = result.astype(np.uint8)

#显示结果

cv2.imshow('Background', background)

cv2.imshow('Foreground', foreground_resized)

cv2.imshow('Alpha Blended', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

else:

print("前景图像没有alpha通道!")

```

8.2 渐变混合

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#创建渐变alpha通道

h, w = image1.shape[:2]

alpha = np.linspace(0, 1, w, dtype=np.float32)

alpha = np.tile(alpha, (h, 1))

alpha = alpha[:, :, np.newaxis]

#Alpha混合

result = (image1.astype(np.float32) alpha +

image2.astype(np.float32) (1 alpha)).astype(np.uint8)

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('Gradient Blend', result)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

九、实战案例

9.1 水印添加

```python

import cv2

import numpy as np

#读取主图像和水印图像

main_image = cv2.imread('main_image.jpg')

watermark = cv2.imread('watermark.png', cv2.IMREAD_UNCHANGED)

#确保水印图像有alpha通道

if watermark.shape[2] == 4:

#分离alpha通道

b, g, r, alpha = cv2.split(watermark)

#归一化alpha通道

alpha = alpha.astype(np.float32) / 255.0

#调整水印大小

watermark_resized = cv2.resize(watermark[:, :, :3],

(main_image.shape[1]//2, main_image.shape[0]//2))

#调整alpha通道大小

alpha_resized = cv2.resize(alpha, (main_image.shape[1]//2, main_image.shape[0]//2))

#定义水印位置(右下角)

x, y = main_image.shape[1] watermark_resized.shape[1] 20, \

main_image.shape[0] watermark_resized.shape[0] 20

#创建ROI

roi = main_image[y:y+watermark_resized.shape[0],

x:x+watermark_resized.shape[1]]

#Alpha混合

result_roi = np.zeros_like(roi, dtype=np.float32)

for c in range(3):

result_roi[:, :, c] = (watermark_resized[:, :, c] alpha_resized +

roi[:, :, c] (1 alpha_resized))

#将混合后的ROI放回原图

main_image[y:y+watermark_resized.shape[0],

x:x+watermark_resized.shape[1]] = result_roi.astype(np.uint8)

#显示结果

cv2.imshow('Image with Watermark', main_image)

cv2.waitKey(0)

cv2.destroyAllWindows()

else:

print("水印图像没有alpha通道!")

```

9.2 图像淡入淡出效果

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#确保两幅图像尺寸相同

image2 = cv2.resize(image2, (image1.shape[1], image1.shape[0]))

#创建淡入淡出效果

frames = 30

for i in range(frames):

#计算alpha值(0到1)

alpha = i / (frames 1)

#Alpha混合

result = (image1.astype(np.float32) alpha +

image2.astype(np.float32) (1 alpha)).astype(np.uint8)

#显示结果

cv2.imshow('Fade Effect', result)

cv2.waitKey(50)

cv2.destroyAllWindows()

```

9.3 图像拼接

```python

import cv2

import numpy as np

#读取两幅图像

image1 = cv2.imread('image1.jpg')

image2 = cv2.imread('image2.jpg')

#水平拼接

h_concat = cv2.hconcat([image1, image2])

#垂直拼接

v_concat = cv2.vconcat([image1, image2])

#显示结果

cv2.imshow('Image 1', image1)

cv2.imshow('Image 2', image2)

cv2.imshow('Horizontal Concatenation', h_concat)

cv2.imshow('Vertical Concatenation', v_concat)

cv2.waitKey(0)

cv2.destroyAllWindows()

```

十、总结

10.1 核心要点

  1. 图像算术运算:使用add、subtract、multiply、divide函数

加法:图像融合、亮度调整

减法:运动检测、差异分析

乘法:亮度调整、遮罩效果

除法:归一化、对比度调整
2. 位运算:使用bitwise_and、bitwise_or、bitwise_not、bitwise_xor函数

与运算:遮罩提取

或运算:图像合并

非运算:图像反转

异或运算:差异检测
3. ROI操作:提取和修改图像的特定区域

减少计算量

提高处理速度

专注于重要部分
4. 图像混合:使用alpha通道进行图像融合

Alpha混合:透明度控制

渐变混合:平滑过渡

水印添加:版权保护

10.2 最佳实践

  1. 尺寸匹配:确保参与运算的图像尺寸相同

  2. 数据类型:注意运算结果的数据类型和范围

  3. 饱和处理:处理溢出和下溢情况

  4. 性能考虑:ROI操作可以显著提高处理速度

  5. 应用场景:根据具体需求选择合适的运算方法

相关推荐
Dev7z2 小时前
基于深度学习的香梨产量预测系统设计与实现(UI界面+数据集+训练代码)
人工智能·深度学习·yolo12·产量预测·香梨
阿达_优阅达2 小时前
让合规更高效:Fin AI × Sumsub 五大智能流程优化实践
人工智能·智能客服·企业数字化转型·intercom·finai
IT_陈寒2 小时前
JavaScript开发实战:从入门到精通
前端·人工智能·后端
前端双越老师2 小时前
为什么说 OpenClaw 应该装在自己的电脑上
人工智能·agent·全栈
Flamingˢ2 小时前
基于 FPGA 的帧间差分运动检测
人工智能·目标跟踪·fpga开发
小陈工2 小时前
2026年4月5日技术资讯洞察:AI商业模式变革、知识管理革命与开源生态反击
开发语言·人工智能·python·安全·oracle·开源
QYR-分析2 小时前
MPPT控制器行业解析:技术迭代与市场机遇前瞻
大数据·人工智能
A尘埃2 小时前
深度学习之卷积神经网络CNN(卷积+池化)
人工智能·深度学习·cnn
pzx_0012 小时前
【Pytorch】nn.Embedding函数详解
人工智能·pytorch·embedding