OpenCV第六章——图像运算

1.掩模

什么是掩模???

掩模(mask)是一个与原图像大小相同的二值图像,其中每个像素的值是 0(纯黑) 或 1(纯白)(或其他值,通常为 0 和 255)。掩模的主要作用是选择图像中的特定区域进行处理。例如:

  • 区域选择:掩模中的非零值(如 1 或 255)标识要操作的区域,而零值标识不需要处理的区域。
  • 图像合成:可以用掩模将两幅图像合成在一起,仅将掩模中标记的部分进行合成。
  • 特定区域处理:例如,应用滤镜或调整亮度/对比度时,仅对掩模中的非零部分进行处理。

通过掩模,可以精确控制图像处理操作的区域,提高处理的灵活性和效率。

下面我们来创建一个掩模图像 !

示例代码:

import cv2
import numpy as np

# 使用zeros()方法创建宽150、高150、3通道,像素类型为无符号8位数字的零值图像
mask = np.zeros((150, 150, 3), np.uint8)
mask[50:90, 20:90, :] = 255;  # 50~100行、20~80列的像素改为纯白像素
cv2.imshow("mask1", mask)  # 展示掩模
mask[:, :, :] = 255;  # 全部改为纯白像素
mask[50:100, 20:80, :] = 0;  # 50~100行、20~80列的像素改为纯黑像素
cv2.imshow("mask2", mask)  # 展示掩模
cv2.waitKey()  
cv2.destroyAllWindows()  

效果图像如下:

2.图像的加法运算

图像的加法运算就是让相同位置的像素值相加,最后将计算结果按照原位置重新组成一个图像。

OpenCV为我们提供了add()方法对图像进行加法运算,语法格式如下:

dst = cv2.add(src1, src2, mask, dtype)

参数说明:

scr1:第一幅图像

scr2:第二幅图像

mask: 可选参数, 掩模

dtype:可选参数, 图像深度

返回值说明:

dst: 相加之后ide结果图像,若相加之后结果大于255则取255

2.1 计算图像和

2.1.1 使用“+”

示例代码:

import cv2

img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg") 
sum1 = img + img  # 使用运算符相加
cv2.imshow("img", img)  # 展示原图
cv2.imshow("sum1", sum1)  # 展示运算符相加结果
cv2.waitKey()  
cv2.destroyAllWindows()  

结果图像:

2.1.2 使用add()方法

示例代码:

import cv2

img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg") 
sum2 = cv2.add(img, img)  # 使用方法相加
cv2.imshow("img", img)  # 展示原图
cv2.imshow("sum2", sum2)  # 展示方法相加结果
cv2.waitKey()  
cv2.destroyAllWindows()  

结果图像:

2.2 模拟三色光叠加得白光

光学中三原色为红绿蓝,三种颜色混在一起会变为白色

 示例代码:

import cv2
import numpy as np

img1 = np.zeros((150, 150, 3), np.uint8)  # 创建150*150的0值图像
img1[:, :, 0] = 255  # 蓝色通道賦予最大值,创建纯蓝图像
img2 = np.zeros((150, 150, 3), np.uint8)
img2[:, :, 1] = 255  # 绿色通道賦予最大值,创建纯绿图像
img3 = np.zeros((150, 150, 3), np.uint8)
img3[:, :, 2] = 255  # 红色通道賦予最大值,创建纯红图像
cv2.imshow("1", img1)  # 展示蓝色图像
cv2.imshow("2", img2)  # 展示绿色图像
cv2.imshow("3", img3)  # 展示红色图像
img = cv2.add(img1, img2)  # 蓝色 + 绿色 = 青色
cv2.imshow("1+2", img)  # 展示蓝色加绿色的结果
img = cv2.add(img, img3)  # 红色 + 青色 = 白色
cv2.imshow("1+2+3", img)  # 展示三色图像相加的结果
cv2.waitKey()  
cv2.destroyAllWindows()  

结果图像如下:

2.3 使用掩模遮盖相加结果

示例代码:

import cv2
import numpy as np

img1 = np.zeros((250, 250, 3), np.uint8)  # 创建250*250的0值图像
img1[:, :, 0] = 255  # 蓝色通道賦予最大值,创建纯蓝图像
img2 = np.zeros((250, 250, 3), np.uint8)
img2[:, :, 2] = 255  # 红色通道賦予最大值,创建纯红图像

img = cv2.add(img1, img2)  # 蓝色 + 红色 = 洋红色
cv2.imshow("no mask", img)  # 展示相加的结果

m = np.zeros((250, 250, 1), np.uint8)  # 创建掩模
m[50:200, 50:200, :] = 255  # 掩模中央位置为纯白色
cv2.imshow("mask", m)  # 展示掩模

img = cv2.add(img1, img2, mask=m)  # 相加时使用掩模
cv2.imshow("use mask", img)  # 展示相加的结果

cv2.waitKey()  
cv2.destroyAllWindows()  

结果图像:

3.图像的位运算

图像的位运算是对图像像素值的逐位操作,用于实现各种图像处理效果,比如遮罩、图像合成和特征提取。常见的位运算包括 AND、OR、XOR 和 NOT。

在 OpenCV 中,常用的位运算方法有:

  • cv2.bitwise_and(): 计算两个图像的按位与 运算。
  • cv2.bitwise_or(): 计算两个图像的按位或运算。
  • cv2.bitwise_xor(): 计算两个图像的按位取反运算。
  • cv2.bitwise_not(): 计算单个图像的按位异或运算。

3.1按位与运算

OpenCV提供了bitwise()方法来对图像做与运算,其语法结构如下:

dst = cv2.bitwise_and(src1,src2, mask)

参数说明同上。

示例代码:

import cv2
import numpy as np

flower = cv2.imread(r"B:\Python_opencv_book\06\05\amygdalus triloba.png")  
mask = np.zeros(flower.shape, np.uint8)  # 与花图像大小相等的掩模图像
mask[120:180, :, :] = 255  # 横着的白色区域
mask[:, 80:180, :] = 255  # 竖着的白色区域
img = cv2.bitwise_and(flower, mask)  # 与运算
cv2.imshow("flower", flower)  # 展示花图像
cv2.imshow("mask", mask)  # 展示掩模图像
cv2.imshow("img", img)  # 展示与运算结果
cv2.waitKey()  
cv2.destroyAllWindows() 

 结果图像:

3.2 按位或运算

按位或运算(bitwise OR)对每对对应的二进制位进行操作。规则是:如果对应的二进制位中至少有一个是1,那么结果位就是1;否则,结果位是0

语法格式如下:

dst = cv2.bitwise_or(src1, src2, mask)

 示例代码如下:

import cv2
import numpy as np

flower = cv2.imread(r"B:\Python_opencv_book\06\05\amygdalus triloba.png")  
mask = np.zeros(flower.shape, np.uint8)  # 与花图像大小相等的掩模图像
mask[120:180, :, :] = 255  # 横着的白色区域
mask[:, 80:180, :] = 255  # 竖着的白色区域
img = cv2.bitwise_or(flower, mask)  # 或运算
cv2.imshow("flower", flower)  # 展示花图像
cv2.imshow("mask", mask)  # 展示掩模图像
cv2.imshow("img", img)  # 展示或运算结果
cv2.waitKey()  
cv2.destroyAllWindows()  

结果图像如下:

3.3按位取反运算

按位取反运算(bitwise NOT)将每个二进制位的值取反。也就是说,0 变成 1,1 变成 0。

 OpenCV提供bitwise_not()方法对图像做取反运算,语法格式如下:

dst = cv2.bitwise_not(src, mask)

示例代码如下:

import cv2

img1 = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg")  
img2 = cv2.bitwise_not(img1)  # 取反运算
cv2.imshow("img1", img1)  # 展示花图像
cv2.imshow("img2", img2)  # 展示取反运算结果
cv2.waitKey()  
cv2.destroyAllWindows()  

运行结果如下:

可以看到,图像经过取反运算后会呈现与原图完全相反的颜色效果!!!

3.4 按位异或运算

如果两个运算数统一为上的数字相同, 则运算结果的相同数字取0否则取1。

OpenCV提供了bitwise_xor()的方法来对图像进行异或运算,语法格式如下:

dst = cv2.bitwise_xor(src, mask)

3.4.1 图像与十字掩模做异或运算

某像素与纯白色像素进行异或运算, 结果为原像素的取反结果

00101011 & 11111111 = 11010100

某像素与纯黑色像素进行异或运算, 结果仍是该像素的原值

00101011 & 0000000  =  00101011

示例代码如下:

import cv2
import numpy as np

img1 = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg")  
m = np.zeros(img1.shape, np.uint8)  # 与花图像大小相等的0值图像
m[120:180, :, :] = 255  # 横着的白色区域
m[:, 80:180, :] = 255  # 竖着的白色区域
img = cv2.bitwise_xor(img1, m)  # 两幅图像做异或运算
cv2.imshow("img1", img1)  # 展示花图像
cv2.imshow("mask", m)  # 零值图像
cv2.imshow("img", img)  # 异或运算结果
cv2.waitKey()  
cv2.destroyAllWindows()  

操作结果图像如下:

3.4.2 对图像进行加密解密

示例代码如下:

import cv2
import numpy as np

def encode(img, img_key): # 加密、解密方法
    result = img = cv2.bitwise_xor(img, img_key)  # 两图像做异或运算
    return result

flower = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg")  # 花原始图像
rows, colmns, channel = flower.shape  # 原图像的行数、列数和通道数
# 创建与花图像大小相等的随机像素图像,作为密钥图像
img_key = np.random.randint(0, 256, (rows, colmns, 3), np.uint8)

cv2.imshow("1", flower)  # 展示花图像
cv2.imshow("2", img_key)  # 展示秘钥图像

result = encode(flower, img_key)  # 对花图像进行加密
cv2.imshow("3", result)  # 加密图像
result = encode(result, img_key)  # 对花图像进行解密
cv2.imshow("4", result)  # 解密图像
cv2.waitKey() 
cv2.destroyAllWindows()  

操作结果图像如下:

4.合并图像

4.1 加权和

Opencv提供addWeighted()方法计算图像的加权和,语法格式如下:

dst = cv2.addWeighted(src1, alpha, src2, beta, gamma)

参数说明:

alpha:第一幅图像的权重

beta:第二幅图像的权重

gamma:在和结果行添加的标量, 该值越大, 结果图像越亮, 反之越暗,可以为负值。

示例代码如下:

import cv2
img1 = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  # 原始图像1
img2 = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(1).jpg")  # 原始图像2
rows, colmns, channel = img1.shape  # img1的行数、列数和通道数
img2 = cv2.resize(img2, (colmns, rows))  # img2缩放成日落图像大小
img3 = cv2.addWeighted(img1, 0.6, img2, 0.6, 0)  # 计算两幅图像加权和
cv2.imshow("img1", img1)  
cv2.imshow("img2", img2)  
cv2.imshow("addWeighted", img3)  # 展示加权和图像
cv2.waitKey()  
cv2.destroyAllWindows()  

操作结果图像如下:

4.2 覆盖

OpenCV中没有直接实现图像覆盖操作的方法,我们可以从图像1中取像素值,赋值给图像2的像素,这样就能在图像2中看到图像1的信息了。

示例代码如下:

import cv2

beach_img = cv2.imread(r"B:\Python_opencv_book\06\11\beach.jpg")  # 沙滩原始图像
cat_img = cv2.imread(r"B:\Python_opencv_book\06\11\cat.jpg")  # 小猫原始图像
cat = cat_img[75:400, 120:260, :]  # 截取75行至400行、120列至260列的像素值所组成的图像
cat = cv2.resize(cat, (70, 160))  # 将截取出的图像缩放成70*160大小
cv2.imshow("cat", cat_img)  # 展示小猫原始图像
cv2.imshow("cat2", cat)  # 展示截取并缩放的小猫图像
cv2.imshow("beach", beach_img)  # 展示沙滩原始图像
rows, colmns, channel = cat.shape  # 记录截取图像的行数和列数
# 将沙滩中一部分像素改成截取之后的图像
beach_img[100:100 + rows, 260:260 + colmns, :] = cat
cv2.imshow("beach2", beach_img)  # 展示修改之后的图像
cv2.waitKey() 
cv2.destroyAllWindows()  #

操作结果图像如下:

 

那么本章内容就到此结束了!!! 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值