【问题标题】:What's 0xFF for in cv2.waitKey(1)?cv2.waitKey(1) 中的 0xFF 是什么?
【发布时间】:2016-05-24 04:46:18
【问题描述】:

我试图了解 0xFF 在以下代码 sn-p 中的作用:

if cv2.waitKey(0) & 0xFF == ord('q'):
    break

有什么想法吗?

【问题讨论】:

  • 你在问它是什么吗?例如。价值255?或者您是在问为什么将其与 ord('q') 进行比较?
  • 也许 OP 会问为什么有必要使用面具...
  • 看看这里...高字节可能包含修饰键stackoverflow.com/a/33555071/2836621
  • 对不起,让我改写一下。 OpenCV中有这个waitkey,它基本上等待一个键并做一些事情。 Waitkey 'q' 基本上会关闭相机窗口。在这种情况下,我不明白 0xFF 的目的。我知道它是一个十六进制,但我们为什么需要它?

标签: python opencv hex


【解决方案1】:

同样重要的是要注意,如果您激活了 NumLock,ord('q') 可以返回不同的数字(也许其他键也会发生这种情况)。 比如按c的时候,代码:

key = cv2.waitKey(10) 
print(key) 

返回

 1048675 when NumLock is activated 
 99 otherwise

将这两个数字转换为二进制我们可以看到:

1048675 = 100000000000001100011
99 = 1100011

我们可以看到,最后一个字节是相同的。然后有必要只取最后一个字节,因为其余的字节是由于 NumLock 的状态引起的。因此,我们执行:

key = cv2.waitKey(33) & 0b11111111  
# 0b11111111 is equivalent to 0xFF

键的值将保持不变,现在我们可以将它与我们想要的任何键进行比较,例如您的问题

if key == ord('q'):

【讨论】:

    【解决方案2】:

    cv2.waitKey() 返回一个 32 位整数值(可能取决于平台)。键输入是 ASCII 码,它是一个 8 位整数值。因此,您只关心这 8 位,并希望所有其他位为 0。您可以通过以下方式实现:

    cv2.waitKey(0) & 0xFF
    

    【讨论】:

    • 这是最好的答案
    【解决方案3】:

    0xFF 是一个十六进制常量,在二进制中是11111111。通过对这个常数使用按位与 (&),它只留下原始的最后 8 位(在这种情况下,无论 cv2.waitKey(0) 是什么)。

    【讨论】:

    • 那不是二进制的 10000000,所以 2 到 8 (=256)?另外我不确定你的意思。我有 waitkey 通过获取密钥输入来执行特定事件。你得到一个键输入,将它转换成 ASCII 并用它做一些事情。似乎总是在 opencv 中使用 waitkey 时你会使用 0xFF,我不明白。
    • @Dora 我来晚了一点,但 0xFF 是 255。F == 15(就像我们有 10 个数字,但 9 是最高的),所以 15*16 + 15 == 255. 0xF == 0b1111 (15) 和 0xFF == 0b1111111
    【解决方案4】:

    在这段代码中,

    if cv2.waitKey(0) & 0xFF == ord('q'):
        break
    

    当没有任何输入时,waitKey(0) 函数返回 -1。一旦事件发生,即按下按钮它返回一个32位整数

    在这种情况下,0xFF 表示二进制 11111111 一个 8 位 二进制,因为我们只需要 8 位来表示我们将 waitKey(0) 与 @ 相加的字符987654325@。结果得到255以下的整数。

    ord(char) 返回字符的 ASCII 值,最大值为 255。

    因此,通过将整数与ord(char) 值进行比较,我们可以检查按键事件并中断循环。

    【讨论】:

      【解决方案5】:

      **阅读这将节省您的时间**

      注 1: cv2.waitKey() 将返回您按下的关键字 如果你只是点击关闭按钮 当窗口打开时,它将返回-1

      注意 2: 让我们假设您按下了“q” 然后 cv2.waitkey() 将返回那个 'q' 但它返回的格式将是 为了改变字符串数据类型 它是我们正在执行的二进制文件 在 & 符号和 0xFF 的帮助下进行位与运算。 0xFF 是十六进制格式也知道 作为十六进制常数 十进制格式为 255,二进制格式为 11111111。

      
          Decimal=255
          Binary=11111111
          Hexadecimal=0xff
      
      
      **Note it is the same value in different formats **
      

      注 3: 我们都知道python中的'&'是用来 执行按位“与”运算, 按位在我们执行的意义上 二进制级别的 And 操作 AND运算逻辑: **

              0&0=0
              0&1=0
              1&0=0
              1&1=1
      

      **

      下面是字母'q'的asci值和二进制值小表

      **Letter    ASCII Code  Binary  **
        q           113      01110001    
      

      注 4:因为我们已经给出了 十六进制常数 0xFF 其二进制值为 11111111 让我们执行位与操作 字母“q”的二进制值 是 01110001。

              q= 01110001
            0xFF=11111111
                ----------
                 01110001   ----->q so when do bitwise and operation we get the same value of q
                ----------
      

      注 5:

      因为我们正在执行按位与运算 0xFF 是一个十六进制常数, 一旦按位运算完成或 执行,结果将变为十进制格式, 因此,由于我们使用的是 ord('q') 函数,它将 返回 '​​q' 的十进制值或 ASCII 值 所以两者都等于条件 如果条件为真,循环将中断

      【讨论】:

        【解决方案6】:

        说实话,在这种情况下,您不需要 0xFF。如果你做了cv2.waitkey(0) == ord(q),它会完全一样。 0xFF 仅用于屏蔽序列的最后一个8bits,任何键盘字符的 ord() 都不会大于 255。您可以参考此ASCII Table 来查找任何键盘字符的数值。

        【讨论】:

          【解决方案7】:

          ord(c) 当参数是 unicode 对象时返回一个整数,表示字符 (c) 的 Unicode 代码点,或者当参数是 8 位字符串时返回字节的值。

          在 64 位系统的情况下,cv2.waitKey(0) 的值与 0xFF 十六进制常数(表示二进制字符串 11111111) 的最后 8 位。因此用 ord(c) 来检查相等性。

          【讨论】:

            【解决方案8】:

            waitKeyhas changed in v3.2 (December 2016) 的行为。

            当前行为是这样的:

            • waitKey 返回 -1 或键码的最低 8 位
            • waitKeyEx 返回 -1full 键码,其中可以包含特殊键的附加标志(例如箭头键、修饰符等)

            不需要 & 0xFFwaitKey 的东西。 随便用

            if cv2.waitKey(...) == ord('q'):
                ...
            

            这会检查是否按下了键 qord() 将字符串/字符 q 转换为其 ASCII 整数代码。这是必需的,因为waitKey 返回一个整数。

            历史行为是只有waitKey,没有waitKeyExwaitKey 返回了完整的密钥代码。

            如果键码包含额外的标志,它就不再是 ord('q')& 0xFF 是相当于掩码的按位运算。仅保留密钥代码的低八位,因此丢弃高位中的任何标志。如果您按下q 键,即使设置了任何标志,比较也会成功。

            【讨论】:

              【解决方案9】:

              cv2.waitKey() 如果没有按下任何键,则返回值 -1。当您按下一个键时,它会返回该键的 ASCII 值。所以如果你这样做了

               k = cv2.waitKey(0)
               if k == ord('b'):
                  break
              

              当按下b 键时,k 的值将是 98,它等于 ord('b') 的值,即 98,并且此条件为真会导致中断。 但是,根据平台或键盘修饰符,将返回一个 32 位整数值。在这种情况下,最好使用cv2.waitKey() & 0xFF,它在二元与运算中会得到按下的键的值,并且可以与ord('key')进行比较

              【讨论】:

              • 这种行为在 v3.2 之前就已经存在,今天已经没有相关性了。 waitKey 始终返回 -1 或 8 位值。 waitKeyEx 返回完整代码。
              【解决方案10】:

              cv2.waitKey() 是将您的代码与键盘绑定的函数,您键入的任何内容都将由该函数返回。 然后 waitKey 的输出与 0xFF 进行逻辑与,以便可以访问最后 8 位。 因此最后 8 位表示来自键盘的输入,并使用 == 与您想要的字符进行比较。

              【讨论】:

                【解决方案11】:

                这就像你等了 0 毫秒然后按键盘上的“Q”然后循环就会中断。

                # If we've waited at least 1 ms And we've pressed the Esc
                while True:
                   if cv2.waitKey(1) & 0xFF == 27:
                      break
                cv2.destroyAllWindows()
                

                【讨论】:

                  【解决方案12】:
                  1. cv2.waitKey(0) -- 0 表示您的输出将在屏幕上停留 0 毫秒,即无限时间段
                  2. 0xFF == ord('q') -- 表示接受键盘输入。这里是'q'

                  在正常情况下,我说这是在用户按下键盘上的'q' 之前保持输出打开。

                  【讨论】:

                    猜你喜欢
                    • 2023-03-12
                    • 2018-11-13
                    • 2017-12-04
                    • 2018-12-10
                    • 2022-07-01
                    • 2016-06-12
                    • 2020-01-14
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多