Opencv图像处理之详解掩膜mask
1.在OpenCV中我们经常会遇到⼀个名字:Mask(掩膜)。很多函数都使⽤到它,那么这个Mask到底什么呢?
2.如果我们想要裁剪图像中任意形状的区域时,应该怎么办呢?
答案是,使⽤掩膜(masking)。
我们先看⼀下掩膜的基础。图像的位运算。
图像基本运算
图像的基本运算有很多种,⽐如两幅图像可以相加、相减、相乘、相除、位运算、平⽅根、对数、绝对值等;图像也可以放⼤、缩⼩、旋转,还可以截取其中的⼀部分作为ROI(感兴趣区域)进⾏操作,各个颜⾊通道还可以分别提取及对各个颜⾊通道进⾏各种运算操作。总之,对于图像可以进⾏的基本运算⾮常的多,只是挑了些常⽤的操作详解。
bitwise_and、bitwise_or、bitwise_xor、bitwise_not这四个按位操作函数。
void bitwise_and(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()); //dst = src1 & src2
void bitwise_or(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()); //dst = src1 | src2
void bitwise_xor(InputArray src1, InputArray src2,OutputArray dst, InputArray mask=noArray()); //dst = src1 ^ src2
void bitwise_not(InputArray src, OutputArray dst,InputArray mask=noArray()); //dst = ~src
上述的基本操作中都属于将基础数学运算应⽤于图像像素的处理中,下⾯将着重介绍
bitwise_and是对⼆进制数据进⾏“与”操作,即对图像(灰度图像或彩⾊图像均可)每个像素值进⾏⼆进制“与”操
作,1&1=1,1&0=0,0&1=0,0&0=0
bitwise_or是对⼆进制数据进⾏“或”操作,即对图像(灰度图像或彩⾊图像均可)每个像素值进⾏⼆进制“或”操作,1|1=1,1|0=0,0|1=0,0|0=0 bitwise_xor是对⼆进制数据进⾏“异或”操作,即对图像(灰度图像或彩⾊图像均可)每个像素值进⾏⼆进制“异或”操
作,1^1=0,1^0=1,0^1=1,0^0=0
bitwise_not是对⼆进制数据进⾏“⾮”操作,即对图像(灰度图像或彩⾊图像均可)每个像素值进⾏⼆进制“⾮”操作,~1=0,~0=1
为了便于⼤家进⼀步理解,下⾯给出测试代码:
# opencv 图像的基本运算
# 导⼊库
import numpy as np
import argparse
import cv2
# 构建参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# 加载图像
image = cv2.imread(args["image"])
cv2.imshow("image loaded", image)
# 创建矩形区域,填充⽩⾊255
rectangle = np.zeros(image.shape[0:2], dtype="uint8")
cv2.imshow("Rectangle", rectangle)
# 创建圆形区域,填充⽩⾊255
circle = np.zeros(image.shape[0:2], dtype="uint8")
cv2.circle(circle, (150, 150), 150, 255, -1) # 修改
cv2.imshow("Circle", circle)
# 在此例(⼆值图像)中,以下的0表⽰⿊⾊像素值0, 1表⽰⽩⾊像素值255
# 位与运算,与常识相同,有0则为0, 均⽆0则为1
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)
# ⾮运算,⾮0为1, ⾮1为0
bitwiseNot = cv2.bitwise_not(circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)
# 或运算,有1则为1, 全为0则为0
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)
# 异或运算,不同为1, 相同为0
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)
可以看到,原图是⼀张星空夜景图。效果如下:
为了便于展⽰,后⾯我只截取部分区域效果:
掩膜(mask)
在有些图像处理的函数中有的参数⾥⾯会有mask参数,即此函数⽀持掩膜操作,⾸先何为掩膜以及有什么⽤,如下:
数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯⽚⼯艺步骤采⽤光刻技术,⽤于这些步骤的图形“底⽚”称为掩膜(也称作“掩模”),其作⽤是:在硅⽚上选定的区域中对⼀个不透明的图形模板遮盖,继⽽下⾯的腐蚀或扩散将只影响选定的区域以外的区域。
图像掩膜与其类似,⽤选定的图像、图形或物体,对处理的图像(全部或局部)进⾏遮挡,来控制图像处理的区域或处理过程。
数字图像处理中,掩模为⼆维矩阵数组,有时也⽤多值图像,图像掩模主要⽤于:
rectangle函数opencv①提取感兴趣区,⽤预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,⽽区外图像值都为0。
②屏蔽作⽤,⽤掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
③结构特征提取,⽤相似性变量或图像匹配⽅法检测和提取图像中与掩模相似的结构特征。
④特殊形状图像的制作。
在所有图像基本运算的操作函数中,凡是带有掩膜(mask)的处理函数,其掩膜都参与运算(输⼊图像运算完之后再与掩膜图像或矩阵运算)。掩膜实例
如开篇所提问题2,要对⼀幅图进⾏抠图(裁剪)操作,这就要⽤到Mask了,那么就以抠图为例,解释Mask在⾥⾯的作⽤。同样以上图为例,从原图中裁剪⼩树。
我们利⽤OR结果(其他结果也⾏),修改调整后,
代码如下:
# opencv 图像的基本运算
# 导⼊库
import numpy as np
import argparse
import cv2
# 构建参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# 加载图像
image = cv2.imread(args["image"])
cv2.imshow("image loaded", image)
# 创建矩形区域,填充⽩⾊255
rectangle = np.zeros(image.shape[0:2], dtype="uint8")
cv2.imshow("Rectangle", rectangle)
# 创建圆形区域,填充⽩⾊255
circle = np.zeros(image.shape[0:2], dtype="uint8")
cv2.circle(circle, (520, 455), 140, 255, -1) # 修改
cv2.imshow("Circle", circle)
'''
# 在此例(⼆值图像)中,以下的0表⽰⿊⾊像素值0, 1表⽰⽩⾊像素值255
# 位与运算,与常识相同,有0则为0, 均⽆0则为1
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)
# ⾮运算,⾮0为1, ⾮1为0
bitwiseNot = cv2.bitwise_not(circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)
# 异或运算,不同为1, 相同为0
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)
'''
# 或运算,有1则为1, 全为0则为0
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)
# 使⽤mask
mask = bitwiseOr
cv2.imshow("Mask", mask)
# Apply out mask -- notice how only the person in the image is cropped out masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask Applied to Image", masked)
cv2.waitKey(0)
结果展⽰:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。