😶?🌫?😶?🌫?😶?🌫?😶?🌫?Take your time ! 😶?🌫?😶?🌫?😶?🌫?😶?🌫?
💥個人主頁:🔥🔥🔥大魔王🔥🔥🔥
💥所屬專欄:🔥魔王的修煉之路–Computer vision🔥
如果你覺得這篇文章對你有幫助,請在文章結尾處留下你的點贊👍和關注💖,支持一下博主。同時記得收藏?這篇文章,方便以后重新閱讀。
文章目錄
- 顯示圖片(waitKey(),GUI 事件)
- 保存圖片
- 顯示攝像頭并保存
- 控制鼠標
- Trackbar(控件:滑動條)
顯示圖片(waitKey(),GUI 事件)
import cv2img = cv2.imread('D:/Zachary/6_OpenCV/images/1.png')cv2.namedWindow("new", cv2.WINDOW_NORMAL) cv2.resizeWindow("new", 480, 360) cv2.imshow('new', img)key = cv2.waitKey(0) # 單位毫秒,0 時不會跳過等待輸入,在顯示窗口時一般都要使用該函數。 # 這不用 key 接收,因為不作比較,想一直顯示圖片的話直接堵塞就行,參數為 0。cv2.destroyAllWindows()
imshow 第二個參數是圖片對象,不能是圖片路徑。
記得最后釋放窗口資源。
cv2.waitKey(time),單位是毫秒,0 時不會跳過,等待輸入,所以圖片窗口才不會閃關。當為其他時間時,表示該函數等待的毫秒數。
cv2.waitKey(time) 返回的數據類型:返回按下鍵的 ASCII 值,int 類型。
waitKey():是 OpenCV 處理 GUI 事件的唯一入口。
GUI 事件:在圖形界面上的操作動作(比如點擊、拖動、輸入等),程序會 ”監聽“ 這些動作并 ”響應“ 他們。
GUI 事件處理流程:
- 用戶操作(點擊、輸入、拖動…)
- 操作觸發事件
- 程序注冊的回調函數被調用
- 程序根據事件做出響應
OpenCV 中的幾個 GUI 事件相關函數:
函數名 作用 cv2.waitKey()
等待鍵盤輸入,返回按鍵的編碼 cv2.setMouseCallback()
注冊鼠標事件回調 cv2.createTrackbar()
添加滑動條控件并監聽滑動變化 cv2.namedWindow()
+cv2.imshow()
創建可響應事件的窗口
保存圖片
import cv2cv2.namedWindow("win", cv2.WINDOW_NORMAL) cv2.resizeWindow("win", 480, 360) img = cv2.imread("../images/1.png") cv2.imshow("win", img)key = 0 while key != ord('q'):key & 0xff = cv2.waitKey(0) # 單位毫秒,0 時不會跳過等待輸入,在顯示窗口時一般都要使用該函數。單位毫秒。 key & 0xff,處理高字節問題。if key == ord('d'):cv2.imwrite("../images/2.png", img)print("保存完成")breakelse:print(key)cv2.destroyAllWindows()
- key 作比較時,最好 & 0xff ,處理高字節問題。
- ord 函數:返回字符對應的 ASCII 值。
- ord -> ordinal,序號的意思,因為 ASCII 是給字符排序號作為 ASCII 值。
- 所以要通過 ord 轉換才能進行比較,因為 python 沒有字符,底層不會將單個字符看成對應的 ASCII(int 類型),就算是單個字符 python 也會看作字符串,所以沒有對應的數值。
顯示攝像頭并保存
# 查看電腦攝像頭分辨率# import cv2# cap = cv2.VideoCapture(0)# # 確保攝像頭已打開 # if not cap.isOpened(): # print("無法打開攝像頭") # exit() # width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # fps = cap.get(cv2.CAP_PROP_FPS) # 獲取攝像頭幀率 # if fps <= 0: fps = 30.0 # 默認30FPS# print(f"攝像頭分辨率: {width}x{height}, 幀率: {fps}")# 引入模塊 import cv2# 創建VedioWriter,為了寫多媒體文件 fourcc = cv2.VideoWriter_fourcc(*'MJPG') # 寫入的多媒體文件的格式 vw = cv2.VideoWriter('../test/out.mp4', fourcc, 25, (640,480)) # 與攝像頭分辨率不一樣,讀取出來的無法播放# 創建窗口 cv2.namedWindow("win", cv2.WINDOW_NORMAL)# 調整窗口大小 cv2.resizeWindow("win", 640, 480)# 獲取視頻設備,創建連接,初始化資源后(攝像頭與硬件之間)返回一個對象給cap,cap是一個持久性對象,創立連接后維持與攝像頭的連接。 cap = cv2.VideoCapture(0)while cap.isOpened():# 檢查攝像頭實時更新的數據,看它是否還打開# 接收其返回的參數,第一為讀取成功 True,失敗 False,第二個為讀取到的幀ret, frame = cap.read()# 每次都讀的這個cap,不過cap這個對象內部狀態會隨著每次讀取而更新。# 展示幀是否讀取正確if ret == True:# 展示窗口,在同一個窗口展示不同的幀,就會形成視頻cv2.imshow("win", frame)# 重新將窗口設置為指定大小cv2.resizeWindow("win", 640, 480) # 這點有點不理解# 將幀寫入多媒體文件vw.write(frame)elif ret == False:breakkey = cv2.waitKey(1)if key & 0xff == ord('q'):break# 釋放 VideoCapture cap.release()# 釋放 VideoWriter vw.release()# 釋放窗口 cv2.destroyAllWindows()
- 沒什么說的,注釋的很詳細。
控制鼠標
import cv2 import numpy as np # 重命名為 np# 鼠標回調函數 def mouse_callback(event, x, y, flags, userdata):print(event, x, y, flags, userdata)# 創建窗口 cv2.namedWindow("mouse", cv2.WINDOW_NORMAL) cv2.resizeWindow("mouse", 640, 480)# 設置鼠標回調 cv2.setMouseCallback("mouse", mouse_callback, "123") # 第一個參數為窗口名,第二個參數為回調函數,第三個參數為回調函數的最后一個參數,即上面函數的 userdata# 顯示窗口和背景 img = np.zeros((480, 640, 3), np.uint8) # 調整窗口是 長、寬,這個參數順序是 寬,長。還有三通道的順序,是 BGR,和 RGB 是反著的。 # 參數 # 第一個,設置一個分辨率,(第一個為高,第二個為寬,BGR組數),這個函數默認bgr都為0,所以顯示出來為黑色。 bgr組數 3 是因為圖片的色彩就是三個通道 # 第二個參數是像素類型。數據類型是 uint8,即 0~255 的整數,圖像數據通常用這個。 img[:] = (0, 0, 255) # 紅色(注意:OpenCV 是 BGR 不是 RGB)while True:cv2.imshow("mouse", img) # 因為這個代碼顯示的是圖片,所以可以不用循環,只控制 cv2.waitKey() 參數為 0 就行。key = cv2.waitKey(1)if key & 0xFF == ord('q'):breakcv2.destroyAllWindows()
- cv2.imshow(“mouse”, img),因為這個代碼顯示的是圖片,所以可以不用循環,只控制 cv2.waitKey() 參數為 0 就行。但是如果用了循環,那么顯示窗口和 cv2.waitKey() 都要放在循環,因為如果想要畫面會變,需要不斷地刷新窗口才行,這段代碼的話沒必要,因為就是黑的,然后 cv2.waitKey() 也要在循環,不然窗口就顯示不出來了。
- OpenCV 顏色三通道是 BGR,和 RGB 正好反著的。
目的 是否必須循環調用 imshow()
僅靜態顯示一張圖片 ? 只用一次就夠 有窗口交互(鼠標、鍵盤) ? 必須每幀都 imshow()
播放視頻或動畫 ? 必須每幀都 imshow()
Trackbar(控件:滑動條)
import cv2 import numpy as np# 創建窗口 cv2.namedWindow("trackbar", cv2.WINDOW_NORMAL)cv2.resizeWindow("trackbar", 640, 480)# 回調函數 def callback(pos): # 雖然不用回調函數,但要寫一個參數,因為改變滑動條時會底層會調用 crrateTrackbar() 的回調函數,并傳遞當前值,所以需要有參數接收。pass# 創建 trackbar:trackbar 是 滑動條的意思 cv2.createTrackbar("R", "trackbar", 0, 255, callback) cv2.createTrackbar("G", "trackbar", 0, 255, callback) cv2.createTrackbar("B", "trackbar", 0, 255, callback)while True: # 獲取當前 trackbar 的值:# 獲取滑動條當前位置:不會再去調用回調函數,它只是讀取滑動條當前的位置,不會觸發任何事件,也不會執行回調函數。r = cv2.getTrackbarPos("R", "trackbar")g = cv2.getTrackbarPos("G", "trackbar")b = cv2.getTrackbarPos("B", "trackbar")# 創建圖片img = np.zeros((360, 480, 3), np.uint8)# 改變圖片顏色img[:] = [b, g, r]cv2.imshow("trackbar", img)key = cv2.waitKey(10)if key & 0xff == ord('q'):breakcv2.destroyAllWindows()
- 博主長期更新,博主的目標是不斷提升閱讀體驗和內容質量,如果你喜歡博主的文章,請點個贊或者關注博主支持一波,我會更加努力的為你呈現精彩的內容。
🌈專欄推薦
😈魔王的修煉之路–C語言
😈魔王的修煉之路–數據結構
😈魔王的修煉之路–C++
😈魔王的修煉之路–QT
😈魔王的修煉之路–算法
😈魔王的修煉之路–力扣
😈魔王的修煉之路–牛客
😈魔王的修煉之路–劍指offer
😈魔王的修煉之路–Linux
😈魔王的修煉之路–Computer vision
更新不易,希望得到友友的三連支持一波。收藏這篇文章,意味著你將永久擁有它,無論何時何地,都可以立即找到重新閱讀;關注博主,意味著無論何時何地,博主將永久和你一起學習進步,為你帶來有價值的內容。