什么是 | Python Opencv 函数中使用的(管道)符号(cv2.threshold)

What is | (Pipe) symbol used for in Python Opencv functions ( cv2.threshold)

我知道这是按位或但我想知道它在给定函数中做了什么以及它如何用于函数调用

我在 opencv 函数中看到了一些使用 | 的代码,例如

t, im = cv2.threshold(blurred, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)

这个|是什么意思?是什么意思以及如何在随机函数 foo(x|y) 中使用此 |

它是或位运算符。如果两个位中的一个或两个为 1,则将每个位设置为 1。

让我们定义一个函数

def print_if_1(number):
    if number == 1:
        print(1)
    else:
        print(0)

和两个变量ab

a=1
b=0

现在让我们先验证一下:

print(a)

1

print(b)

0

下面是我们如何在此函数中使用管道:

print(a|b)

1

您可以像往常一样创建一个函数来使用这些值。但请注意,通常定义被“或”运算的常量,以便当两个或多个值被“或”运算在一起时,每个常量只设置一位。

在使用这些值的函数中,您通常会测试机器人的 eahc,这最简单的方法是与值进行 AND 运算,如下例中的 myfn()

正如其他人在 asnwers 中所说,这种按位或运算 is/was 的风格在 C/C++ 代码实现中很常见,例如opencv python 是底层 opencv C++ 实现的包装器。就个人而言,如果我正在设计 Python API 我会为每个标志使用单独的命名参数,即避免 OR-ing。

例如:

import cv2

def showvalue(v):
    print( f"{v=} {bin(v)=} {hex(v)=}" )

showvalue( cv2.THRESH_OTSU )
showvalue( cv2.THRESH_BINARY_INV )
showvalue( cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU )

abit = 0b0010
bbit = 0b0100

def myfn( v ):
    print( "+++++++" )
    print( f"{v=}" )
    if v & abit:
        print( f"abit is set" )
    if v & bbit:
        print( f"bbit is set" )
    print( "-------" )

myfn(abit)
myfn(bbit)
myfn(abit| bbit)

输出:

v=8 bin(v)='0b1000' hex(v)='0x8'
v=1 bin(v)='0b1' hex(v)='0x1'
v=9 bin(v)='0b1001' hex(v)='0x9'
+++++++
v=2
abit is set
-------
+++++++
v=4
bbit is set
-------
+++++++
v=6
abit is set
bbit is set
-------

编码人员将一堆选项塞入单个变量是很常见的。如果以二进制形式查看分配给各种 ThresholdTypes 的常量,则更容易理解一些

import cv2

print('THRESH_BINARY:     ', format(cv2.THRESH_BINARY, '#08b'))
print('THRESH_BINARY_INV: ', format(cv2.THRESH_BINARY_INV, '#08b'))
print('THRESH_TRUNC:      ', format(cv2.THRESH_TRUNC, '#08b'))
print('THRESH_TOZERO:     ', format(cv2.THRESH_TOZERO, '#08b'))
print('THRESH_TOZERO_INV: ', format(cv2.THRESH_TOZERO_INV, '#08b'))
print('THRESH_MASK:       ', format(cv2.THRESH_MASK, '#08b'))
print('THRESH_OTSU:       ', format(cv2.THRESH_OTSU, '#08b'))
print('THRESH_TRIANGLE:   ', format(cv2.THRESH_TRIANGLE, '#08b'))

给出:

THRESH_BINARY:      0b000000
THRESH_BINARY_INV:  0b000001
THRESH_TRUNC:       0b000010
THRESH_TOZERO:      0b000011
THRESH_TOZERO_INV:  0b000100
THRESH_MASK:        0b000111
THRESH_OTSU:        0b001000
THRESH_TRIANGLE:    0b010000

竖线 (|) 是按位或,如果一个或两个输入位为 1,则将输出位设置为 1,否则为 0。在您的示例中,选项 THRESH_BINARY_INVTHRESH_OTSU都可以用按位或来选择。在这种情况下,第 1 位和第 4 位被设置,0b001001 被发送到函数。

如果你尝试使用它会变得有点奇怪

cv2.THRESH_BINARY | cv2.THRESH_BINARY_INV

在这种情况下,第一位被设置 (0b00000001),您将得到一个倒置的阈值。在这种情况下,cv2.THRESH_BINARY 被有效地忽略了。

Qt 库中有一个不那么令人困惑的例子,InputMethodHints 的可能值都是按位排他的:

from PyQt5.QtCore import Qt

print('Qt.ImhHiddenText:       ', format(Qt.ImhHiddenText, '#011b'))
print('Qt.ImhSensitiveData:    ', format(Qt.ImhSensitiveData, '#011b'))
print('Qt.ImhNoAutoUppercase:  ', format(Qt.ImhNoAutoUppercase, '#011b'))
print('Qt.ImhPreferNumbers:    ', format(Qt.ImhPreferNumbers, '#011b'))
print('Qt.ImhPreferUppercase:  ', format(Qt.ImhPreferUppercase, '#011b'))
print('Qt.ImhPreferLowercase:  ', format(Qt.ImhPreferLowercase, '#011b'))
print('Qt.ImhNoPredictiveText: ', format(Qt.ImhNoPredictiveText, '#011b'))
print('Qt.ImhDate:             ', format(Qt.ImhDate, '#011b'))
print('Qt.ImhTime:             ', format(Qt.ImhTime, '#011b'))

Qt.ImhHiddenText:        0b000000001
Qt.ImhSensitiveData:     0b000000010
Qt.ImhNoAutoUppercase:   0b000000100
Qt.ImhPreferNumbers:     0b000001000
Qt.ImhPreferUppercase:   0b000010000
Qt.ImhPreferLowercase:   0b000100000
Qt.ImhNoPredictiveText:  0b001000000
Qt.ImhDate:              0b010000000
Qt.ImhTime:              0b100000000

您可以按位 2 个或更多选项或所有选项而不会发生冲突。