图像的基本运算有很多种,比如两幅图像可以相加、相减、相乘、相除、位运算、平方根、对数、绝对值等;图像也可以放大、缩小、旋转,还可以截取其中的一部分作为ROI(感兴趣区域)进行操作. 图像的逻辑操作主要是bitwise_and、bitwise_or、bitwise_xor、bitwise_not这四个按位操作函数。
dst = bitwise_and(InputArray src1, InputArray src2, InputArray mask=noArray());//dst = src1 & src2 与操作 dst = bitwise_or(InputArray src1, InputArray src2, InputArray mask=noArray());//dst = src1 | src2 或操作 dst = bitwise_xor(InputArray src1, InputArray src2, InputArray mask=noArray());//dst = src1 ^ src2 异或操作 dst = bitwise_not(InputArray src, InputArray mask=noArray());//dst = ~src 取反操作
对应的算法如下图

取反操作的效果如下
使用前 
使用后
Mask基本知识
Mask(掩膜运算) 即图与掩膜的“按位与”运算:
原图中的每个像素和掩膜(Mask)中的每个对应像素进行按位与运算,如果为真,结果是原图的值, 如果为假,结果就是零

mask的最大作用:让我们只关注我们感兴趣的图像部分 ROI(region of interest)
基本的位运算和Mask运算
# -*- coding: utf-8 -*-
import numpy as np
import cv2
# 因为是颜色,取值范围[0, 255], 类型应该为unsigned int 8 bit, 即uint8
# 可以把src1, src2看成一个像素点
# OpenCV中颜色顺序为BGR
src1 = np.array([[192, 0, 3]], dtype="uint8")
src2 = np.array([[162, 0, 34]], dtype="uint8") # 红色
dst_and = cv2.bitwise_and(src1, src2) # 按位与AND运算
dst_or = cv2.bitwise_or(src1, src2) # 按位或OR运算
dst_xor = cv2.bitwise_xor(src1, src2) # 按位异或XOR运算
dst_not_src1 = cv2.bitwise_not(src1) # 按位否NOT运算
dst_not_src2 = cv2.bitwise_not(src2) # 按位否NOT运算
# 输出以上的按位运算结果
print("dst_and:",dst_and) #[[128 0 2]]
print("dst_or:",dst_or) # [[226 0 35]]
print("dst_xor:",dst_xor) #[[98 0 33]]
print("dst_not_src1:",dst_not_src1) #[[ 63 255 252]]
print("dst_not_src2:",dst_not_src2) #[[ 93 255 221]]
# 构建一个mask, mask只能是二维的,单通道;
mask = np.array([[231, 0, 0]], dtype="uint8") # 一定要加dtype="uint8"
# mask运算
# 先按位与操作AND,再和mask"与"操作
and_mask = cv2.bitwise_and(src1, src2, mask=mask)
# 先按位或操作OR,再和mask"与"操作
or_mask = cv2.bitwise_or(src1, src2, mask=mask)
print("and_mask:", and_mask) #[[128 0 0]]
print("or_mask:",or_mask) # [[226 0 0]]
用mask提取ROI(Region of Interest)-三通道颜色
# -*- coding: utf-8 -*-
import numpy as np
import cv2
# 在画布中心画了一个250*250像素的矩形,颜色为三通道,用红色填充
rectangle = np.zeros((300, 300, 3), dtype="uint8")
cv2.rectangle(rectangle, (25, 25), (275, 275), (0, 0, 255), -1)
cv2.imshow("Rectangle", rectangle)
# 在画布中心画了一个半径为150像素的圆圈,颜色为三通道,用紫罗兰色填充
circle = np.zeros((300, 300, 3), dtype="uint8")
cv2.circle(circle, (150, 150), 150, (226, 43, 138), -1)
cv2.imshow("Circle", circle)
# 构建一个mask,形状为矩形,300*300 只能是单通道矩阵,图片表现是灰度值;
mask = np.zeros((300, 300), dtype="uint8")
cv2.rectangle(mask, (15, 15), (130, 100), 200, -1)
cv2.imshow("Mask", mask)
# 按位与操作AND
bitwiseAnd = cv2.bitwise_and(rectangle, circle) # 按位与AND操作结果为[0 0 138]
cv2.imshow("AND", bitwiseAnd)
# 先按位与操作AND,再和mask"与"操作
bitwiseAndMask = cv2.bitwise_and(rectangle, circle, mask=mask)
cv2.imshow("bitwiseAndMask", bitwiseAndMask)
# 按位或操作OR
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
# 先按位或操作OR,再和mask"与"操作
bitwiseOrMask = cv2.bitwise_or(rectangle, circle, mask=mask)
cv2.imshow("bitwiseOrMask", bitwiseOrMask)
cv2.waitKey(0) # 等待用户输入,按任意键即可
效果如下








