图像的基本运算有很多种,比如两幅图像可以相加、相减、相乘、相除、位运算、平方根、对数、绝对值等;图像也可以放大、缩小、旋转,还可以截取其中的一部分作为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) # 等待用户输入,按任意键即可
效果如下