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实现图像按位与运算的技巧。

相关推荐
不做超级小白2 分钟前
深入理解 JavaScript 对象字面量:创建对象的简洁方法
开发语言·javascript·ecmascript
我曾经是个程序员3 分钟前
C#集合排序的三种方法(List<T>.Sort、LINQ 的 OrderBy、IComparable<T> 接口)
开发语言·c#
半夏知半秋24 分钟前
rust学习-rust中的格式化打印
服务器·开发语言·后端·学习·rust
SmallBambooCode39 分钟前
【Flask】在Flask应用中使用Flask-Limiter进行简单CC攻击防御
后端·python·flask
IU宝1 小时前
vector的使用,以及部分功能的模拟实现(C++)
开发语言·c++
抱抱宝1 小时前
Pyecharts之图表样式深度定制
python·信息可视化·数据分析
码界筑梦坊1 小时前
基于Flask的哔哩哔哩评论数据可视化分析系统的设计与实现
python·信息可视化·flask·毕业设计
大懒猫软件1 小时前
如何有效使用Python爬虫将网页数据存储到Word文档
爬虫·python·自动化·word
小熊科研路(同名GZH)1 小时前
【Matlab高端绘图SCI绘图模板】第05期 绘制高阶折线图
开发语言·matlab·信息可视化
大数据魔法师1 小时前
1905电影网中国地区电影数据分析(二) - 数据分析与可视化
python·数据分析