当前位置:   article > 正文

计算机视觉——OpenCV Python位运算与图像掩码

计算机视觉——OpenCV Python位运算与图像掩码

概述

位运算与图像掩码的结合允许对图像的特定区域进行精确的操作。通过使用位运算(如AND、OR、XOR和NOT),可以基于掩码的选择性地修改图像数据。位运算与图像掩码结合使用的一些关键点和应用场景:

  1. 选择性修改
    通过位运算AND,我们可以将图像的特定区域(由掩码定义)与其他图像或图形元素结合。例如,如果我们有一个对象的掩码,我们可以使用这个掩码来保留原始图像中的对象,同时将其他区域替换为另一张图像的内容。

  2. 区域保护
    位运算AND也可以用于保护图像的某些区域不受更改。例如,如果我们想要在图像的某个区域上添加效果,但不想影响其他区域,我们可以创建一个掩码,将效果应用于该区域,同时保持其他区域不变。

  3. 图像融合
    使用位运算OR,我们可以将两个图像的重叠区域合并,同时保留各自的独特区域。这对于图像融合和创建合成图像特别有用。

  4. 图像反转
    位运算NOT可以用来反转图像的颜色。通过将整个图像应用掩码(其中所有像素都是1),我们可以创建图像的负片。

  5. 对象提取
    通过结合使用掩码和位运算,我们可以从复杂背景中提取对象。例如,我们可以创建一个掩码来隔离感兴趣的对象,然后使用位运算AND将其从原始图像中分离出来。

  6. 图像修复
    在图像修复任务中,我们可以使用掩码来标识需要修复的区域。然后,可以使用位运算将修复区域与周围区域融合,以实现自然的过渡。

在实际应用中,图像掩码通常是由图像处理算法生成的,例如阈值化、边缘检测、颜色分割等。一旦有了掩码,就可以使用OpenCV等图像处理库提供的位运算函数来执行上述操作。

位运算AND

在 OpenCV 中,位运算AND是一种按位操作,它允许你逐像素地比较两个图像,并根据指定的掩码保留那些在两个图像中都为非零的像素。这种操作通常用于图像处理中,例如提取两个图像的交集或者根据掩码保留特定区域的像素。
为了应用位运算,首先创建两个黑色图像,一个带有垂直白色矩形,另一个带有水平白色矩形:

import cv2
import numpy as np

# 画一个垂直矩形

image1 = np.zeros((400, 600), dtype="uint8")

cv2.rectangle(image1, (50, 50), (250, 350), 255, -1)

# 画一个水平矩形

image2 = np.zeros((400, 600), dtype="uint8")

cv2.rectangle(image2, (50, 200), (550, 350), 255, -1)

cv2.imshow("image1", image1)

cv2.imshow("image2", image2)

cv2.waitKey(0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

要创建一个黑色图像,我们np.zeros函数。这个函数将创建一个充满零(黑色图像)的(400, 600)图像。在第一个黑色图像中,使用cv2.rectangle函数画了一个垂直白色矩形。这个白色矩形的宽度为250 - 50 = 200,高度为350 - 50 = 300。

在第二个黑色图像中,画了一个水平白色矩形,宽度为550 - 50 = 500,高度为350 - 200 = 150。

两个图像如下所示:
在这里插入图片描述

要应用位运算AND,可以使用cv2.bitwise_and函数:

bitwise_and = cv2.bitwise_and(image1, image2)
cv2.imshow("bitwise_and", bitwise_and)
cv2.waitKey(0)
  • 1
  • 2
  • 3

cv2.bitwise_and 函数确实是用于计算两个数组的逐元素位逻辑“与”(AND)运算。这个函数会将输入图像中的每个像素位置的像素值进行比较,并根据比较结果设置输出图像中相应位置的像素值。

在位运算中,逻辑“与”运算的规则如下:

  • 如果两个比较位都是1(非零),则结果位也是1。
  • 如果两个比较位中有任何一个是0,则结果位是0。

在图像处理的上下文中,这通常意味着:

  • 如果 image1image2 中相应位置的像素值都大于0(在8位图像中,像素值的范围是0到255),那么这两个像素都被认为是有效的,输出图像中对应位置的像素值将被设置为最大值,通常是255(代表白色)。
  • 如果 image1image2 中任一像素值为0(代表黑色或透明),或者两者都是0,那么输出图像中对应位置的像素值将被设置为0(代表黑色或完全不透明)。
a = np.array([255])  # 两个像素都大于0

b = np.array([255])  # 大于0

cv2.bitwise_and(a, b)  # 输出255
array([[255]], dtype=int32)

a = np.array([0])  # 两个像素中的一个等于0

b = np.array([255])

cv2.bitwise_and(a, b)  # 输出0
array([[0]], dtype=int32)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

位运算AND函数的下面图像所示,唯一留下的白色(255)区域是两个矩形重叠的区域,其他都是黑色(0):
在这里插入图片描述

位运算OR

cv2.bitwise_or 函数是 OpenCV 库中用于执行逐元素位逻辑“或”(OR)运算的函数。这个函数比较两个输入数组的对应元素,并根据比较结果计算输出数组的元素值。位运算 OR 的基本原则是:

  • 如果两个比较位中任何一个为1(非零),结果位为1。
  • 如果两个比较位都为0(零),结果位也为0。

在图像处理的上下文中,cv2.bitwise_or 函数的行为如下:

  • 如果 image1image2 中任一位置的像素值大于0(在8位图像中,像素值的范围是0到255),那么输出图像中对应位置的像素值将被设置为最大值(通常是255,代表白色)。
  • 如果 image1image2 中所有位置的像素值都为0(代表黑色),那么输出图像中对应位置的像素值也将是0(黑色)。

这种操作在图像处理中可以用于多种目的,例如:

  • 合并两个图像中的所有非黑像素。
  • 提取两个图像共有的区域和独有的区域。
  • 实现某些特殊的图像融合效果。

下面是一个使用 cv2.bitwise_or 函数的简单示例:

import cv2
import numpy as np

# 读取或创建两个图像
image1 = cv2.imread('image1.png', cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread('image2.png', cv2.IMREAD_GRAYSCALE)

# 确保两个图像大小相同
# 如果需要,可以使用 cv2.resize() 函数调整图像大小

# 应用位运算OR
result = cv2.bitwise_or(image1, image2)

# 显示结果
cv2.imshow('Result of Bitwise OR', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个示例中,image1image2 是两个单通道灰度图像。cv2.bitwise_or 函数将这两个图像进行逐元素的 OR 运算,并将结果存储在 result 中。
在这里插入图片描述

位运算XOR

cv2.bitwise_xor 函数是 OpenCV 库中用于执行逐元素位逻辑“异或”(XOR)运算的函数。这个操作比较两个输入数组的对应元素,并根据比较结果计算输出数组的元素值。位运算 XOR 的基本原则是:

  • 如果两个比较位中的一个为1而另一个为0,结果位为1。
  • 如果两个比较位相同(都为1或都为0),结果位为0。

在图像处理的上下文中,cv2.bitwise_xor 函数的行为如下:

  • 如果 image1image2 中相应位置的像素值中只有一个大于0(例如一个为白色而另一个为黑色),那么输出图像中对应位置的像素值将被设置为最大值(通常是255,代表白色)。
  • 如果 image1image2 中相应位置的像素值都是0(黑色)或者都是非零值(白色),那么输出图像中对应位置的像素值将被设置为0(黑色)。

这种操作在图像处理中可以用于多种目的,例如:

  • 比较两个图像的差异。
  • 从两个图像中提取相互独立的区域。
  • 实现某些特殊的图像融合效果。

下面是一个使用 cv2.bitwise_xor 函数的简单示例:

import cv2
import numpy as np

# 读取或创建两个图像
image1 = cv2.imread('image1.png', cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread('image2.png', cv2.IMREAD_GRAYSCALE)

# 确保两个图像大小相同
# 如果需要,可以使用 cv2.resize() 函数调整图像大小

# 应用位运算XOR
result = cv2.bitwise_xor(image1, image2)

# 显示结果
cv2.imshow('Result of Bitwise XOR', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个示例中,image1image2 是两个单通道灰度图像。cv2.bitwise_xor 函数将这两个图像进行逐元素的 XOR 运算,并将结果存储在 result 中。然后,我们使用 cv2.imshow 函数显示结果图像。

两个矩形重叠的区域被移除(黑色),因为在这个区域中两个像素都大于0:
在这里插入图片描述

位运算NOT

cv2.bitwise_not 函数是 OpenCV 库中用于执行逐元素位逻辑“非”(NOT)运算的函数。这个操作通常被称为位求反或位翻转,它将输入数组中的每个像素的位进行翻转:将0变为1,将1变为0。在图像处理中,这个操作可以用来反转图像的颜色,即把白色变成黑色,把黑色变成白色。

位运算 NOT 的基本原则是:

  • 如果输入位是0(零),则结果位是1(一)。
  • 如果输入位是1(一),则结果位是0(零)。

在图像处理的上下文中,cv2.bitwise_not 函数的行为如下:

  • 如果输入图像中的像素值为0(黑色),那么输出图像中对应位置的像素值将被设置为最大值(通常是255,代表白色)。
  • 如果输入图像中的像素值大于0(白色或其他颜色),那么输出图像中对应位置的像素值将被设置为0(黑色)。

这种操作在图像处理中可以用于创建图像的负片效果,或者在某些特殊情况下作为图像预处理步骤。

下面是一个使用 cv2.bitwise_not 函数的简单示例:

import cv2
import numpy as np

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fd7499108e1f4a8595ada89dade36c95.png)


# 显示结果
cv2.imshow('Result of Bitwise NOT', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个示例中,image 是一个单通道灰度图像。cv2.bitwise_not 函数将这个图像进行逐元素的 NOT 运算,这个操作将反转图像中的所有像素值,创建一个负片效果:
在这里插入图片描述

图像掩码

图像掩码是一种用于控制图像中哪些部分应该被处理或忽略的技术。掩码通常是一个与原始图像大小相同的二值图像,其中像素值通常是0或255(或其他与图像深度相对应的最大值)。掩码可以用于多种目的,包括但不限于图像编辑、特征提取、对象选择和图像融合。

掩码的一些主要用途:

  1. 区域选择
    掩码可以用来选择图像中的特定区域。例如,如果你只对图像中的某个对象感兴趣,你可以创建一个掩码,其中该对象是白色(255)的,其余部分是黑色(0)的。然后,你可以使用这个掩码与原始图像进行位运算,如AND运算,以仅保留你感兴趣的对象。

  2. 图像编辑
    掩码可以用于图像编辑中,例如在原始图像上添加文本或图形元素。你可以创建一个包含所需编辑的掩码,然后将其与原始图像合并。

  3. 图像融合
    在图像融合中,掩码可以用来决定不同图像之间的哪些部分应该可见。例如,你可以使用掩码将两个图像的重叠区域混合在一起,而保留其他区域的原始外观。

  4. 对象检测和分割
    掩码可以用于对象检测和分割任务中,通过识别和隔离感兴趣的对象或特征。这通常涉及到图像分割算法,它们可以根据像素值或颜色信息创建掩码。

  5. 图像预处理
    在某些图像预处理步骤中,掩码可以用来忽略不相关的图像部分,例如背景,而只关注前景中的特定元素。

moon = cv2.imread("moon.jpg")

# 创建一个与我们的图像相同大小的黑色图像,然后创建一个白色圆形

mask = np.zeros(moon.shape[:2], dtype="uint8")

cv2.circle(mask, (202, 133), 34, 255, -1)

# 将掩蔽应用到图像
masked = cv2.bitwise_and(moon, moon, mask=mask)

cv2.imshow("moon", moon)

cv2.imshow("mask", mask)

cv2.imshow("Mask applied to image", masked)

cv2.waitKey(0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

首先从磁盘加载我们的图像。然后,创建一个与原始图像相同大小的黑色图像。接下来,在掩蔽图像上创建一个白色圆形。白色圆形完全对应于原始图像中的月亮区域。这步可以用HSV颜色识别来获取月亮的区域。

该函数接受一个可选的第三个参数,即掩蔽。如果提供了掩蔽,函数将输出原始图像中的像素,如果掩蔽中的对应像素非零,则输出0:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/452495
推荐阅读
相关标签
  

闽ICP备14008679号