3、图像位运算
位运算在图像处理,特别是掩膜中有着极其重要的作用,主要有与、或、异或以及非等操作。
Operation | Function |
AND | cv2.bitwise_and |
OR | cv2.bitwise_or |
XOR | cv2.bitwise_xor |
NOT | cv2.bitwise_not |
接下来以书上的代码来了解图像的位运算。
a.源代码展现
bitwise.py
import numpy as np
import cv2
# First, let's draw a rectangle
rectangle = np.zeros((300, 300), dtype = "uint8")
cv2.rectangle(rectangle, (25, 25), (275, 275), 255, -1)
cv2.imshow("Rectangle", rectangle)
# Secondly, let's draw a circle
circle = np.zeros((300, 300), dtype = "uint8")
cv2.circle(circle, (150, 150), 150, 255, -1)
cv2.imshow("Circle", circle)
# A bitwise 'AND' is only True when both rectangle
# and circle have a value that is 'ON'. Simply put,
# the bitwise_and function examines every pixel in
# rectangle and circle. If both pixels have a value
# greater than zero, that pixel is turned 'ON' (i.e
# set to 255 in the output image). If both pixels
# are not greater than zero, then the output pixel
# is left 'OFF' with a value of 0.
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)
# A bitwise 'OR' examines every pixel in rectangle
# and circle. If EITHER pixel in rectangle or circle
# is greater than zero, then the output pixel has a
# value of 255, otherwise it is 0.
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)
# The bitwise 'XOR' is identical to the 'OR' function,
# with one exception: both rectangle and circle are
# not allowed to have values greater than 0.
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)
# Finally, the bitwise 'NOT' inverts the values of
# the pixels. Pixels with a value of 255 become 0,
# and pixels with a value of 0 become 255.
bitwiseNot = cv2.bitwise_not(circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)
b.代码分析
Line 5-7
首先将rectangle定义为一个300*300的黑色画布,然后通过opencv中的cv2.rectangle绘制了一个纯白色的矩形并显示,白色矩形起点和终点分别为(25, 25)和(275, 275),参数中255表示矩形的像素亮度为255,即纯白,-1表示将矩形内的部分填充,即绘制一个实心矩形。
Line 10-12
同样是在300*300的黑色画布上,绘制一个纯白色的实心圆形并显示,圆形的圆心位置为(150, 150),半径为150。
Line 22-46
分别对矩形和圆形进行四种位运算,并依次输出这两张图像位运算的结果。
c.结果呈现
比较简单,就不对结果做多解释了(▽)
4、图像掩膜
首先有个疑问:掩膜是啥(⊙_⊙)?
掩膜的本质其实就是图像的位运算,我们通过将不位于感兴趣区域内的像素点与0相与,将像素点的值转变为0,用黑色掩盖住原像素点,进而突出我们感兴趣的图像区域。当我们只关注于图像中的一部分内容而不关心其剩余部分时,可以采用掩膜的方式将那不重要的部分图像盖住。
因此,掩膜常常应用于简单的背景替换。【学会了掩膜,就可以自己编程来替换证件照背景啦O(∩_∩)O~】
例如,对于如下的一张海景图,倘若我们只关心天空和椰子树,而不关注像海滩等其余图像部分,那么我们就可以首先通过绘制一张矩形掩膜,然后通过与原图像的位运算生成掩膜后的图像,应用矩形掩膜的结果如下表所示。
Original | Mask | Masked image |
接下来就看看怎么通过代码实现吧。
a.源代码呈现
masking.py
import numpy as np
import argparse
import cv2
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True,
help = "Path to the image")
args = vars(ap.parse_args())
# Load the image and show it
image = cv2.imread(args["image"])
cv2.imshow("Original", image)
# Masking allows us to focus only on parts of an image that
# interest us. A mask is the same size as our image, but has
# only two pixel values, 0 and 255. Pixels with a value of 0
# are ignored in the orignal image, and mask pixels with a
# value of 255 are allowed to be kept. For example, let's
# construct a mask with a 150x150 square at the center of it
# and mask our image.
mask = np.zeros(image.shape[:2], dtype = "uint8")
(cX, cY) = (image.shape[1] // 2, image.shape[0] // 2)
cv2.rectangle(mask, (cX - 75, cY - 75), (cX + 75 , cY + 75), 255, -1)
cv2.imshow("Mask", mask)
# Apply out mask -- notice how only the center rectangular
# region of the pill is shown
masked = cv2.bitwise_and(image, image, mask = mask)
cv2.imshow("Mask Applied to Image", masked)
cv2.waitKey(0)
# Now, let's make a circular mask with a radius of 100 pixels
mask = np.zeros(image.shape[:2], dtype = "uint8")
cv2.circle(mask, (cX, cY), 100, 255, -1)
masked = cv2.bitwise_and(image, image, mask = mask)
cv2.imshow("Mask", mask)
cv2.imshow("Mask Applied to Image", masked)
cv2.waitKey(0)
b.代码分析
Line 22-25
创建与图像大小一致的画布,命名为掩膜。
将(cX, cY)赋值为图像的几何中心坐标,并据此在画布中心绘制一个长宽均为150的实心纯白矩形,形成一张掩膜。
Line 29-31
通过图像位运算对掩膜和原图像执行与操作,完成图像掩膜。
图片的呈现效果正如上表所示,只截出了天空和椰子树,而掩盖掉了海滩。
Line 34-39
以图像的几何中心坐标为圆心,绘制一个半径为100的实心圆形掩膜。
【最后两个参数255和-1分别表示像素亮度值为最大即白色以及绘制实心圆】
对原图像应用圆形掩膜后的结果如下表所示:
Original | Mask | Masked image |
思考:实现对证件照的背景颜色替换。
【提示:设置颜色阈值采用cv.inRange函数提取背景掩膜,将掩膜部分在原图中设置为黑色以便添加新的背景色】
(详情参照机器视觉作业2)