OpenCV:03图像的算数运算

文章目录

掩膜

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

OpenCV:03图像的算数运算

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

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

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

OpenCV:03图像的算数运算

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

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


import cv2
import numpy as np

mask = np.zeros((150,150,3),np.uint8)

mask[50:100,20:80,:] = 255

cv2.imshow('mask1',mask)

mask[:,:,:] = 255

mask[50:100,20:80,:] = 0

cv2.imshow('mask2',mask)

cv2.waitKey()
cv2.destroyAllWindows()

结果:

OpenCV:03图像的算数运算

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

图像的算数运算

加法运算

关键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)

sum2 = cv2.add(img,img)

cv2.imshow('using_cv2.add()',sum2)

cv2.waitKey()
cv2.destroyAllWindows()

上述代码运行结果如下:
原图:

OpenCV:03图像的算数运算
OpenCV:03图像的算数运算

从这个结果可以看出:

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

不同的图相加:


import cv2
import numpy as np

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

print(cat.shape)
print(dog.shape)

new_dog = dog[0:1078,0:1095]
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')

dog += 100
print(dog[:3,:3])

cv2.waitKey()
cv2.destroyAllWindows()

利用掩膜遮盖相加结果

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

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

具体代码如下:

import cv2
import numpy as np

img1 = np.zeros((150,150,3),np.uint8)
img2 = np.zeros((150,150,3),np.uint8)

img1[:,:,0] = 255

img2[:,:,2] = 255

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()

结果:

OpenCV:03图像的算数运算
原图 、 掩膜 、 原图使用了掩膜后的效果

减法运算

关键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')

print(cat.shape)
print(dog.shape)

new_dog = dog[0:1078,0:1095]
print(new_dog.shape)

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')

print(cat.shape)
print(dog.shape)

new_dog = dog[0:1078,0:1095]
print(new_dog.shape)

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


import cv2
import numpy as np

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

print(cat.shape)
print(dog.shape)

new_dog = dog[0:1078,0:1095]
print(new_dog.shape)

new_img = cv2.divide(cat,new_dog)
cv2.imshow('new_img',new_img)

cv2.waitKey()
cv2.destroyAllWindows()

图片的融合

关键API: addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
其中:

  • src1:第一幅图片
  • alpha:第一幅图片的权重
  • scr2:第二幅图片
  • beta:第二幅图片的权重
  • gamma:偏差

import cv2
import numpy as np

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

new_dog = dog[0:1078,0:1095]

new_img = cv2.addWeighted(cat,0.3,new_dog,1,0)

cv2.imshow('new_img',new_img)

cv2.waitKey()
cv2.destroyAllWindows()

OpenCV:03图像的算数运算

OpenCV的逻辑运算(位运算)

位运算是二进制数特有的运算特性。图像由像素组成,每个像素可以用十进制数表示,十进制整数又可以转化为二进制数,所以图像也可以进行为位运算,并且位运算在图像数字化技术是一项重要的运算操作

OpenCV提供了几种常用的位运算方法

方 法含 义 cv2.bitwise_and()

按 位 与 cv2.bitwise_or()

按 位 或 cv2.bitwise_not()

按 位 取反 cv2.bitwise_xor()

按 位 异或

与运算 &

关键API: cv2.bitwise_and(src1,src2,mask)
其中:

  • src1:第一幅图像
  • src2:第二幅图像
  • mask:可选参数,掩膜

返回值:

图像做与运算时,会把每一个像素值都转换为二进制数,然后让两幅图像相同位置的两个像素值做与运算,最后把运算结果保存在新图像的相同位置上

OpenCV:03图像的算数运算
  • dst:与运算后的结果图像

204 & 213 = 196,先将204和213转化为二进制,再把结果的二进制转化为十进制,即为196

两个数与运算后会变小,如 204 & 213 = 196 ; 150 & 140 = 132

与运算有两个特点:

  • 如果某像素与纯白色像素(255)做与运算,结果仍然是某像素的原值,即不变
00101011 & 11111111 = 00101011
  • 如果某像素与纯黑色像素(0)做与运算,结果为纯黑像素,即归零
00101011 & 00000000 = 00000000

由此可以得出: 如果原图像与 掩膜 进行与运算,原图像仅仅会保留掩膜中白色区域所覆盖的内容,其他区域全部变成黑色。下面通过一个实例来演示掩膜在与运算过程中的作用,

花图像与十字掩膜做 与运算

创建一个掩膜,在掩膜中央保留一个十字形的白色区域,让掩膜与❀做 与运算 ,查看运算后的结果

代码如下:

import cv2
import numpy as np

img = cv2.imread('./amygdalus triloba.png')

print(img.shape)

mask = np.zeros(img.shape,np.uint8)

mask[120:180,:,:] = 255
mask[:,90:150,:] = 255

dst = cv2.bitwise_and(img, mask)

cv2.imshow('img',img)
cv2.imshow('mask',mask)
cv2.imshow('dst',dst)

cv2.waitKey()
cv2.destroyAllWindows()

结果:

OpenCV:03图像的算数运算

示例代码:
两张图片进行与运算


import cv2
import numpy as np

cv2.namedWindow('new_img',cv2.WINDOW_NORMAL)

cv2.resizeWindow('new_img',800,600)

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

new_dog = dog[0:1078,0:1095]

cat_and = cv2.bitwise_and(cat,new_dog)

print(cat[:2,:2])
print('---------------------')
print(dog[:2,:2])
print('---------------------')
print(cat_and[:2,:2])

cv2.imshow('new_img',np.hstack((cat,cat_and)))

cv2.waitKey()
cv2.destroyAllWindows()

结果:

cat:
[[[195 216 244]
  [194 215 243]]

 [[194 215 243]
  [193 214 242]]]
cat_and
[[[ 64  64 116]
  [ 66  68 114]]

 [[ 64  70 115]
  [ 64  70 112]]]

OpenCV:03图像的算数运算

或运算 |

关键API: dst = cv2.bitwise_or(src1,src2,mask)

  • src1:第一幅图像
  • src2:第二幅图像
  • mask:可选参数,掩膜

返回值:
dst :或运算之后的结果图像

或运算也有两个特点:

  • 如果某像素与纯白色像素(255)做 或运算,结果为纯白色像素(255)
00101011 | 11111111 = 11111111
  • 如果某像素与纯黑色像素(0)做 或运算,结果仍然为某像素的原值(不变)
00101011 | 00000000 = 00101011

由此可以得出: 如果原图像与 掩膜 进行或运算,原图像仅会保存掩膜中黑色区域所覆盖的内容,其他区域全部变成白色。下面通过一个实例来掩饰掩膜在或运算中的作用

花图像与十字掩膜做 或运算

创建一个掩膜,在掩膜中央保留一个十字形的白色区域,让掩膜与❀做 或运算 ,查看运算后的结果

代码如下:

import cv2
import numpy as np

img = cv2.imread('./amygdalus triloba.png')

print(img.shape)

mask = np.zeros(img.shape,np.uint8)

mask[120:180,:,:] = 255
mask[:,90:150,:] = 255

dst = cv2.bitwise_or(img, mask)

cv2.imshow('img',img)
cv2.imshow('mask',mask)
cv2.imshow('dst',dst)

cv2.waitKey()
cv2.destroyAllWindows()

结果:

OpenCV:03图像的算数运算

示例代码:

两个数进行或运算


import cv2
import numpy as np

cv2.namedWindow('new_img',cv2.WINDOW_NORMAL)

cv2.resizeWindow('new_img',800,600)

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

new_dog = dog[0:1078,0:1095]

cat_or = cv2.bitwise_or(cat,new_dog)

print(cat[:2,:2])
print('---------------------')
print(dog[:2,:2])
print('---------------------')
print(cat_or[:2,:2])

cv2.imshow('new_img',np.hstack((cat,new_dog,cat_and)))

cv2.waitKey()
cv2.destroyAllWindows()

结果:

[[[195 216 244]
  [194 215 243]]

 [[194 215 243]
  [193 214 242]]]
[[[215 254 253]
  [207 247 251]]

 [[215 247 251]
  [213 247 254]]]

OpenCV:03图像的算数运算

非运算 ~

关键API: dst = cv2.bitwise_not(src,mask)
其中:

  • src:参与运算的图像
  • mask:可选参数,掩膜

返回值:

  • dst:取反运算之后的结果图像

~255 = 0, ~195 = 60,在opencv中取非就是相当于用255减去取非的数


import cv2
import numpy as np

cv2.namedWindow('new_img',cv2.WINDOW_NORMAL)

cv2.resizeWindow('new_img',800,600)

cat = cv2.imread('./cat.jpeg')

cat_not = cv2.bitwise_not(cat)

print(cat[:2,:2])
print('---------------------')
print(cat_not[:2,:2])

cv2.imshow('new_img',np.hstack((cat,cat_not)))

cv2.waitKey()
cv2.destroyAllWindows()

结果:

`python
cat:
[[[195 216 244]
[194 215 243]]

[[194 215 243]
[193 214 242]]]
[[[ 84 102 125]
[ 79 100 122]]

[[ 85 102 123]
[ 84 103 124]]]

Original: https://blog.csdn.net/m0_59466249/article/details/125537910
Author: Lionetxx
Title: OpenCV:03图像的算数运算

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/763553/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球