欢迎来到军工软件开发人才培养基地——学到牛牛

图像上算数运算

时间:2024-05-06 07:01:10 来源:学到牛牛

1、图像加法

1.1 Numpy的加法

图像对象可以直接使用“+”号为图像的每个通道加上指定的值。

如下示例,为每个通道中的每个值加10。

# 使用“+”号进行数值计算

import cv2

 

img = cv2.imread("E:/tmp/img/cat.png")

 

# 原始数值

# img[:5, :8, 0] 表示读取前5行(h),前8列(w),B通道的值,方便结果验证

print(img[:5, :8, 0])

print("-----分割线-----")

 

# 相加后数值,将对每个通道中的每个值加10

img2 = img + 10

print(img2[:5, :8, 0])

 

cv2.imshow("test", img2)

 

cv2.waitKey(0)

cv2.destroyAllWindows()

 

BGR值在0-255范围,在进行数值相加时有可能会出现超过255值的情况,OpenCV将自动获取超过255部分的作为结果值,如图1.1所示。

图1.1 图像加法运行结果

 

1.2 Numpy的加法的加法

也可以使用cv2.add()函数将两幅图像进行加法运算。需要注意,使用该方法时,需要保证两幅图像的大小、类型一致。或者第2个图像使用一个简单的常量值(类似蒙板)。

示例代码如下所示。

# 数值计算

import cv2

import numpy

 

cat = cv2.imread("E:/tmp/img/cat.png")

dog = cv2.imread("E:/tmp/img/dog.jpg")

 

h, w = cat.shape[:2]

 

# 根据cat图像尺寸创建空的dog画布

dog2 = numpy.zeros_like(cat)

 

# 截取dog图像中部分内容,赋值到dog2画布中

dog2[:h, :w] = dog[:h, :w]

 

# 此时cat图像与dog2图像尺寸已经一致,满足使用add()函数的条件

newImg = cv2.add(cat, dog2)

print("1、cat图像矩阵")

print(cat[0:3, 0:8, 0])

print("\n2、dog2图像矩阵")

print(dog2[0:3, 0:8, 0])

print("\n3、cat与dog2运算后的图像矩阵")

print(newImg[0:3, 0:8, 0])

 

cv2.waitKey(0)

cv2.destroyAllWindows()

运行结果如下。

图2.1 add()函数运行结果

从上例子可以看出,add()函数也可以实现图像加法。使用add()函数这种加法要比使用“+”加法效果好一点,add()函数的加法是一种饱和操作,而Numpy的加法("+")是一种模操作,所以建议大家尽量使用OpenCV中的函数进行操作。

Numpy加法与OpenCV函数加法的区别:

Numpy加法,两个数相加,如果和大于255,将取两个值的和。

OpenCV函数的加法,两个相同尺寸的图像相加,如果和大于255,取值为255,否则取值为本身。

 

2、图像融合

图像融合其实也是加法,但是不同的是两幅图像的权重可以自定义,就会给人一种混合或者透明的感觉。可以使用cv2.addWeighted()函数实现图像融合,使用该函数前要求两幅图像尺寸致。

cv2.resize()函数用于根据给定的维度变化图像尺寸,它可以给定尺寸变化图像,也可以给定倍数变化图像。

2.1 根据给定尺寸变化图像

示例:将dog图像变化成cat图像一样大小

import cv2

 

cat = cv2.imread("E:/tmp/img/cat.png")

dog = cv2.imread("E:/tmp/img/dog.jpg")

 

# 获取cat图像尺寸

h, w = cat.shape[:2]

 

# 设置dog图像尺寸与cat图像尺寸一致,(w, h)中w为图像的宽,h为图像的高

# 重置图像尺寸

newDog = cv2.resize(dog, (w, h))

 

# 获取cat和newDog的尺寸

print(cat.shape)

print(newDog.shape)

 

cv2.imshow("cat", cat)

cv2.imshow("dog", newDog)

 

cv2.waitKey(0)

cv2.destroyAllWindows()

 

2.2 根据比例变化图像

import cv2

 

dog = cv2.imread("E:/tmp/img/dog.jpg")

 

# 1、将dog图像缩小1倍,在使用倍数改变图像时,尺寸参数应该设置为(0,0),表示不使用尺寸更改

narrow = cv2.resize(dog, (0, 0), fx=0.2, fy=0.2)

# 2、将dog图像放大1倍

expand = cv2.resize(dog, (0, 0), fx=2, fy=2)

# 3、将dog图像的宽度缩小1倍

width_narrow = cv2.resize(dog, (0, 0), fx=0.5, fy=1)

 

# 展示结果

cv2.imshow("original", dog)     # 原始图像

cv2.imshow("narrow", narrow)    # 缩小

cv2.imshow("expand", expand)    # 放大

cv2.imshow("width_narrow", width_narrow)    # 宽度缩小

 

cv2.waitKey(0)

cv2.destroyAllWindows()

 

2.3 权重加法

cv2.addWeighted(img1, α , img2, β, b)

OpenCV还提供了带权重的加法,即两副图像的像素通道值相加时各自按一定的权重比例取值来相加。

假设有2个图像矩阵img1和img2,在两个图像融合时,各自的权重分别为α和β,b为偏移量,表示在亮度集上的微调,则二者融合后的目标图像dst中各像素通道值的计算公式为:

dst = α · img1 + β · img2 + b

示例:设置cat图像权重为0.7,dog图像权重为0.3,亮度集为0。

import cv2

 

cat = cv2.imread("E:/tmp/img/cat.png")

dog = cv2.imread("E:/tmp/img/dog.jpg")

 

# 获取cat图像尺寸

h, w = cat.shape[:2]

 

# 设置dog2尺寸与cat图像尺寸一致

dog2 = cv2.resize(dog, (w, h))

 

# 展示显示

cv2.imshow("cat", cat)

cv2.imshow("dog", dog2)

 

# 按权重将cat与dog图像融合

fusion_img = cv2.addWeighted(cat, 0.7, dog2, 0.3, 0)

cv2.imshow("Fusion Image", fusion_img)

 

cv2.waitKey(0)

cv2.destroyAllWindows()

运行结果如下。

图2.1 addWeighted()运行结果