python学opencv|读取图像(四十八)使用cv2.bitwise_xor()函数实现图像按位异或运算

news2025/1/31 0:57:16

【0】基础定义

按位与运算:两个等长度二进制数上下对齐,全1取1,其余取0。

按位或运算:两个等长度二进制数上下对齐,有1取1,其余取0。

按位取反运算:一个二进制数,0变1,1变0。

按位异或运算: 两个等长度二进制数上下对齐,相同取0,其余取1。

【1】引言

前序已经学习了cv2.bitwise_and()函数、cv2.bitwise_or()函数和cv2.bitwise_not()函数进行图像按位与计算、按位或运算和按位取反运算,相关文章链接为:

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

python学opencv|读取图像(四十四)原理探究:bitwise_and()函数实现图像按位与运算-CSDN博客

python学opencv|读取图像(四十五)增加掩模:使用cv2.bitwise_and()函数实现图像按位与运算-CSDN博客python学opencv|读取图像(四十六)使用cv2.bitwise_or()函数实现图像按位或运算-CSDN博客python学opencv|读取图像(四十五)增加掩模:使用cv2.bitwise_and()函数实现图像按位与运算-CSDN博客

python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算-CSDN博客

在此基础上,我们再次回到两个图像的操作,使用的函数cv2.bitwise_xor()实现图像在各个像素点BGR值的异或。

【2】官网教程

【2.1】cv2.bitwise_xor()函数

点击下方链接,直达函数cv2.bitwise_xor()的官网教程:

OpenCV: Operations on arrays

官网对函数的说明页面为:

图1  cv2.bitwise_xor()的官网教程

在cv2.bitwise_xor()的官网教程可以看到,函数的参数说明为:

void cv::bitwise_xor     (     InputArray     src1,   #输入图像1
        InputArray     src2,                                     #输入图像2
        OutputArray     dst,                                    #输出图像
        InputArray     mask = noArray() )               #掩模矩阵,单通道二维矩阵

和之前的几个位操作函数一样,在函数cv2.bitwise_xor()中,调用掩模效果对应的掩模矩阵为8位单通道二维矩阵 。

【2.2】np.bitwise_xor()函数

点击下方链接,直达函数np.bitwise_xor()的官网教程:

numpy.bitwise_xor — NumPy v2.2 Manual

代码先后使用cv2.bitwise_xor()函数和np.bitwise_xor()函数来展示图像按位异或操作的基本原理。

【3】代码测试

参考前述学习进程中调用的代码,按照输入图像-按位异或-输出图像的顺序规划代码。

首先引入相关模块和图像:

import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块

# 读取图片-直接转化灰度图
src = cv.imread('srcx.png') #读取图像
dst=src #输出图像
gray_src=cv.cvtColor(src,cv.COLOR_BGR2GRAY) #转化为灰度图
dstg=gray_src #输出图像
print('初始图像像素大小为',src.shape)
print('初始图像灰度图像素大小为',gray_src.shape)

然后定义第二张图像和掩模矩阵:

# 定义第二个图像
image = np.zeros(src.shape, np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
print('初始图像像素大小为',src.shape)
image[50:350, :, :] = 180  # 行掩模
image[:,120:200,: ] = 255  # 列掩模
image[:, :, 2] = 120  # 第二个通道值

#定义掩模矩阵
mask = np.zeros((gray_src.shape), np.uint8)  # 定义一个竖直和水平像素与初始图像等大的全0矩阵
mask[280:350, :] = 155  # 水平区域
mask[:,150:350] = 100  # 竖直区域

然后执行按位异或计算:

#按位异或运算
img=cv.bitwise_xor(src,image) #异或运算
img2=cv.bitwise_xor(src,image,mask=mask) #异或运算

之后读取特定点BGR值进行按位异或计算验证:

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

a=np.zeros((1,3),np.uint8) #定义矩阵
a=dst[300,180] #将像素点BGR直接赋值给矩阵
b=np.zeros((1,3),np.uint8) #定义矩阵
b=image[300,180] #将像素点BGR直接赋值给矩阵
c=np.zeros((1,3),np.uint8) #定义矩阵
d=np.zeros((1,3),np.uint8) #定义矩阵
d=image[300,180] #将像素点BGR直接赋值给矩阵
e=np.zeros((1,3),np.uint8) #定义矩阵

#二进制按位异或计算
for i in range(3): #计数
    print('a','[0,',i,']=',a[i],'的二进制转化值=', bin(a[i]), ',b=','[0,',i,']=', b[i],'的二进制转化值=',bin(b[i])) #输出二进制转化值
    c[0,i]=np.bitwise_xor(a[i],b[i]) #赋值按位异或计算值
    print('c',[0,i],'是a[0,',i,']和b[0',i,']按位异或的值=',c[0,i]) #输出按位异或计算值
    print('c','[0,',i,']=',[0,i],'的二进制转化值=', bin(c[0,i]), ',d=','[0,',i,']=', d[i],'的二进制转化值=',bin(d[i])) #输出二进制转化值
    e[0,i]=np.bitwise_xor(c[0,i],d[i]) #赋值按位与计算值
    print('e',[0,i],'是c[0,',i,']和d[0',i,']按位异或的值=',e[0,i]) #输出按位异或计算值

#输出矩阵结果
print('a=',a) #输出矩阵
print('b=',b) #输出矩阵
print('c=',c) #输出矩阵
print('d=',d) #输出矩阵
print('e=',e) #输出矩阵

然后显示和保存图像:

#合并图像
himg=np.hstack((src,img))
himg2=np.hstack((src,img2))
himg3=np.hstack((img,img2))

# 显示和保存定义的图像
cv.imshow('dst', dst)  # 显示图像
cv.imshow('xor-n-mask', img)  # 显示图像
cv.imwrite('xornmask.png', img)  # 保存图像
cv.imshow('xor-w-mask', img2)  # 显示图像
cv.imwrite('xor-w-mask.png', img2)  # 保存图像
cv.imshow('xor-image', image)  # 显示图像
cv.imwrite('xor-image.png', image)  # 保存图像
cv.imshow('xor-mask', mask)  # 显示图像
cv.imwrite('xor-mask.png', mask)  # 保存图像
cv.imshow('ini-xor-n-mask', himg)  # 显示图像
cv.imwrite('ini-xor-n-mask.png', himg)  # 保存图像
cv.imshow('ini-xor-w-mask', himg2)  # 显示图像
cv.imwrite('ini-xor-w-mask.png', himg2)  # 保存图像
cv.imshow('xor-n-w', himg3)  # 显示图像
cv.imwrite('xor-n-w.png', himg3)  # 保存图像
cv.waitKey()  # 图像不关闭
cv.destroyAllWindows()  # 释放所有窗口

代码运行使用的图像有:

图2  初始图像srcx.png

图3 生成的带掩模的第二张图像xor-image.png

图4  掩模矩阵对应图像or-mask.png

图5 图像按位异或效果-不带掩模矩阵xor-n-mask.png

图6 初始图像和图像按位异或效果-不带掩模矩阵ini-xor-n-mask.png

图7 图像按位异或效果-带掩模矩阵xor-w-mask.png

图8 初始图像和图像按位异或效果-带掩模矩阵ini-xor-w-mask.png

图9 图像按位异或效果-不带和带掩模矩阵xor-n-w-mask.png

由图2至图9可知,对图像按位异或操作后,图像的颜色发生了明显变化,添加掩模矩阵后,只在掩模矩阵显示出图像异或操作的图像效果。

然后读取了特定像素点的BGR值:

图10 特定像素点BGR值异或运算验证

图10中,对第一个图像dst和第二个图像image在特定像素点[300,180]读取了BGR值(矩阵a和b),并调用np.bitwise_xor()函数对这两个值进行了按位异或运算(矩阵c)。

之后,又设置了反异或运算,此时的按位异或图像为:上一步获得的按位异或矩阵和第二个图像image。这两个图像(矩阵c和d)在特定像素点[300,180]的BGR值执行了按位异或操作。

图11 反异或运算代码设置

图10中矩阵形式的BGR值读取效果表明,反按位异或操作执行后,获得的矩阵值(矩阵e)和第一个图像的特定像素点取值相等。

综上所述,基于所有运算结果:使用cv2.bitwise_xor()函数执行图像按位异或计算时,各个像素点的BGR值都是按照十进制转二进制、二进制按位异或计算,然后再转回十进制的顺序进行。

图12  cv2.bitwise_xor()函数实现图像带掩模矩阵按位异或计算

【4】细节说明

由于掩模矩阵是单通道二维矩阵,所以掩模本身只会在黑白色之间变化。

【5】总结

掌握了python+opencv实现使用cv2.bitwise_xor()函数实现图像带掩模矩阵按位异或计算的技巧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2286676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关联传播和 Python 和 Scikit-learn 实现

文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数:集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…

【etcd】二进制安装etcd

由于生产服务器不能使用yum 安装 etcd ,或者 安装的etcd 版本比较老,这里介绍一个使用二进制安装的方式。 根据安装文档编写一个下载脚本即可 : 指定 etcd 的版本 提供了两个下载地址 一个 Google 一个 Github, 不过都需要外网 注释掉删除保…

企业知识管理平台助力企业创新与竞争力提升的有效策略探讨

内容概要 在当今快速发展的商业环境中,企业知识管理平台的构建显得至关重要。它不仅为企业的知识资源提供了一个整合与分享的空间,还为企业的创新与竞争力提升提供了策略支持。本文将深入探讨企业知识管理平台的关键要素,包括知识获取、存储…

Java多线程——线程安全性

线程安全性 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的 public class A {public void test(){//....} }无状态对象是线程安全的,其不包含任何域,也不包含任何对其他类中域的引用&#…

Windows安装Miniconda和PySide6以及配置PyCharm

目录 1. 选择Miniconda 2. 下载Miniconda 3. 安装Miniconda 4. 在base环境下创建pyside6环境 5. 安装pyside6环境 6. 配置PyCharm环境 7. 运行第一个程序效果 1. 选择Miniconda 选择Miniconda而没有选择Anaconda,是因为它是一个更小的Anaconda发行版&#x…

C++传送锚点的内存寻址:内存管理

文章目录 1.C/C内存分布回顾2.C内存管理2.1 内存申请2.2 operator new与operator delete函数2.3 定位new表达式 3.关于内存管理的常见知识点3.1 malloc/free和new/delete的区别3.2 内存泄漏 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 继C语…

循序渐进kubernetes-RBAC(Role-Based Access Control)

文章目录 概要Kubernetes API了解 Kubernetes 中的 RBACRoles and Role Bindings:ClusterRoles and ClusterRoleBindings检查访问权限:外部用户结论 概要 Kubernetes 是容器化应用的强大引擎,但仅仅关注部署和扩展远远不够,集群的安全同样至…

《从因果关系的角度学习失真不变表示以用于图像恢复》学习笔记

paper:2303.06859 GitHub:lixinustc/Causal-IR-DIL: Distortion invariant feature learning for image restoration from a causality perspective 2023 CVPR 目录 摘要 1、介绍 1.1 图像修复任务 1.2 失真不变表示学习 1.3 因果效应估计的挑战…

亚博microros小车-原生ubuntu支持系列:16 机器人状态估计

本来想测试下gmapping建图,但是底层依赖了yahboomcar_bringup做底层的数据处理,所以先把依赖的工程导入。 程序启动后,会订阅imu和odom数据,过滤掉一部分的imu数据后,然后与odom数据进行融合,最后输出一个…

Greenplum临时表未清除导致库龄过高处理

1.问题 Greenplum集群segment后台日志报错 2.回收库龄 master上执行 vacuumdb -F -d cxy vacuumdb -F -d template1 vacuumdb -F -d rptdb 3.回收完成后检查 仍然发现segment还是有库龄报警警告信息发出 4.检查 4.1 在master上检查库年龄 SELECT datname, datfrozen…

【Unity3D】实现横版2D游戏角色二段跳、蹬墙跳、扶墙下滑

目录 一、二段跳、蹬墙跳 二、扶墙下滑 一、二段跳、蹬墙跳 GitHub - prime31/CharacterController2D 下载工程后直接打开demo场景:DemoScene(Unity 2019.4.0f1项目环境) Player物体上的CharacterController2D,Mask添加Wall层…

mybatis(134/134)完结

一级缓存(默认情况下开启)同一个sqlsession中执行相同的查询语句走一级缓存 二级缓存 :同一个sqlsessionfactory,sqlsession关闭了才会将一级缓存提交到二级缓存中 外部编写的缓存 PageHelper插件:方便进行分页&#x…

PaddleSeg 从配置文件和模型 URL 自动化运行预测任务

git clone https://github.com/PaddlePaddle/PaddleSeg.git# 在ipynb里面运行 cd PaddleSegimport sys sys.path.append(/home/aistudio/work/PaddleSeg)import os# 配置文件夹路径 folder_path "/home/aistudio/work/PaddleSeg/configs"# 遍历文件夹,寻…

BLE透传方案,IoT短距无线通信的“中坚力量”

在物联网(IoT)短距无线通信生态系统中,低功耗蓝牙(BLE)数据透传是一种无需任何网络或基础设施即可完成双向通信的技术。其主要通过简单操作串口的方式进行无线数据传输,最高能满足2Mbps的数据传输速率&…

苍穹外卖—订单模块

该模块分为地址表的增删改查、用户下单、订单支付三个部分。 第一部分地址表的增删改查无非就是对于单表的增删改查,较基础,因此直接导入代码。 地址表 一个用户可以有多个地址,同时有一个地址为默认地址。用户还可为地址添加例如&q…

openeuler 22.03 lts sp4 使用 cri-o 和 静态 pod 的方式部署 k8s-v1.32.0 高可用集群

前情提要 整篇文章会非常的长…可以选择性阅读,另外,这篇文章是自己学习使用的,用于生产,还请三思和斟酌 静态 pod 的部署方式和二进制部署的方式是差不多的,区别在于 master 组件的管理方式是 kubectl 还是 systemctl有 kubeadm 工具,为什么还要用静态 pod 的方式部署?…

MySQL分表自动化创建的实现方案(存储过程、事件调度器)

《MySQL 新年度自动分表创建项目方案》 一、项目目的 在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低。分表是一种有效的优化策略,它将数据分散存储在多…

接口技术-第6次作业

目录 作业内容 解答 1.假设在一个系统中,8255A的端口地址为184H-187H,A口工作于方式1输出,B口工作于方式1输入,禁止中断,C口剩余的两根线PC5,PC4位输入,如下图所示,试编写初始化…

(1)Linux高级命令简介

Linux高级命令简介 在安装好linux环境以后第一件事情就是去学习一些linux的基本指令,我在这里用的是CentOS7作演示。 首先在VirtualBox上装好Linux以后,启动我们的linux,输入账号密码以后学习第一个指令 简介 Linux高级命令简介ip addrtou…

网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索

摘要:随着互联网技术的飞速发展,网络直播作为一种新兴的、极具影响力的媒体形式,正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示,网络直播用户规模已达到3.25亿,占网民总数的45.8…