OpenCV:03图像的算数运算


掩膜

外科医生在给患者做手术时,会为患者盖上手术洞巾,这样医生就可以只在这个预设好的孔洞部位进行手术。手术洞巾不仅有利于医生定位患处、暴露手术视野,还可以对非患处起到隔离、防止污染的作用

在这里插入图片描述

同样地,当计算机处理图像时,图像也如同一名“患者”一样,有些内容需要处理,有些内容不需要处理。通常计算机处理图像时会把所有像素都处理一遍,但如果想让计算机像外科大夫那样仅处理某一小块区域,那就要为图像盖上一张仅暴露一小块区域的“手术洞巾”。像“手术洞巾”那样能够覆盖原始图像、仅暴露原始图像感兴趣区域(ROI)的模板图像就被叫做掩膜

掩膜,也叫掩码(mask),在程序中用二值图像来表示:

  • 0值(纯黑)区域表示被遮盖的部分
  • 255值(纯白)区域表示暴露的部分
  • 某些场景下也会用01当作掩膜的值

在这里插入图片描述

在使用OpenCV处理图像时,通常使用Numpy库提供的方法来创建掩膜图像,下面通过一个实例来演示:

利用Numpy库的np.zeros()方法来创建一幅掩膜图像,感兴趣区域为在该图像中横坐标为20、纵坐标为50、宽为60、高为50的矩形。先展示该掩膜图像,后调换该掩膜图像的感兴趣区域和不感兴趣区域,再次展示掩膜图像

# 掩膜

import cv2
import numpy as np

# 创建宽150、高150、3通道、像素类型为无符号8位数字的零值(纯黑)图像
mask = np.zeros((150,150,3),np.uint8)

##---------------------------------------------------
# 将50~100行、20~80列的像素改为纯白像素
mask[50:100,20:80,:] = 255

# 展示掩膜
cv2.imshow('mask1',mask)
##---------------------------------------------------
# 全部改成纯白像素
mask[:,:,:] = 255

# 将50~100行、20~80列的像素改为纯黑像素
mask[50:100,20:80,:] = 0

# 展示掩膜
cv2.imshow('mask2',mask)
##---------------------------------------------------

# 退出
cv2.waitKey()
cv2.destroyAllWindows()

结果:

在这里插入图片描述

掩膜在图像运算过程中充当了重要角色,通过掩膜才能看到最直观的运算结果,接下来将详细介绍图像运算的相关内容


图像的算数运算

加法运算

关键API:dst = cv2.add(src1, src2[, dst[, mask[, dtype]]])
其中:

  • src1:第一幅图像
  • src2:第二幅图像
  • mask:可选参数,掩膜(建议使用默认值)
  • dtype:可选参数,图像深度(建议使用默认值)

返回值:

  • dst:相加之后的结果图像。如果相加之后值的结果大于255,则取255

cv2.add()的规则就是两个图对应的元素相加,如果超过255(像素点的大小0-255),则全部变成255

我们可以用cv2.add()方法和正常的相加+做比较

代码如下:

# 加法运算
import cv2
import numpy as np

# 读取图片
img = cv2.imread('./beach.jpg')

# 展示
cv2.imshow('img',img) # 原图

##----------------------------------------
# 使用 "+" 运算符增加
sum1 = img + img

# 展示
cv2.imshow('using_+',sum1)

##----------------------------------------
# 使用cv2.add()方法相加
sum2 = cv2.add(img,img)

# 展示
cv2.imshow('using_cv2.add()',sum2)

##----------------------------------------

cv2.waitKey()
cv2.destroyAllWindows()

上述代码运行结果如下:
原图:
在这里插入图片描述
在这里插入图片描述

从这个结果可以看出:

  • " + "运算符的计算结果如果超出了255,就会取相加的和除以255的余数,也就是取模运算,像素值相加后反而变得更小了,由浅色变成了深色
  • cv2.add()方法的计算结果如果超过了255,就取值为255,很多浅颜色像素彻底变成了白色

不同的图相加:

# 加法运算
import cv2
import numpy as np

# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')


# cv2.add()方法要求两个图的长、宽、通道数都相等,否则会报错 
    # add的规则就是两个图对应的元素相加,如果超过255(像素点的大小0-255),则全部变成255
print(cat.shape)
print(dog.shape)  # 检查两图的长宽及通道数

# 由于dog的大小比cat大,因此我们使用numpy切片的方法把dog切成和cat一样的大小
new_dog = dog[0:1078,0:1095] # numpy的切片方式
print(new_dog.shape)

# 将两幅图片相加
new_img = cv2.add(cat,new_dog)
cv2.imshow('new_img',new_img)

cv2.waitKey()
cv2.destroyAllWindows()

图片还可以和单个数字进行运算,如dog += 100
每个和100进行加法运算,超过255的数字,会被截断,相当于%256

# 加法运算
import cv2
import numpy as np

# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')


# cv2.add()方法要求两个图的长、宽、通道数都相等,否则会报错 
    # add的规则就是两个图对应的元素相加,如果超过255(像素点的大小0-255),则全部变成255
# print(cat.shape)
# print(dog.shape)  # 检查两图的长宽及通道数

# 图片还可以和单个数字进行运算
    # 每个和100进行加法运算,超出255的数字,会被截断,相当于%256
dog += 100
print(dog[:3,:3])
    
cv2.waitKey()
cv2.destroyAllWindows()

利用掩膜遮盖相加结果

图像的加运算也可以使用掩膜,下面通过一个实例介绍掩膜的使用方法

创建纯蓝和纯红这两幅图像,使用add()方法对这两幅图像进行加运算,并在方法中添加一个掩膜,查看计算结果

具体代码如下:

import cv2
import numpy as np

# 创建150*150的0值(纯黑)图像
img1 = np.zeros((150,150,3),np.uint8)
img2 = np.zeros((150,150,3),np.uint8)

##--------------------------------------------------------------------

# 将图片变成蓝色 ——> 设置第三维度的BGR通道:蓝色通道赋予最大值
img1[:,:,0] = 255

# cv2.imshow('new_img',img1)

# 将图片变成红色 ——> 设置第三维度的BGR通道:红色通道赋予最大值
img2[:,:,2] = 255

# cv2.imshow('img2',img2)

# 蓝色 + 红色 = 洋红色
img = cv2.add(img1,img2)
cv2.imshow('img',img)

##--------------------------------------------------------------------

# 创建掩膜
mask = np.zeros((150,150,1),np.uint8)
mask[50:100,50:100,:] = 255
cv2.imshow('mask',mask)

# 相加时使用掩膜
img = cv2.add(img1,img2,mask = mask)
cv2.imshow('using_mask',img)


cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述
原图 、 掩膜 、 原图使用了掩膜后的效果


减法运算

关键API:cv2.subtract(img1,img2)

subtract的规则就是两个图对应的元素相减,如果小于0(像素点的大小0-255),则全部变成0

# 减法运算
import cv2
import numpy as np

# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')


# cv2.subtract()方法要求两个图的长、宽、通道数都相等,否则会报错 
    # subtract的规则就是两个图对应的元素相减,如果小于0(像素点的大小0-255),则全部变成0
print(cat.shape)
print(dog.shape)  # 检查两图的长宽及通道数

# 由于dog的大小比cat大,因此我们使用numpy切片的方法把dog切成和cat一样的大小
new_dog = dog[0:1078,0:1095] # numpy的切片方式
print(new_dog.shape)

# 将两幅图片相减 ——> 对应图片的元素(像素)相减,减完小于0,则全部为0
new_img = cv2.subtract(cat,new_dog)
cv2.imshow('new_img',new_img)

cv2.waitKey()
cv2.destroyAllWindows()

乘法运算

关键API:cv2.multiply(img1,img2)

乘法的规则和加法一样:两个图对应的元素相乘,如果超过255(像素点的大小0-255),则全部变成255

# 乘法运算
import cv2
import numpy as np

# 读取图片
cat = cv2.imread('./cat.jpeg')
dog = cv2.imread('./dog.jpeg')


# cv2.multiply()方法要求两个图的长、宽、通道数都相等,否则会报错 
    # multiply的规则就是两个图对应的元素相乘,如果超过255(像素点的大小0-255),则全部变成255
print(cat.shape)
print(dog.shape)  # 检查两图的长宽及通道数

# 由于dog的大小比cat大,因此我们使用numpy切片的方法把dog切成和cat一样的大小
new_dog = dog[0:1078,0:1095] # numpy的切片方式
print(new_dog.shape)

# 将两幅图片相乘 multiply——> 对应图片的元素(像素)相减,减完小于0,则全部为0
new_img = cv2.multiply(cat,new_dog)
cv2.imshow('new_img',new_img)

cv2.waitKey()
cv2.destroyAllWindows()

除法运算

关键API:cv2.divide(img1,img2

除法的规则和减法一样:两个图对应的元素相除,如果小于0(像素点的大小0-255),则全部变成0

# 加法运算
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值