OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

OpenCV图像的掩模、运算 与 合并专题 【Python-Open_CV系列(七)】

ʚʕ̯•͡˔•̯᷅ʔɞ
🍹欢迎各路大佬来到小啾主页指点☀️欢迎大家前来学习OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学, Python-Open_CV系列博文第七篇,我是博主侯小啾。
✨我的博客主页:云雀编程巢🌹꧔ꦿ
🌹꧔ꦿ如果博文内容对你有帮助,请点个赞+关注+收藏✨
请添加图片描述请添加图片描述请添加图片描述
竹子

🌹꧔ꦿ最后一个传送门:

✨OpenCV图像处理基本操作 【Python-Open_CV系列(一)】

✨OpenCV像素处理基本操作 【Python-Open_CV系列(二)】

✨OpenCV之 BGR、GRAY、HSV色彩空间&色彩通道专题 【Python-Open_CV系列(三)】

✨OpenCV绘制图像与文字(可作为脚手架代码)(python) 【Python-Open_CV系列(四)】

✨OpenCV图像几何变换专题(缩放、翻转、仿射变换及透视)【python-Open_CV系列(五)】

✨基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】

如果您有任何疑问,请随时在评论部分分享。 ☀️

1.图像的掩模

掩模,即掩码(mask)。用计算机处理图像时,常常是有的内容需要处理,有的内容不需要处理。通过掩模,可以实现将我们不需要处理的部分暂时“遮住”,以保证其保持不变。而仅仅操作其暴露出来的部分。整个操作过程就像做手术时医生使用的“手术洞巾”。

掩模过程通常使用二值图像表示,像素值0表示纯黑色,其区域表示我们不需要操作的部分。像素值为255的纯白色部分表示我们想要操作的部分。(某些情况也可以用0,1作为掩模值)。掩模对象通过操作numpy数组创建,没有专有方法。

以名画《思考的人》为例,我们将对其进行面具操作测试。

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

此图片长1080,高810,途中正在饭桌上思考的男人,名叫莱纳。
我们的目标是尽可能多地覆盖 Reiner 的上半身,下边框以右侧的瓶口为界。
使用矩形框住 Reiner 所在的位置。矩形四个点的坐标大致是
A.(568, 28)   B.(1044, 28)
C.(568, 430)   D.(1044, 430)

(可以使用绘图工具估计坐标。)
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

掩码代码如下:

import cv2
import numpy as np

mask = np.zeros((810, 1080, 1), np.uint8)
mask[28:430, 568:1044, :] = 255
cv2.imshow("mas", mask)
cv2.waitKey()
cv2.destroyAllWindows()

程序执行效果如下:

这是此图像的蒙版图像:
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.图像的运算

2.1 图像的加法运算

两幅图像相加即相同位置的像素值之间一 一相加。图像的相加通常有两种方法,一种是使用“+”符号连接两个数组,另一种则是使用add()方法。

2.1.1 “+”方法

使用“+”这种方法我们在做图像处理时通常不会采用,因为相加后的像素值精彩会出现大于255的情况。而大于255的像素值,则会取该值除以255后的余数,即取模。因此原图中白色的衣服,经过加法运算后反而颜色变暗了。

import cv2
img = cv2.imread("pic.jpg")
result_pic = img + img
cv2.imshow("+", result_pic)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.1.2 cv2.add()方法

cv2.add()相加得到的图像,如果存在像素值大于255,取255。这一点相比使用加号要好得多,明显更利于我们的图像处理。

使用cv2.add()方法,该方法语法如下:

add(src1, src2, mask=None, dtype=None)

  • src1 与 src2 即需要相加的两幅图像
  • mask是可选参数,掩模对象。默认没有
  • dtype 图像深度。
import cv2
img = cv2.imread("trump.jpg")
result_pic = cv2.add(img, img)
cv2.imshow("add", result_pic)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.1.3 使用掩模遮盖相加结果

在相加的时候,可以说掩码图片也是作为参数传入的,对相加结果进行掩码。

import cv2
import numpy as np
img = cv2.imread("pic.jpg")

# 细节
m = np.zeros((810, 1080, 1), np.uint8)
m[28:430, 568:1044, :] = 255
image5 = cv2.add(img, img, mask=m)
cv2.imshow("use mask", image5)
cv2.waitKey()
cv2.destroyAllWindows()

图像处理结果:
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】
值得注意的是,这里有一个非非非非非非非非非常重要的细节,很多人都会在这里被卡壳(很显然博主也被卡了)。就是掩模对象是灰度图像,不是说看起来是灰度图像,而是数组要是灰度图像的数组,即创建的到时候m = np.zeros((a, b, 1), np.uint8)中 (a, b, 1)最后一个数字是1,不能顺手写成3。否者就会有下面的报错:

image5 = cv2.add(img, img, mask=m)
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:706: error: (-215:Assertion failed) (mtype == CV_8UC1 || mtype == CV_8SC1) && _mask.sameSize(*psrc1) in function ‘cv::arithm_op’

意思是mask的size有问题。

2.2 图像的位运算

位运算是二进制数的唯一运算。也可以将图像像素阵列中的十进制数转换为二进制数,然后进行位运算。

OpenCV提供了以下位运算方法

  • cv2.bitwise_and()  按位与
  • cv2.bitwise_or()  按位或
  • cv2.bitwise_not()  按位取反
  • cv2.bitwise_xor()  按位异或


cvbitwise_and() 与 bitwise_or() 方法都有三个参数,scr1,scr2,mask,即图像1,图像2与掩码

cv2.bitwise_not() 与 cv2.bitwise_xor()方法都有两个参数,scr与mask,即图像与掩码。

2.2.1 按位与 cv2.bitwise_and()

让mask和目标图像做AND运算,同样可以达到mask覆盖图像的处理效果。
这是制作交叉蒙版的示例。

import cv2
import numpy as np

img1 = cv2.imread("pic.jpg")
mask = np.zeros(img1.shape, np.uint8)
# 横着的白色区域
mask[490:600, :, :] = 255
# 竖着的白色区域
mask[:, 470:545, :] = 255
img2 = cv2.bitwise_and(img1, mask)
cv2.imshow("img", img2)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.2.2 按位或 cv2.bitwise_or()

对图像使用按位或运算可以实现与按位与运算相反的结果。

import cv2
import numpy as np

img1 = cv2.imread("pic.jpg")
mask = np.zeros(img1.shape, np.uint8)
# 横着的白色区域
mask[490:600, :, :] = 255
# 竖着的白色区域
mask[:, 470:545, :] = 255
img2 = cv2.bitwise_or(img1, mask)
cv2.imshow("img", img2)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.2.3 按位取反 cv2.bitwise_not()

按位取反是仅对一个图像做的操作,根据二进制,如果某位置上数值为0,则改为1;如果为1则该为0。

import cv2

img1 = cv2.imread("pic.jpg")
img2 = cv2.bitwise_not(img1)
cv2.imshow("img", img2)
cv2.waitKey()
cv2.destroyAllWindows()

处理结果如下图所示:
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.2.4 按位异或 cv2.bitwise_xor()

对二进制位进行判断,如果两个运算数的同一位上的数字相同,则运算结果的相同位数字取0,否则取1。
这个描述有些抽象。可以简单理解为,将蒙版匹配的区域颠倒过来,蒙版无法匹配的区域与图像保持一致。详情见下图:

import cv2
import numpy as np

img1 = cv2.imread("pic.jpg")
mask = np.zeros(img1.shape, np.uint8)
# 横着的白色区域
mask[490:600, :, :] = 255
# 竖着的白色区域
mask[:, 470:545, :] = 255
img = cv2.bitwise_xor(img1, mask)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()

效果呈现:
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

2.3 图像加密

通过按位异或运算,还可以实现对图像的加密。使用numpy创建随机数组的方法,创建一个随机像素值图像作为密匙,进而实现对原图像的加密和解密。结果因图片过大不再展示。

import cv2
import numpy as np


# 定义加密、解密方法
def encode_img(img, img_key):
    result = img = cv2.bitwise_xor(img, img_key)
    return result

# 原图
img = cv2.imread("pic.jpg")
rows, colmns, channel = img.shape
# 创建大小相等的密钥图像
img_key = np.random.randint(0, 256, (rows, colmns, 3), np.uint8)
cv2.imshow("img", img)
cv2.imshow("img_key", img_key)
Encryption_result = encode_img(img, img_key)
cv2.imshow("After Encryption", Encryption_result)
Decryption_result = encode_img(Encryption_result, img_key)
cv2.imshow("After Decryption", Decryption_result)
cv2.waitKey()
cv2.destroyAllWindows()

3.图像的合并

图像合并也是图像处理中的常见操作。图像合并可分为加权合并和叠加合并。

再找一张与pic.jpg相同尺寸、名为“pic2.jpg”的图片如下图所示:

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

将该图片与pic.jpg分别按照0.2和0.8的权重进行合并,代码即执行效果如下:

3.1加权合并

import cv2
img1 = cv2.imread("pic.jpg")
img2 = cv2.imread("pic2.jpg")
rows, colmns, channel = img1.shape
img3 = cv2.resize(img2, (colmns, rows))
img = cv2.addWeighted(img1, 0.8, img3, 0.2, 0)
cv2.imshow("new_pic", img)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

3.2 覆盖合并

OpenCV没有直接提供覆盖操作的方法,因此要实现覆盖还需要自己动手。

以下边这张金底白字的标签图片为例(pic3.png),
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】
将其贴在pic.jpg上(覆盖)

import cv2
img1 = cv2.imread("pic.jpg")
img2 = cv2.resize(cv2.imread("pic3.png"), dsize=None, fx=2, fy=2)
y, x, z = img2.shape
X = 180
Y = 70
img1[Y:Y+y, X:X+x, :] = img2
cv2.imshow("new_pic", img1)
cv2.waitKey()
cv2.destroyAllWindows()

效果如下
OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

🌹꧔ꦿ小酒感谢您的关注和支持!竹子

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(1)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年4月6日 下午2:30
下一篇 2022年4月6日 下午2:58

相关推荐