【P38 6】OpenCV Python——图片的运算(算术运算、逻辑运算)加法add、subtract减法、乘法multiply、除法divide

发布于:2025-08-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

在这里插入图片描述

1 加法运算

1.1 加法运算示例add

import cv2
import numpy as np

dog=cv2.imread('dog.jpeg')

h=dog.shape[0]//2#//取整除法
w=dog.shape[1]//2

#尺寸太大了,不便展示
dog = cv2.resize(dog, (w,h), interpolation = cv2.INTER_CUBIC)
#dog=dog.resize((200,200))#不知为啥,这个resize是错的,运行一闪而过
print(dog.shape)
cv2.imshow("dog",dog)


img=np.full((h,w,3),50,np.uint8)#生成每个像素的RGB值都是(50,50,50)的灰色图像
result=cv2.add(dog,img)

#直接相加,效果不好
dog2=dog+img

#显示
cv2.imshow("img",img)
cv2.imshow("result",result)
cv2.imshow("dog2",dog2)#直接相加,效果不好

key=cv2.waitKey(0)

在这里插入图片描述

add函数相加(饱和运算):效果(左)
直接相加(模运算),效果不好(右)

在这里插入图片描述

1.2 cv2.add() 和直接相加 对比

在OpenCV中,cv2.add() 和直接相加 (+) 是两种不同的图像像素值相加方式,主要区别在于数值处理机制:

‌ 1 cv2.add() 函数‌:

  • 饱和运算(Saturation Arithmetic):
    • 计算结果超过255时自动截断为255;
    • 例:200 + 100 = 255;
  • 保证结果始终在0-255范围内;
  • 适合图像混合/叠加操作;
    2‌ 直接相加 (+)‌:
  • 模运算(Modulo Arithmetic):
    • 计算结果超过255时会取模(256取余);
    • 例:200 + 100 = 300 % 256 = 44;
  • 产生非预期的颜色循环效果;
  • 通常需要手动处理溢出(如 np.clip(dog+img, 0, 255));

在这里插入图片描述

2 减法

在这里插入图片描述

img=np.full((h,w,3),50,np.uint8)
add_img=cv2.add(dog,img)#加
subtract_img=cv2.subtract(dog,img)#减

#显示
cv2.imshow("img",img)
cv2.imshow("add_img",add_img)
cv2.imshow("subtract_img",subtract_img)

原图
在这里插入图片描述

左加,右减;

结论:
加运算,图片更亮;
减运算,图片更暗;

在这里插入图片描述

完整代码

import cv2
import numpy as np

dog=cv2.imread('dog.jpeg')

h=dog.shape[0]//2#//取整除法
w=dog.shape[1]//2

#尺寸太大了,不便展示
dog = cv2.resize(dog, (w,h), interpolation = cv2.INTER_CUBIC)
#dog=dog.resize((200,200))#不知为啥,这个resize是错的,运行一闪而过
print(dog.shape)
cv2.imshow("dog",dog)


img=np.full((h,w,3),50,np.uint8)
add_img=cv2.add(dog,img)#加
subtract_img=cv2.subtract(dog,img)#减

#显示
cv2.imshow("img",img)
cv2.imshow("add_img",add_img)
cv2.imshow("subtract_img",subtract_img)

key=cv2.waitKey(0)

3 乘法multiply,除法divide

在这里插入图片描述

import cv2
import numpy as np

dog=cv2.imread('dog.jpeg')

h=dog.shape[0]//2#//取整除法
w=dog.shape[1]//2

#尺寸太大了,不便展示
dog = cv2.resize(dog, (w,h), interpolation = cv2.INTER_CUBIC)
#dog=dog.resize((200,200))#不知为啥,这个resize是错的,运行一闪而过
print(dog.shape)
cv2.imshow("dog",dog)

img=np.full((h,w,3),50,np.uint8)#生成每个像素的RGB值都是(50,50,50)的灰色图像



#乘法运算(亮度增强效果)
mult_img = cv2.multiply(dog, 1.5) # 1.5倍亮度提升 
cv2.imshow("Multiplication", mult_img)

# 除法运算(需添加微小常量防除零)
divide51_img = cv2.divide(dog, img + 1) # 避免除数为0 
cv2.imshow("Division/51", divide51_img)

#标准化除法(更可视化的结果)
normalized_div = cv2.divide(dog, img + 1, scale=100) # 缩放结果 
cv2.imshow("Normalized Division", normalized_div)

#加权乘法(矩阵元素级)
matrix_mult = cv2.multiply(dog, np.array([0.8, 1.2, 0.9], dtype=np.float32)) 
cv2.imshow("Channel Weighted Multiply", matrix_mult)


key=cv2.waitKey(0)

下面是对上面代码关键部分的解释

3.1 乘法运算(亮度增强)

mult_img = cv2.multiply(dog, 1.5)  # 1.5倍亮度提升
  • 原理‌: 对每个像素的BGR通道值执行标量乘法
  • 运算规则‌:
    • 采用饱和运算:结果 = min(原始值 × 1.5, 255);
    • 例如:原像素值100 → 100×1.5=150(正常显示);
    • 原像素值200 → 200×1.5=300 → 截断为255;
  • 效果‌: 整体亮度提升,高光区域可能出现过曝;
    在这里插入图片描述

3.2. 基础除法运算 (需添加常量防除零)

divide_img = cv2.divide(dog, img + 1)  # img是50的灰度图
  • 运算过程‌:
    • 除数: img + 1 = 51(所有像素值);
    • 计算公式: 结果 = dog / 51;
    • 典型计算: 原像素值100 → 100/51≈1.96 → 转换为uint8后=1(几乎全黑);
  • ‌全黑原因‌:
    • 原始图像像素值范围(0-255)除以51后结果范围(0-5);
    • 转换为uint8类型时,小于1的值显示为0(纯黑);

在这里插入图片描述

3.3. 标准化除法改进 (更可视化的结果)

将除法的结果 再乘以 scale 倍率。

normalized_div = cv2.divide(dog, img + 1, scale=100)

改进原理‌:

  • scale参数作为乘数:结果 = 100 × (dog/51)
  • 使输出值范围扩大到0-500,但:
    • 仍会被截断到255(uint8限制)
    • 实际效果:100/51×100≈196(可见灰度)

在这里插入图片描述

3.4. 通道加权乘法(矩阵元素级)

通道加权乘法: 每个通道乘以不同的系数;

matrix_mult = cv2.multiply(dog, [0.8,1.2,0.9])

‌特殊效果‌:

  • B通道×0.8(削弱蓝色)
  • G通道×1.2(增强绿色)
  • R通道×0.9(轻微削弱红色)

‌应用场景‌: 色彩平衡调整;

在这里插入图片描述

3.5 除法再探究

下面两种代码,都是每个通道除以5的意思,结果一样

divide_45_img = cv2.divide(dog, img - 45) 
cv2.imshow("Division-45", divide_45_img)
divide5_img = cv2.divide(dog, 5) 
cv2.imshow("Division/5", divide5_img)

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到