python学opencv|读取图像(四十三)使用cv2.bitwise_and()函数实现图像按位与运算

【1】引言

前序已经对图像叠加进行了一些探索:

python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖-CSDN博客

python学opencv|读取图像(四十一 )使用cv2.add()函数实现各个像素点BGR叠加-CSDN博客

python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加-CSDN博客

这些叠加的本质上都是通过叠加各个像素点上的BGR值实现的。

有时候需要仿照数学上的做法,对像素点上的值做与运算,这时候就要使用cv2.bitwise_and()函数。

【2】官网教程

点击下方链接,直达官网教程:OpenCV: Operations on arrays

官网对cv2.bitwise_and()函数的说明为:

++图1++

具体的,参数意义为:

void cv::bitwise_and ( InputArray src1, #第一个图像

InputArray src2, #第二个图像

OutputArray dst, #输出图像

InputArray mask = noArray() ) #掩模,单通道数据,可选参数

按位与运算要求数据的大小一致,对于三通道图像,会逐个通道进行按位与运算。

【3】代码测试

【3.1】灰度图像

首先对灰度图像进行按位与运算,先引入必要的模块和初始图像:

python 复制代码
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片-直接转化灰度图
src = cv.imread('srcp.png',0) #读取图像
dst=src#输出图像

然后定义了第二个图像,是一个黑色画布加灰白色掩模矩阵的图像,定义按位与运算:

python 复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :] = 200  # 第一个通道值
image[:,100:350 ] = 200  # 第二个通道值
#image[:, :, 200:300] = 255  # 第三个通道值
img=cv.bitwise_and(src,image) #与运算

然后显示和保存图像:

python 复制代码
#显示BGR值
print("dst像素数为[150,150]位置处的BGR=", dst[150,150])  # 获取像素数为[100,100]位置处的BGR
print("img像素数为[150,150]位置处的BGR=", img[150,150])  # 获取像素数为[100,100]位置处的BGR


#合并图像
himg=np.hstack((src,img))
# 显示和保存定义的图像
cv.imshow('display-and-src-2', dst)  # 显示图像
cv.imshow('display-and-2', img)  # 显示图像
cv.imwrite('display-and-2.png', img)  # 保存图像
cv.imshow('display-and-image-2', image)  # 显示图像
cv.imwrite('display-and-image-2.png', image)  # 保存图像
cv.imshow('display-and-himg-2', himg)  # 显示图像
cv.imwrite('display-and-himg-2.png', himg)  # 保存图像
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

代码运行相关的图像为:

++图2 初始图像++

++图3 按位与运算后的图像-灰度图像++

++图4 掩模-二维矩阵++

++图5 初始图像和按位与运算后的图像对比-灰度图像++

由图2至图5可见,经过按位与运算后,只在掩模区域显示了图像,并且图像的清晰度发生了变化,进一步读取到的特定点BGR值为:

++图6 特定点BGR值++

由图6显示BGR值,结合掩模定义代码,可知在按位与运算过程中,显示出来的图像BGR值统一为掩模值200。

复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :] = 200  # 第一个通道值
image[:,100:350 ] = 200  # 第二个通道值

此时的完整代码为:

python 复制代码
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片-直接转化灰度图
src = cv.imread('srcp.png',0) #读取图像
dst=src#输出图像

# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :] = 200  # 第一个通道值
image[:,100:350 ] = 200  # 第二个通道值
#image[:, :, 200:300] = 255  # 第三个通道值
img=cv.bitwise_and(src,image) #与运算

#显示BGR值
print("dst像素数为[150,150]位置处的BGR=", dst[150,150])  # 获取像素数为[100,100]位置处的BGR
print("img像素数为[150,150]位置处的BGR=", img[150,150])  # 获取像素数为[100,100]位置处的BGR


#合并图像
himg=np.hstack((src,img))
# 显示和保存定义的图像
cv.imshow('display-and-src-2', dst)  # 显示图像
cv.imshow('display-and-2', img)  # 显示图像
cv.imwrite('display-and-2.png', img)  # 保存图像
cv.imshow('display-and-image-2', image)  # 显示图像
cv.imwrite('display-and-image-2.png', image)  # 保存图像
cv.imshow('display-and-himg-2', himg)  # 显示图像
cv.imwrite('display-and-himg-2.png', himg)  # 保存图像
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

【3.2】彩色图像

之后进行彩色图像的零值和反零值处理,首先需要改一行代码,将src = cv.imread('srcp.png',0)改为:

复制代码
src = cv.imread('srcp.png') #读取图像

然后定义掩模矩阵为三维矩阵:

复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :, :] = 200  # 第一个通道值
image[:,100:350,: ] = 200  # 第二个通道值

直接输出完整代码:

python 复制代码
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片-直接转化灰度图
src = cv.imread('srcp.png') #读取图像
dst=src#输出图像

# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :, :] = 200  # 第一个通道值
image[:,100:350,: ] = 200  # 第二个通道值
#image[:, :, 200:300] = 255  # 第三个通道值
img=cv.bitwise_and(src,image) #与运算

#显示BGR值
print("dst像素数为[150,150]位置处的BGR=", dst[150,150])  # 获取像素数为[100,100]位置处的BGR
print("img像素数为[150,150]位置处的BGR=", img[150,150])  # 获取像素数为[100,100]位置处的BGR

#合并图像
himg=np.hstack((src,img))
# 显示和保存定义的图像
cv.imshow('display-and-src', dst)  # 显示图像
cv.imshow('display-and', img)  # 显示图像
cv.imwrite('display-and.png', img)  # 保存图像
cv.imshow('display-and-image', image)  # 显示图像
cv.imwrite('display-and-image.png', image)  # 保存图像
cv.imshow('display-and-himg', himg)  # 显示图像
cv.imwrite('display-and-himg.png', himg)  # 保存图像
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

代码运行的相关图像为:

++图7 按位与运算后的图像-彩色图像++

++++

++图8 掩模-三维矩阵++

++图9 初始图像和按位与运算后的图像对比-彩色图像++

进一步探索第二个图像掩模BGR值带来的BGR值变化,读取到的特定像素点BGR值为:

++图10 特定点BGR值++

由图10显示BGR值,结合掩模定义代码,可知在按位与运算过程中,显示出来的图像BGR值只在R通道统一为200。

【4】代码测试

实际上上述图像在做按位与运算的时候,没有加入掩模,上述提记的掩模是指第二个图像自身所带的掩模。

【4.1】第二个图像掩模值修改

然后做一个测试,将第二个图像的掩模值改为255:

灰度图像的修改值为:

复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :] = 200  # 第一个通道值
image[:,100:350 ] = 255  # 第二个通道值

运行后获得的BGR值为:

++图11 特定点BGR值-灰度图像++

此时的图像对比效果为:

++++

++图12 初始图像和按位与运算后的图像对比-灰度图像++

图12所展示的图像表明,在image[:,100:350 ] = 255 ,也就是第二个通道值确定的区域,图像的BGR值和原图像其实是一致的。

++图13 变化对比-灰度图像++

彩色图像的修改值为:

复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :, :] = 200  # 第一个通道值
image[:,100:350,: ] = 255  # 第二个通道值

运行后获得的BGR值为:

++图14 特定点BGR值-彩色图像++

此时的图像对比效果为:

++图15 初始图像和按位与运算后的图像对比-彩色图像++

图15所展示的图像表明,在image[:,100:350,: ] = 255 ,也就是第二个通道值确定的区域,图像的BGR值和原图像其实是一致的。

++图16 变化对比-彩色图像++

这种变化效果,本质上有一种截断的可能:当高于第二个图像给定的掩模值后,图像BGR值会被截断到掩模值,其余就保持原值。

【4.2】第二个图像掩模值扩大

然后继续利用彩色图像的通道数为3,扩大第二个图像的掩模矩阵定义范围:

复制代码
# 定义图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('像素大小为',src.shape)
image[100:200, :, :] = 55  # 第一个通道值
image[:,100:350,: ] = 155  # 第二个通道值
image[:, :, 200:300] = 255  # 第三个通道值

此时代码运行后,获得的相关图像为:

++图17 初始图像和按位与运算后的图像对比-彩色图像++

++++

++图18 掩模-三维矩阵扩展++

++图19 按位与运算后的图像-彩色图像++

图18和图19是对图17的解释,图18 的颜色深深浅,自然也会影响到图19 的颜色深浅。

此时获得的特定点BGR值为:

++图20 特定点BGR值-彩色图像++

【5】总结

掌握了python+opencv实现图像按位与运算的技巧。

相关推荐
databook2 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar3 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780514 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_4 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机10 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机11 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机11 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机11 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i11 小时前
drf初步梳理
python·django
每日AI新事件11 小时前
python的异步函数
python