if cv2.waitkey(10) & 0xFF = ord('s')
1. 首先了解下0xFF
顯然,這是個16進位制數,FF為1111 1111,寫完整的話就是0000 0000 0000 0000 0000 0000 1111 1111,一個32位的二進位制(因為0xFF儲存為int型別,而int為4byte,即32bit)
2. &0xFF
這個是對0xFF做了邏輯與的操作,即1&1->1,其他都是0。要知道,計算機儲存資料是按照補碼的形式儲存的(也有說負數才是按照補碼的形式儲存,但其實正數的原碼和補碼是一樣的,所以說二者均儲存補碼也沒什麼問題)
現在設想這樣一個場景:byte a = -127;,而-127對應的補碼是1000 0001(byte-8bit),將 byte 作為int型別向控制檯輸出的時候(printf("%d",a)),編譯器做了一個符號擴充的處理,因為int型別是32位二進位制數,所以byte擴充後的補碼就是1111111111111111111111111 10000001(32位),這個32位二進位制補碼錶示的十進位制數也是-127。這說明符號擴充並不會影響當前對應的十進位制數的值。但問題在於如果我們只是想要一個相同的補碼呢?即將byte轉換為int後,其結果仍然是0000...0000 1000 0001,那就需要用到&0xFF了,0xFF在高24位補零,從而做邏輯與操作後其結果為0000...0000 1000 0001,當然這個時候-127就不再是-127了,所以對於0xFF的運用要慎重考量。
一般而言,在if cv2.waitkey(10) & 0xFF這裡做的操作不是很有意義,因為這個我們鍵盤鍵入的按鍵值所對應的ascii碼都是正數
3.cv2.waitkey(10) & 0xFF
此時這句話的意義就比較清楚了,cv2.waitkey(10)會返回在這個圖片存在的10ms內根據按鍵值返回對應的ascii碼(也有說Unicode碼的,這個沒有驗證),然後和0xFF做邏輯與運算。由上文,這個運算在這裡沒有太大意義,其實指的是windows環境下無所謂,實際上在linux上使用waitkey有時會出現waitkey返回值超過了(0-255)的範圍的現象。通過cv2.waitKey(1) & 0xFF運算,當waitkey返回值正常時 cv2.waitKey(1) = cv2.waitKey(1000) & 0xFF,當返回值不正常時,cv2.waitKey(1000) & 0xFF的範圍仍不超過(0-255),就避免了一些奇奇怪怪的BUG。
Unicode和ascii:ASCII編碼是1個位元組,而Unicode編碼通常是2個位元組。.字母A用ASCII編碼是十進位制的65,二進位制的01000001;而在Unicode中,只需要在前面補0,即為:00000000 01000001。
4.cv2.waitkey(10) & 0xFF = ord('s')
ord('s')返回s對應的ascii碼,和左邊進行比較,就知道是不是按下了's'從而做出下一步反饋
5. 等價寫法
經驗證,在windows下以下寫法也是被接受的
# 正常寫法 if cv2.waitKey(10) & 0xFF == ord('s'): break # 等價寫法 cv2.waitKey(10)if cv2.waitKey() == ord('s'): break
6. 參考連結
(46條訊息) cv2.waitKey的入門級理解_山上有強強的部落格-CSDN部落格_cv2.waitkey